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.
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/PKG-INFO +2 -2
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/README.md +1 -1
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0087-deploy-compiled-policy-with-a-privileged-scheduled-job.md +20 -5
- stacktrace_cli-0.7.1/docs/releases/v0.7.1.md +76 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/daemon-scanning.md +7 -2
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/managed-policy-deployment.md +27 -14
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/remote-sync.md +13 -3
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/pyproject.toml +1 -1
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/__init__.py +1 -1
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/cli.py +13 -9
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/server.py +7 -0
- stacktrace_cli-0.7.1/src/stacktrace_cli/monitor/site/apple-icon.png +0 -0
- stacktrace_cli-0.7.1/src/stacktrace_cli/monitor/site/favicon.ico +0 -0
- stacktrace_cli-0.7.1/src/stacktrace_cli/monitor/site/icon.svg +7 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/index.html +3 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/cli.py +97 -22
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/client.py +0 -83
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/config.py +5 -1
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/policy_service.py +134 -9
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/sync.py +7 -1
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_cli.py +41 -9
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_server.py +13 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_cli.py +250 -81
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_client.py +0 -116
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_config.py +11 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_policy_service.py +412 -2
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_policy_service_cli.py +135 -3
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_sync.py +29 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/uv.lock +1 -1
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.agents/skills/release-stacktrace/SKILL.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.claude/settings.json +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.claude/skills/pr-review-loop/SKILL.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.claude/skills/release-stacktrace/SKILL.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.codex/hooks.json +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/managed-autofix.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/workflows/autofix.yml +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/workflows/ci.yml +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/workflows/claude.yml +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/workflows/publish-pypi.yml +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.gitignore +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/AGENTS.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/CLAUDE.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0003-runtime-edges.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0004-three-stage-detector.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0006-trust-boundary-and-detection-upload.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0011-verdict-cache.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0014-declared-project-mapping.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0021-two-command-kinds.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
- {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
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
- {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
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
- {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
- {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
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +0 -0
- {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
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0041-defer-native-windows-support.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
- {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
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0045-scan-every-session-and-outlive-them.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
- {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
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
- {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
- {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
- {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
- {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
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0061-the-drain-sends-findings-only.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0083-each-block-reason-is-its-own-rule.md +0 -0
- {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
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0086-a-refusal-names-who-answered-the-call.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0088-slack-alerts-leave-out-confidence.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/HOOK-PROMPT.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/INDEX.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/TEMPLATE.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/cutover-openaca-remote.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/002-session-input.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/003-correlation.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/004-detector.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/005-remote-sync.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/006-cli-composition.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/007-detection-upload.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/008-monitor.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/009-reasoning-jev.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/010-session-daemon.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/011-daemon-store.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/012-daemon-scanning.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/013-daemon-uploads.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/014-asset-identity.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/015-managed-policy-deployment.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.0.1.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.1.0.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.2.0.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.2.1.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.2.2.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.2.3.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.3.0.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.3.1.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.4.0.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.4.1.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.5.0.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.5.1.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.5.2.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.5.3.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.6.0.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.6.1.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.7.0.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/research/001-intent-drift-metric.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/aidr.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/cli-composition.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/correlation.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/daemon-store.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/daemon-uploads.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/detection-policies.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/detection-upload.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/detector.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/event-time.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/monitor-inventory.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/monitor.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/notification-delivery.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/reasoning-jev.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/session-input.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/scripts/git-hooks/pre-push +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/scripts/install-hooks.sh +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/__main__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/analysis.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/build.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/cli.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/cloud/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/cloud/setup.sh +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/acquire.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/composition.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/join.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/observed.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/orchestrate.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/project_map.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/record.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/render.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/activity_log.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/bom.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/client.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/composition.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/config.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/db.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/fleet.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/identity.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/jobs.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/observer.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/paths.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/presentation.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/protocol.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/runtime.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/scan.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/server.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/service.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/store.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/webhook.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/analyzer.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/blocked.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/cache.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/deterministic.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/finding.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/history.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/jev.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/priors.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/reasoning.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/render.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/rules.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/run.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/secrets.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/verdict.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/windows.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/inventory.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/reasoning.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/render.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/app.js +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/inventory.js +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/styles.css +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/state.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/verdicts.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/watch.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/options.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/private_state.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/detect_payload.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/identity.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/payload.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/policy.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/policy_worker.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/redact.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/spool.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/sync_detect.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/upload_contract.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/access.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/index.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/outcome.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/protocols.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/render.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/cli.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/events.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/posthog.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/state.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/webhook/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/webhook/cli.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/webhook/config.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/agent_bom_fixture.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/conftest.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_activity_log.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_client.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_composition.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_config.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_db.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_detection_needs_no_subscriber.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_fleet.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_identity.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_jobs.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_lifecycle.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_observer.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_queue_reader.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_runtime.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_scan.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_service.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_socket.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_store.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_the_drained_payload_is_the_cold_one.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_webhook.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/detector_session_fixture.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/feed_harness.mjs +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/inventory_harness.mjs +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_feed_model.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_inventory.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_inventory_page.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_reasoning_gates.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_render.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_site_assets.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_state.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_verdicts.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_watch.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/helpers.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_activity.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_cli.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_client.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_contract_is_exhaustive.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_layers_compose.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_redaction.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_spool.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_upload_contract.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_wire_payload.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_facade_contract.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_identity.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_payload.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_policy.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_redact_payload.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_seam.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_spool.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_sync_detect.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_upload_contract.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/__init__.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_activity_log.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_cli.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_events.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_hooks.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_release_gate.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_state.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_uploader.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_acquire.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_agent_instance_id.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_analysis.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_bom_shape.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_build_commit.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_call_status_conventions.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_cli.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_composition.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_correlate_orchestrate.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_correlate_render.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_correlated_session.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detection_components.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detection_event_time.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detection_subject.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_analyzer_contract.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_analyzer_live.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_blocked.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_cache.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_deterministic.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_end_to_end.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_finding.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_history.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_jev.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_names_the_service.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_new_deterministic.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_priors.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_prompts.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_reasoning.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_render.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_run.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_secrets.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_verdict.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_vulnerable_dep_invoked.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_why_it_stopped.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_windows.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_evidence_is_dated_not_numbered.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_help_sections.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_join.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_monitor_cli.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_observed.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_openaca_contract.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_openaidr_contract.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_option_arity_matches_the_binary.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_project_map.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_readme_examples_are_real_output.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_release_gate_coverage.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_release_readiness.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_seam_boundary.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_session_identity_is_the_pair.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_access.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_end_to_end.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_protocol_typing.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_protocols.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_render.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_shell_separators_match_the_shell.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_title_disclosure_invariant.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_untrusted_content_never_travels.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_verification_subcommands_match_the_binary.py +0 -0
- {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_what_jev_is_told_is_what_was_disclosed.py +0 -0
- {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.
|
|
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.
|
|
54
|
+
stacktrace 0.7.1 (openaca 0.8.0)
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
## 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.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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`
|
|
204
|
-
|
|
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.
|
|
135
|
-
|
|
136
|
-
root
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
|
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
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
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
|
-
|
|
108
|
-
`
|
|
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_
|
|
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
|
|
|
@@ -210,14 +210,13 @@ def _reject_unobservable_kinds(config: DaemonConfig) -> None:
|
|
|
210
210
|
|
|
211
211
|
|
|
212
212
|
@daemon.command()
|
|
213
|
-
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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",
|
|
Binary file
|
|
Binary file
|
|
@@ -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(
|
|
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
|
|
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
|
-
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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 =
|
|
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_
|
|
435
|
-
return "ot_
|
|
509
|
+
return f"ot_••••{token[-4:]}"
|
|
510
|
+
return "ot_••••"
|
|
436
511
|
return "***"
|
|
437
512
|
|
|
438
513
|
|