stacktrace-cli 0.8.0__tar.gz → 0.10.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.10.0/.github/workflows/bedrock-live.yml +55 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/CLAUDE.md +13 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/PKG-INFO +23 -7
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/README.md +20 -4
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0006-trust-boundary-and-detection-upload.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0026-the-console-becomes-a-product-surface.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0045-scan-every-session-and-outlive-them.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0061-the-drain-sends-findings-only.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +1 -1
- stacktrace_cli-0.10.0/docs/adrs/0092-cost-is-its-own-rule-family.md +49 -0
- stacktrace_cli-0.10.0/docs/adrs/0093-environment-cost-baselines-count-tokens-keyed-by-model.md +78 -0
- stacktrace_cli-0.10.0/docs/adrs/0094-estimate-cost-from-tokens-the-agent-figure-is-a-cross-check.md +63 -0
- stacktrace_cli-0.10.0/docs/adrs/0095-cost-findings-reach-fleet-each-rule-can-be-muted.md +53 -0
- stacktrace_cli-0.10.0/docs/adrs/0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md +86 -0
- stacktrace_cli-0.10.0/docs/adrs/0097-the-daemon-makes-cost-findings-and-the-monitor-reads-them.md +69 -0
- stacktrace_cli-0.10.0/docs/adrs/0098-a-run-is-its-main-session.md +53 -0
- stacktrace_cli-0.10.0/docs/adrs/0099-cost-is-measured-in-tokens-and-relative-increases.md +85 -0
- stacktrace_cli-0.10.0/docs/adrs/0100-the-monitor-runs-offline-for-the-website.md +70 -0
- stacktrace_cli-0.10.0/docs/adrs/0101-what-names-a-run-in-fleet.md +111 -0
- stacktrace_cli-0.10.0/docs/adrs/0102-token-use-is-never-compared-with-a-providers-usage-api.md +55 -0
- stacktrace_cli-0.10.0/docs/adrs/0103-finished-runs-may-leave-as-numbers-for-org-baselines.md +91 -0
- stacktrace_cli-0.10.0/docs/adrs/0104-usage-is-its-own-upload.md +92 -0
- stacktrace_cli-0.10.0/docs/adrs/0105-an-asset-key-is-a-bare-uuid.md +76 -0
- stacktrace_cli-0.10.0/docs/adrs/0106-boot-id-is-salted-with-the-pid-namespace.md +69 -0
- stacktrace_cli-0.10.0/docs/adrs/0107-the-daemon-follows-every-kind-openaidr-reads.md +114 -0
- stacktrace_cli-0.10.0/docs/adrs/0108-a-kind-renamed-before-any-release-read-it-keeps-no-alias.md +68 -0
- stacktrace_cli-0.10.0/docs/adrs/0109-a-detection-carries-its-runs-title-and-the-persons-name.md +106 -0
- stacktrace_cli-0.10.0/docs/adrs/0110-every-kinds-account-comes-from-openaidr.md +70 -0
- stacktrace_cli-0.10.0/docs/adrs/0111-built-in-sub-agents-and-skills-come-from-the-bom.md +74 -0
- stacktrace_cli-0.10.0/docs/adrs/0112-a-person-is-known-by-the-accounts-on-the-host.md +137 -0
- stacktrace_cli-0.10.0/docs/adrs/0113-size-triggers-behaviour-explains-session-cost-carries-reasons.md +103 -0
- stacktrace_cli-0.10.0/docs/adrs/0114-similar-sessions-are-the-same-agent-in-the-same-repo.md +79 -0
- stacktrace_cli-0.10.0/docs/adrs/0115-usage-states-its-coverage-and-fleet-returns-expected-runs.md +93 -0
- stacktrace_cli-0.10.0/docs/adrs/0116-a-component-row-carries-what-its-results-cost-under-one-closed-key.md +84 -0
- stacktrace_cli-0.10.0/docs/adrs/0117-a-component-row-on-the-day-of-a-switch-counts-from-the-switch.md +60 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/INDEX.md +29 -3
- stacktrace_cli-0.10.0/docs/plans/016-cost-phase-1.md +832 -0
- stacktrace_cli-0.10.0/docs/plans/017-cost-phase-2.md +325 -0
- stacktrace_cli-0.10.0/docs/releases/v0.10.0.md +136 -0
- stacktrace_cli-0.10.0/docs/releases/v0.9.0.md +116 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/aidr.md +19 -11
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/correlation.md +9 -2
- stacktrace_cli-0.10.0/docs/specs/cost-notifications.md +721 -0
- stacktrace_cli-0.10.0/docs/specs/cost-phase-1.md +508 -0
- stacktrace_cli-0.10.0/docs/specs/cost-phase-2.md +190 -0
- stacktrace_cli-0.10.0/docs/specs/cost.md +274 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-store.md +10 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-uploads.md +5 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/detection-policies.md +67 -3
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/detection-upload.md +24 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/detector.md +16 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/monitor.md +257 -13
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/notification-delivery.md +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/session-input.md +11 -9
- stacktrace_cli-0.10.0/docs/specs/usage-upload.md +401 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/pyproject.toml +19 -3
- stacktrace_cli-0.10.0/scripts/cost_latency.py +85 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/__init__.py +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/analysis.py +13 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cli.py +3 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cloud/setup.sh +5 -3
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/acquire.py +7 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/composition.py +46 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/join.py +102 -147
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/observed.py +18 -19
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/orchestrate.py +45 -18
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/__init__.py +6 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/baseline.py +555 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/clock.py +40 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/component_usage.py +324 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/components.py +143 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/evidence.py +69 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/ledger.py +58 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/measures.py +354 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/models.py +38 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/org_baselines.py +258 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/reasons.py +592 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/rules.py +662 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/runs.py +149 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/tokens.py +69 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/totals.py +62 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/usage.py +293 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/accounts.py +269 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/cli.py +84 -7
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/client.py +41 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/composition.py +53 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/config.py +53 -2
- stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/costs.py +780 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/db.py +315 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/fleet.py +88 -22
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/jobs.py +90 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/observer.py +755 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/presentation.py +79 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/runtime.py +253 -18
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/scan.py +32 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/server.py +17 -3
- stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/store.py +2440 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/usage.py +1126 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/webhook.py +2 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/cache.py +4 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/deterministic.py +11 -12
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/finding.py +1 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/__init__.py +0 -5
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/reasoning.py +4 -4
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/render.py +14 -12
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/rules.py +55 -4
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/run.py +2 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/windows.py +3 -3
- stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/costs.py +650 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/offline.py +266 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/render.py +132 -30
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/server.py +18 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/app.js +561 -117
- stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/site/cost.js +1008 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +196 -97
- stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/site/fonts/playfair-display-600-italic-latin.woff2 +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/index.html +37 -5
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/inventory.js +5 -2
- stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/site/styles.css +902 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/state.py +5 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/watch.py +55 -12
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/private_state.py +2 -3
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/client.py +93 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/detect_payload.py +34 -14
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/identity.py +39 -31
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/redact.py +0 -7
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/spool.py +8 -6
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/upload_contract.py +136 -4
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/access.py +96 -0
- stacktrace_cli-0.10.0/src/stacktrace_cli/sessions/lineage.py +24 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/protocols.py +99 -8
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/events.py +3 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/agent_bom_fixture.py +10 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/conftest.py +22 -0
- stacktrace_cli-0.10.0/tests/cost/fakes.py +57 -0
- stacktrace_cli-0.10.0/tests/cost/scenarios.py +313 -0
- stacktrace_cli-0.10.0/tests/cost/test_as_of_cuts_every_timed_collection.py +150 -0
- stacktrace_cli-0.10.0/tests/cost/test_baseline.py +261 -0
- stacktrace_cli-0.10.0/tests/cost/test_clock.py +61 -0
- stacktrace_cli-0.10.0/tests/cost/test_component_usage.py +307 -0
- stacktrace_cli-0.10.0/tests/cost/test_components.py +129 -0
- stacktrace_cli-0.10.0/tests/cost/test_cost_evidence_travels.py +135 -0
- stacktrace_cli-0.10.0/tests/cost/test_cost_findings_are_dated_by_their_citations.py +426 -0
- stacktrace_cli-0.10.0/tests/cost/test_cost_findings_carry_no_session_text.py +123 -0
- stacktrace_cli-0.10.0/tests/cost/test_cost_is_tokens.py +72 -0
- stacktrace_cli-0.10.0/tests/cost/test_cost_latency.py +82 -0
- stacktrace_cli-0.10.0/tests/cost/test_evidence.py +40 -0
- stacktrace_cli-0.10.0/tests/cost/test_ledger.py +44 -0
- stacktrace_cli-0.10.0/tests/cost/test_measures.py +251 -0
- stacktrace_cli-0.10.0/tests/cost/test_models.py +15 -0
- stacktrace_cli-0.10.0/tests/cost/test_org_baselines.py +333 -0
- stacktrace_cli-0.10.0/tests/cost/test_reasons.py +261 -0
- stacktrace_cli-0.10.0/tests/cost/test_rules_baseline.py +189 -0
- stacktrace_cli-0.10.0/tests/cost/test_rules_budget.py +189 -0
- stacktrace_cli-0.10.0/tests/cost/test_runs.py +43 -0
- stacktrace_cli-0.10.0/tests/cost/test_totals.py +55 -0
- stacktrace_cli-0.10.0/tests/cost/test_usage.py +255 -0
- stacktrace_cli-0.10.0/tests/daemon/observing.py +47 -0
- stacktrace_cli-0.10.0/tests/daemon/test_accounts.py +530 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_activity_log.py +28 -6
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_cli.py +167 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_client.py +58 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_composition.py +79 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_config.py +12 -2
- stacktrace_cli-0.10.0/tests/daemon/test_cost_guidance.py +23 -0
- stacktrace_cli-0.10.0/tests/daemon/test_costs.py +1350 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_db.py +44 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_detection_needs_no_subscriber.py +4 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_fleet.py +151 -0
- stacktrace_cli-0.10.0/tests/daemon/test_job_thread.py +63 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_observer.py +480 -50
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_runtime.py +178 -17
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_scan.py +105 -0
- stacktrace_cli-0.10.0/tests/daemon/test_session_cost_notices.py +117 -0
- stacktrace_cli-0.10.0/tests/daemon/test_stage_times.py +80 -0
- stacktrace_cli-0.10.0/tests/daemon/test_subagent_routing.py +154 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_the_drained_payload_is_the_cold_one.py +5 -4
- stacktrace_cli-0.10.0/tests/daemon/test_usage.py +1768 -0
- stacktrace_cli-0.10.0/tests/daemon/test_usage_store.py +973 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_webhook.py +2 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/detector_session_fixture.py +24 -24
- stacktrace_cli-0.10.0/tests/monitor/cost_harness.mjs +288 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/feed_harness.mjs +405 -1
- stacktrace_cli-0.10.0/tests/monitor/test_cost_page.py +548 -0
- stacktrace_cli-0.10.0/tests/monitor/test_cost_range_switch.py +143 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_feed_model.py +255 -5
- stacktrace_cli-0.10.0/tests/monitor/test_offline.py +242 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_render.py +45 -13
- stacktrace_cli-0.10.0/tests/monitor/test_render_cost.py +937 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_site_assets.py +70 -35
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_watch.py +112 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_client.py +51 -0
- stacktrace_cli-0.10.0/tests/remote/test_cloud_setup_asset_id.py +56 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_activity.py +2 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_contract_is_exhaustive.py +16 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_facade_contract.py +31 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_identity.py +119 -42
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_seam.py +6 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_spool.py +12 -0
- stacktrace_cli-0.10.0/tests/remote/test_usage_client.py +111 -0
- stacktrace_cli-0.10.0/tests/remote/test_usage_contract.py +283 -0
- stacktrace_cli-0.10.0/tests/telemetry/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_every_derived_site.py +20 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_hooks.py +5 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_acquire.py +11 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_call_status_conventions.py +159 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_correlate_orchestrate.py +54 -1
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_correlate_render.py +5 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_correlated_session.py +5 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detection_subject.py +6 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_end_to_end.py +2 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_priors.py +0 -35
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +12 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_join.py +82 -4
- stacktrace_cli-0.10.0/tests/test_kind_conformance.py +163 -0
- stacktrace_cli-0.10.0/tests/test_no_agent_kind_is_named.py +83 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_observed.py +5 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_openaca_contract.py +7 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_openaidr_contract.py +81 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_project_map.py +5 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_seam_boundary.py +3 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_session_identity_is_the_pair.py +22 -0
- stacktrace_cli-0.10.0/tests/test_sessions_protocol_typing.py +44 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_sessions_protocols.py +35 -2
- stacktrace_cli-0.10.0/tests/test_signed_in_asks_the_agent.py +93 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +12 -2
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_title_disclosure_invariant.py +11 -4
- stacktrace_cli-0.10.0/tests/tool_fields.py +25 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/uv.lock +10 -10
- stacktrace_cli-0.8.0/.claude/skills/pr-review-loop/SKILL.md +0 -120
- stacktrace_cli-0.8.0/src/stacktrace_cli/daemon/observer.py +0 -655
- stacktrace_cli-0.8.0/src/stacktrace_cli/daemon/store.py +0 -968
- stacktrace_cli-0.8.0/src/stacktrace_cli/monitor/site/styles.css +0 -563
- stacktrace_cli-0.8.0/tests/test_sessions_protocol_typing.py +0 -18
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.agents/skills/release-stacktrace/SKILL.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.claude/settings.json +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.claude/skills/release-stacktrace/SKILL.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.codex/hooks.json +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.github/managed-autofix.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.github/pull_request_template.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.github/workflows/ci.yml +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.github/workflows/publish-pypi.yml +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/.gitignore +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/AGENTS.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0003-runtime-edges.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0004-three-stage-detector.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0011-verdict-cache.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0014-declared-project-mapping.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0021-two-command-kinds.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0033-a-third-party-analyzer-only-by-a-flag-that-names-it.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0034-the-drift-grade-is-read-off-a-run-not-a-call.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0041-defer-native-windows-support.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0043-name-the-session-agent-and-host-and-count-errors-by-class.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0057-grow-the-queue-schema-additively-and-share-only-the-document.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.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.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0059-the-daemon-does-not-decide-whether-it-should-be-running.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0083-each-block-reason-is-its-own-rule.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0086-a-refusal-names-who-answered-the-call.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0087-deploy-compiled-policy-with-a-privileged-scheduled-job.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0088-slack-alerts-leave-out-confidence.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0089-infra-gate-reads-commands-not-shell-semantics.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0090-count-completed-commands-locate-by-ip-send-through-the-managed-proxy.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/0091-mark-our-own-machines-and-name-what-failed.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/HOOK-PROMPT.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/adrs/TEMPLATE.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/cutover-openaca-remote.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/002-session-input.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/003-correlation.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/004-detector.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/005-remote-sync.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/006-cli-composition.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/007-detection-upload.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/008-monitor.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/009-reasoning-jev.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/010-session-daemon.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/011-daemon-store.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/012-daemon-scanning.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/013-daemon-uploads.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/014-asset-identity.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/plans/015-managed-policy-deployment.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.0.1.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.1.0.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.0.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.1.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.2.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.3.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.3.0.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.3.1.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.4.0.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.4.1.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.0.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.1.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.2.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.3.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.6.0.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.6.1.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.7.0.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.7.1.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/releases/v0.8.0.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/research/001-intent-drift-metric.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/cli-composition.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-scanning.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/event-time.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/managed-policy-deployment.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/monitor-inventory.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/reasoning-jev.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/docs/specs/remote-sync.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/scripts/git-hooks/pre-push +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/scripts/install-hooks.sh +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/__main__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/build.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cloud/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/project_map.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/record.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/render.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/activity_log.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/bom.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/identity.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/paths.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/protocol.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/service.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/analyzer.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/blocked.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/history.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/jev.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/priors.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-infra-unsafe-action.json +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/secrets.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/verdict.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/inventory.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/reasoning.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/apple-icon.png +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/favicon.ico +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/icon.svg +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/verdicts.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/options.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/config.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/payload.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy_service.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy_worker.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/sync.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/sync_detect.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/index.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/outcome.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/render.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/posthog.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/state.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/config.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/__init__.py +0 -0
- {stacktrace_cli-0.8.0/tests/monitor → stacktrace_cli-0.10.0/tests/cost}/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_identity.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_jobs.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_lifecycle.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_queue_reader.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_service.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_socket.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_store.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
- {stacktrace_cli-0.8.0/tests/remote → stacktrace_cli-0.10.0/tests/monitor}/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/inventory_harness.mjs +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_inventory.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_inventory_page.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_reasoning_gates.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_server.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_state.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/monitor/test_verdicts.py +0 -0
- {stacktrace_cli-0.8.0/tests/telemetry → stacktrace_cli-0.10.0/tests/remote}/__init__.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/helpers.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_config.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_client.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_layers_compose.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_redaction.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_spool.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_upload_contract.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_wire_payload.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_payload.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy_service.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy_service_cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_redact_payload.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_sync.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_sync_detect.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/remote/test_upload_contract.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_activity_log.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_events.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_every_internal_save_is_reported.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_release_gate.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_state.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_uploader.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_agent_instance_id.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_analysis.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_bom_shape.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_build_commit.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_composition.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detection_components.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detection_event_time.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_analyzer_contract.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_analyzer_live.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_blocked.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_cache.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_deterministic.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_finding.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_history.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_infra_reasoning.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_jev.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_names_the_service.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_new_deterministic.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_prompts.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_reasoning.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_render.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_run.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_secrets.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_verdict.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_vulnerable_dep_invoked.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_why_it_stopped.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_detector_windows.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_evidence_is_dated_not_numbered.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_help_sections.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_monitor_cli.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_option_arity_matches_the_binary.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_readme_examples_are_real_output.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_release_gate_coverage.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_release_readiness.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_sessions_access.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_sessions_end_to_end.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_sessions_render.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_shell_separators_match_the_shell.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_untrusted_content_never_travels.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_verification_subcommands_match_the_binary.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/test_what_jev_is_told_is_what_was_disclosed.py +0 -0
- {stacktrace_cli-0.8.0 → stacktrace_cli-0.10.0}/tests/webhook/test_cli.py +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Live Bedrock test in the sandbox account. Run by hand from the Actions tab.
|
|
2
|
+
# Credentials come from GitHub's OIDC token, exchanged for a one-hour session
|
|
3
|
+
# on a role that can only call Bedrock and read the invocation-logs bucket
|
|
4
|
+
# (integrations/bedrock/tofu/ci.tf). No AWS key is stored anywhere.
|
|
5
|
+
name: bedrock-live
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
inputs:
|
|
10
|
+
ref:
|
|
11
|
+
description: Branch, tag or SHA holding the test to run. Dispatch from main; this is what gets checked out.
|
|
12
|
+
required: false
|
|
13
|
+
default: main
|
|
14
|
+
model:
|
|
15
|
+
description: Inference profile ID. Empty picks a Claude Sonnet profile.
|
|
16
|
+
required: false
|
|
17
|
+
default: ""
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
id-token: write
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
live:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
# The role trusts only jobs in this environment.
|
|
27
|
+
environment: bedrock-sandbox
|
|
28
|
+
timeout-minutes: 30
|
|
29
|
+
steps:
|
|
30
|
+
# GitHub dispatches only workflows on the default branch, and only to
|
|
31
|
+
# other refs after a first run, so the test's ref is an input instead.
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
with:
|
|
34
|
+
ref: ${{ inputs.ref }}
|
|
35
|
+
- uses: astral-sh/setup-uv@v6
|
|
36
|
+
- uses: aws-actions/configure-aws-credentials@v4
|
|
37
|
+
with:
|
|
38
|
+
role-to-assume: ${{ vars.BEDROCK_ROLE_ARN }}
|
|
39
|
+
aws-region: ${{ vars.BEDROCK_REGION || 'us-east-1' }}
|
|
40
|
+
role-duration-seconds: 3600
|
|
41
|
+
- run: uv sync
|
|
42
|
+
- name: Call each Bedrock API, read the logs back, run the rules
|
|
43
|
+
run: >
|
|
44
|
+
uv run --with boto3 python integrations/bedrock/live_test.py
|
|
45
|
+
--bucket "${{ vars.BEDROCK_LOGS_BUCKET }}"
|
|
46
|
+
--region "${{ vars.BEDROCK_REGION || 'us-east-1' }}"
|
|
47
|
+
${{ inputs.model && format('--model {0}', inputs.model) || '' }}
|
|
48
|
+
--out bedrock-live
|
|
49
|
+
# Synthetic traffic only: scripted calls and a fake token.
|
|
50
|
+
- uses: actions/upload-artifact@v4
|
|
51
|
+
if: always()
|
|
52
|
+
with:
|
|
53
|
+
name: bedrock-live
|
|
54
|
+
path: bedrock-live/
|
|
55
|
+
retention-days: 3
|
|
@@ -108,6 +108,10 @@ nothing about detection.
|
|
|
108
108
|
- **OpenACA carries nothing AIDR** (ADR-0006). No finding family, no output row
|
|
109
109
|
type, no scan flag, no rule namespace upstream. Detection rule identifiers are
|
|
110
110
|
`stacktrace-*`, never `openaca-*`, and the combined report is assembled here.
|
|
111
|
+
- **Cost is tokens, never dollars** (ADR-0099). Every cost figure, threshold,
|
|
112
|
+
severity, budget, label and doc line is in tokens or a ratio to the usual
|
|
113
|
+
("3× the usual", "40M tokens more"). No price table, no dollar amount, no
|
|
114
|
+
currency, here or in Fleet. The family is still called `cost`.
|
|
111
115
|
- **Session collection is not ours** (ADR-0002). It lives in `openaidr`, open
|
|
112
116
|
source. Its types stop at our adapter; parsing an agent format here would
|
|
113
117
|
duplicate the thing the split exists to prevent.
|
|
@@ -122,6 +126,12 @@ nothing about detection.
|
|
|
122
126
|
`test_bom_shape.py`, `test_fingerprint_covers_what_the_analyzer_reads.py`. When
|
|
123
127
|
a review names a site, fix the invariant and extend the exhaustive test — a
|
|
124
128
|
second finding of the same class means the first fix was at the wrong level.
|
|
129
|
+
Cost has its own: `tests/cost/test_cost_findings_carry_no_session_text.py`,
|
|
130
|
+
`tests/cost/test_cost_is_tokens.py`, `test_cost_findings_are_dated_by_their_citations.py`,
|
|
131
|
+
and the range and usual checks in
|
|
132
|
+
`tests/monitor/test_render_cost.py`. When reviews keep re-arguing scope (a
|
|
133
|
+
time boundary, which sessions a rule reads), write the answer into the spec,
|
|
134
|
+
as `docs/specs/cost-phase-1.md` §1 "What a rule reads, and when" does.
|
|
125
135
|
|
|
126
136
|
## Adding a command
|
|
127
137
|
|
|
@@ -269,9 +279,10 @@ silently editing an accepted ADR breaks that contract.
|
|
|
269
279
|
- Calibrate priority by impact and urgency:
|
|
270
280
|
- P0: critical, broadly applicable failure requiring immediate action.
|
|
271
281
|
- P1: serious defect that should be fixed before this change lands.
|
|
272
|
-
- P2: normal-priority defect
|
|
282
|
+
- P2: normal-priority defect.
|
|
273
283
|
- P3: low-priority suggestion.
|
|
274
|
-
|
|
284
|
+
- Report only P0 and P1 findings. Do not post P2 or P3 findings, inline or
|
|
285
|
+
in the review summary. Do not inflate priority to get a finding reported.
|
|
275
286
|
- On subsequent reviews, verify earlier fixes and inspect their effects on
|
|
276
287
|
callers and dependencies. Older code within the PR remains reviewable.
|
|
277
288
|
- When review history supports it, identify a finding as:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: stacktrace-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.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>
|
|
@@ -20,8 +20,8 @@ Classifier: Topic :: Security
|
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Requires-Dist: click>=8.1
|
|
22
22
|
Requires-Dist: httpx<1.0.dev0,>=0.28.1
|
|
23
|
-
Requires-Dist: openaca==0.
|
|
24
|
-
Requires-Dist: openaidr==0.
|
|
23
|
+
Requires-Dist: openaca==0.10.1
|
|
24
|
+
Requires-Dist: openaidr==0.6.1
|
|
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.10.0 (openaca 0.10.1)
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
## Quick start
|
|
@@ -178,6 +178,21 @@ so naming the vendor is your act rather than ours (ADR-0033). Without both,
|
|
|
178
178
|
stage three is not asked. `detect --analyzer jev` alone reads back what such a
|
|
179
179
|
run already paid for and commissions nothing (ADR-0035).
|
|
180
180
|
|
|
181
|
+
**With Fleet configured** (`stacktrace remote configure`), the daemon sends
|
|
182
|
+
its findings, and its token usage for the cost ledger: tokens per run,
|
|
183
|
+
session, model and minute, and per run the repository's name (`owner/repo`,
|
|
184
|
+
from its `origin` remote), the branch, the session's own title (never the
|
|
185
|
+
prompt) and the opaque id of the account the agent is signed into, Claude
|
|
186
|
+
Code's or Devin's. With each account go its display name (else the part of its
|
|
187
|
+
email before the `@`), its plan, and a key that groups one person's accounts:
|
|
188
|
+
a hash of the email and the Fleet organization, never the email itself. A
|
|
189
|
+
finding carries its session's account the same way. Prompts, tool arguments,
|
|
190
|
+
results and paths are not sent (ADR-0096, ADR-0104, ADR-0101, ADR-0112).
|
|
191
|
+
|
|
192
|
+
To learn who Devin is signed in as, `stacktrace` runs Devin's own `devin auth
|
|
193
|
+
status`, which asks Devin's server. It asks again only after Devin's sign-in
|
|
194
|
+
changes, or ten minutes after an ask that named no one (ADR-0110).
|
|
195
|
+
|
|
181
196
|
`sessions` omits prompts, tool arguments and results unless you pass
|
|
182
197
|
`--include-content`. `monitor` binds to loopback only, and refuses a
|
|
183
198
|
non-loopback address rather than warning about it.
|
|
@@ -215,9 +230,10 @@ enables telemetry again under a new identity (ADR-0039, ADR-0090).
|
|
|
215
230
|
|
|
216
231
|
Beta, and under active development.
|
|
217
232
|
|
|
218
|
-
`sessions`, `detect` and `monitor` work end to end today
|
|
219
|
-
|
|
220
|
-
|
|
233
|
+
`sessions`, `detect` and `monitor` work end to end today, for Claude Code and
|
|
234
|
+
Devin sessions alike (Devin CLI and Devin Desktop's local agent). Session collection is
|
|
235
|
+
[OpenAIDR](https://github.com/open-agent-security/openaidr)'s, and further agent
|
|
236
|
+
kinds arrive with it. The daemon observes every kind it reads, sub-agents included.
|
|
221
237
|
|
|
222
238
|
## Built on
|
|
223
239
|
|
|
@@ -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.10.0 (openaca 0.10.1)
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
## Quick start
|
|
@@ -151,6 +151,21 @@ so naming the vendor is your act rather than ours (ADR-0033). Without both,
|
|
|
151
151
|
stage three is not asked. `detect --analyzer jev` alone reads back what such a
|
|
152
152
|
run already paid for and commissions nothing (ADR-0035).
|
|
153
153
|
|
|
154
|
+
**With Fleet configured** (`stacktrace remote configure`), the daemon sends
|
|
155
|
+
its findings, and its token usage for the cost ledger: tokens per run,
|
|
156
|
+
session, model and minute, and per run the repository's name (`owner/repo`,
|
|
157
|
+
from its `origin` remote), the branch, the session's own title (never the
|
|
158
|
+
prompt) and the opaque id of the account the agent is signed into, Claude
|
|
159
|
+
Code's or Devin's. With each account go its display name (else the part of its
|
|
160
|
+
email before the `@`), its plan, and a key that groups one person's accounts:
|
|
161
|
+
a hash of the email and the Fleet organization, never the email itself. A
|
|
162
|
+
finding carries its session's account the same way. Prompts, tool arguments,
|
|
163
|
+
results and paths are not sent (ADR-0096, ADR-0104, ADR-0101, ADR-0112).
|
|
164
|
+
|
|
165
|
+
To learn who Devin is signed in as, `stacktrace` runs Devin's own `devin auth
|
|
166
|
+
status`, which asks Devin's server. It asks again only after Devin's sign-in
|
|
167
|
+
changes, or ten minutes after an ask that named no one (ADR-0110).
|
|
168
|
+
|
|
154
169
|
`sessions` omits prompts, tool arguments and results unless you pass
|
|
155
170
|
`--include-content`. `monitor` binds to loopback only, and refuses a
|
|
156
171
|
non-loopback address rather than warning about it.
|
|
@@ -188,9 +203,10 @@ enables telemetry again under a new identity (ADR-0039, ADR-0090).
|
|
|
188
203
|
|
|
189
204
|
Beta, and under active development.
|
|
190
205
|
|
|
191
|
-
`sessions`, `detect` and `monitor` work end to end today
|
|
192
|
-
|
|
193
|
-
|
|
206
|
+
`sessions`, `detect` and `monitor` work end to end today, for Claude Code and
|
|
207
|
+
Devin sessions alike (Devin CLI and Devin Desktop's local agent). Session collection is
|
|
208
|
+
[OpenAIDR](https://github.com/open-agent-security/openaidr)'s, and further agent
|
|
209
|
+
kinds arrive with it. The daemon observes every kind it reads, sub-agents included.
|
|
194
210
|
|
|
195
211
|
## Built on
|
|
196
212
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0092
|
|
3
|
+
title: Cost is its own rule family
|
|
4
|
+
status: proposed
|
|
5
|
+
date: 2026-10-05
|
|
6
|
+
supersedes: null
|
|
7
|
+
superseded-by: null
|
|
8
|
+
amends: null
|
|
9
|
+
amended-by: 0113
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
Cost Phase 1 adds cost rules (`docs/specs/cost-phase-1.md`). The catalogue has
|
|
15
|
+
two families, security and reliability, and Fleet's `detection_rules` check
|
|
16
|
+
constraint allows only those two (migration 0016). ADR-0013 created reliability
|
|
17
|
+
because stuck sessions needed their own heading and handling. Cost now needs the
|
|
18
|
+
same, as one of the product's main use cases.
|
|
19
|
+
|
|
20
|
+
## Decision
|
|
21
|
+
|
|
22
|
+
Cost rules form a third family, **`cost`**, named `stacktrace-cost-*`, with a
|
|
23
|
+
`COST_RULES` set in the catalogue. `rules.family_of` derives it, never stored on
|
|
24
|
+
a finding (ADR-0013). `stacktrace-blocked-quota` stays reliability, because the
|
|
25
|
+
agent got stuck, and cost findings may cite it as evidence.
|
|
26
|
+
|
|
27
|
+
## Alternatives considered
|
|
28
|
+
|
|
29
|
+
- **Reliability, separated by name prefix.** This was the first proposal. It is
|
|
30
|
+
rejected for three reasons:
|
|
31
|
+
- Fleet users count, filter and route by family, and a prefix is invisible to
|
|
32
|
+
them.
|
|
33
|
+
- Cost goes to the people who own the budget, not to whoever runs the agent.
|
|
34
|
+
- Reliability asks whether the session worked; a runaway can work perfectly
|
|
35
|
+
and still use far more tokens than it needs.
|
|
36
|
+
- **Security.** Rejected: costly behaviour is not an attack.
|
|
37
|
+
|
|
38
|
+
## Consequences
|
|
39
|
+
|
|
40
|
+
- One Fleet migration adds `cost` to the family check constraint, done in Phase
|
|
41
|
+
1 before any cost finding exists, so no stored data moves.
|
|
42
|
+
- The CLI catalogue, the monitor's `by_family` summary, the Fleet console and
|
|
43
|
+
Slack each gain a third family.
|
|
44
|
+
- Phase 2 can route notifications per family.
|
|
45
|
+
|
|
46
|
+
## When to revisit
|
|
47
|
+
|
|
48
|
+
If a cost rule turns out to be mainly about a session failing rather than
|
|
49
|
+
using too many tokens, move that rule to reliability.
|
stacktrace_cli-0.10.0/docs/adrs/0093-environment-cost-baselines-count-tokens-keyed-by-model.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0093
|
|
3
|
+
title: Environment cost baselines count tokens and are keyed by model
|
|
4
|
+
status: proposed
|
|
5
|
+
date: 2026-10-05
|
|
6
|
+
supersedes: null
|
|
7
|
+
superseded-by: null
|
|
8
|
+
amends: null
|
|
9
|
+
amended-by: 0099, 0113, 0114
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
`stacktrace-cost-runaway-session` must catch a session running away, while it
|
|
15
|
+
runs, against this developer's normal. Three things move "normal" without
|
|
16
|
+
anything going wrong: a price change, a new default model, and idle time.
|
|
17
|
+
|
|
18
|
+
## Decision
|
|
19
|
+
|
|
20
|
+
- The daemon keeps p50, p95 and p99 of **cumulative tokens by active minute**,
|
|
21
|
+
and of 5-minute burn, from this environment's finished sessions over 30 days.
|
|
22
|
+
- It also keeps a **day curve**: cumulative tokens by local time of day per
|
|
23
|
+
working day, per model. That curve gives the personal-anomaly rule "your usual
|
|
24
|
+
by now", and needs 10 working days of history.
|
|
25
|
+
The rule's score is log(today ÷ usual) divided by the spread: 1.48 × the
|
|
26
|
+
median absolute deviation of that log, at least 0.25. The spec's "beyond the
|
|
27
|
+
normal range" is a score of 3 or more; "far beyond" is 6 or more.
|
|
28
|
+
- It also keeps **behaviour curves** per run: sub-agents started in 10 minutes,
|
|
29
|
+
repeats with an unchanged result, input per response, cache reads and cache
|
|
30
|
+
writes, as p5 and p99, and fresh input at p95. A waste rule fires only when
|
|
31
|
+
the behaviour and the cost are both unusual for this developer, so no waste
|
|
32
|
+
rule rests on a fixed limit alone.
|
|
33
|
+
- The summaries are keyed by cohort, `(repo, entrypoint, model)`, falling back
|
|
34
|
+
to `(entrypoint, model)`, then `(model)`. Each level needs at least 20
|
|
35
|
+
sessions; with none, the rule is silent.
|
|
36
|
+
- **Tokens, not dollars**, throughout: floors and severity too (ADR-0099).
|
|
37
|
+
- **Recorded tokens on both sides.** Baselines and rules count only what the
|
|
38
|
+
transcripts record.
|
|
39
|
+
- The client's own totals are not read at all (ADR-0099): they arrive after
|
|
40
|
+
the work, with no time of their own, and add about half a percent.
|
|
41
|
+
- A comparison then undercounts alike on both sides.
|
|
42
|
+
- On a run with many sub-agents, whose output is often a lower bound, a rule
|
|
43
|
+
fires later, never falsely sooner.
|
|
44
|
+
- The baseline is backfilled from transcripts at start, excludes sessions with
|
|
45
|
+
an open cost finding, and is written only by the daemon (ADR-0046).
|
|
46
|
+
- Rules get a frozen snapshot as an input.
|
|
47
|
+
- **The table holds one numeric summary per finished session**, not the
|
|
48
|
+
percentiles: the summary's curves and behaviour measures, its cohort, run,
|
|
49
|
+
day and login type. The snapshot computes the percentiles from these rows,
|
|
50
|
+
which is what lets it drop a flagged run or a row older than 30 days.
|
|
51
|
+
- Numbers only, never content, so it is an exception to ADR-0006 constraint 1
|
|
52
|
+
on the same terms as the verdict cache (ADR-0011). It is not the sessions
|
|
53
|
+
table ADR-0046 rejected, which would have held session models.
|
|
54
|
+
- It is additive, so `SCHEMA_VERSION` does not move (ADR-0057).
|
|
55
|
+
- The monitor reads the same snapshot, read-only, for "your usual" (ADR-0097).
|
|
56
|
+
|
|
57
|
+
## Alternatives considered
|
|
58
|
+
|
|
59
|
+
- **Dollar baselines.** Rejected: a price change would fire everywhere.
|
|
60
|
+
- **One baseline across models.** Rejected: a model launch would fire everywhere.
|
|
61
|
+
- **Thresholds on finished-session totals.** Rejected: they fire after the
|
|
62
|
+
tokens are used.
|
|
63
|
+
- **Recompute from transcripts every scan.** Rejected: it repeats the cold pass
|
|
64
|
+
ADR-0011 and ADR-0037 avoid.
|
|
65
|
+
- **Rules querying the store directly.** Rejected: it breaks the single writer,
|
|
66
|
+
and output would depend on when it was read.
|
|
67
|
+
|
|
68
|
+
## Consequences
|
|
69
|
+
|
|
70
|
+
- Price changes and model launches can't trigger the rule on their own.
|
|
71
|
+
- It costs a new store table and a backfill.
|
|
72
|
+
- A developer with too few sessions gets no runaway findings until Phase 2
|
|
73
|
+
sends peer numbers.
|
|
74
|
+
|
|
75
|
+
## When to revisit
|
|
76
|
+
|
|
77
|
+
If the cohorts prove too thin in measurement, or Phase 2's fleet-wide numbers
|
|
78
|
+
make the narrow levels unnecessary.
|
stacktrace_cli-0.10.0/docs/adrs/0094-estimate-cost-from-tokens-the-agent-figure-is-a-cross-check.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0094
|
|
3
|
+
title: Cost is tokens × price at the time of use; the agent's own figure is a cross-check
|
|
4
|
+
status: superseded
|
|
5
|
+
date: 2026-10-05
|
|
6
|
+
supersedes: null
|
|
7
|
+
superseded-by: 0099
|
|
8
|
+
amends: null
|
|
9
|
+
amended-by: null
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
Phase 1 shows dollars and uses them as floors. Claude Code already
|
|
15
|
+
writes a running `totalCostUSD` in `cost-state` records, in 109 of 181 measured
|
|
16
|
+
sessions. Using it is the obvious shortcut.
|
|
17
|
+
|
|
18
|
+
## Decision
|
|
19
|
+
|
|
20
|
+
- The CLI prices each response's token buckets from a **versioned,
|
|
21
|
+
effective-dated price table**, at the price **in effect when the response
|
|
22
|
+
happened**.
|
|
23
|
+
- A model with no price is **unpriced**: shown in tokens, never priced at zero.
|
|
24
|
+
- Every dollar says which rate produced it: at list price, or at the org's own
|
|
25
|
+
rates once entered (Phase 2). The arithmetic is exact for what it prices —
|
|
26
|
+
tokens by model, type and date — but that excludes two billing dimensions
|
|
27
|
+
the agent's own figure does include: the 10% multiplier Anthropic applies to
|
|
28
|
+
a response on US data residency, and per-request fees such as web search,
|
|
29
|
+
which aren't token charges at all ([cost.md §4.3](../specs/cost.md#43-what-cost-is)).
|
|
30
|
+
- Claude Code's own figure is compared per session as a **cross-check only**.
|
|
31
|
+
- Tokens the transcripts miss, such as some sub-agent work, are taken from
|
|
32
|
+
Claude Code's per-model token totals and priced the same way, as one
|
|
33
|
+
"unrecorded" line — reconciled once per **run**, against the run's own
|
|
34
|
+
latest cumulative figure, never once per session: a resumed session's figure
|
|
35
|
+
already includes its earlier spend, and a parent's already includes its
|
|
36
|
+
sub-agents', so summing each session's own remainder would double-count
|
|
37
|
+
both. Its dollars are never used.
|
|
38
|
+
|
|
39
|
+
## Alternatives considered
|
|
40
|
+
|
|
41
|
+
- **Use Claude Code's `cost-state` as the cost.** Rejected, for four reasons:
|
|
42
|
+
- it is a per-session running total, so it can't price a window, a run or a
|
|
43
|
+
response;
|
|
44
|
+
- it is missing in 72 of 181 sessions;
|
|
45
|
+
- it is Claude Code's alone, and Codex records none;
|
|
46
|
+
- it can't take org rates or be re-priced.
|
|
47
|
+
- **Price in OpenAIDR.** Rejected by OpenAIDR ADR-0015: a price is
|
|
48
|
+
interpretation.
|
|
49
|
+
- **The provider's usage API.** Not available in the environment: it needs an
|
|
50
|
+
admin key, lags, and has no per-session detail. It is Phase 2's reconciliation
|
|
51
|
+
source.
|
|
52
|
+
|
|
53
|
+
## Consequences
|
|
54
|
+
|
|
55
|
+
- One method prices every agent, window and run.
|
|
56
|
+
- The price table must be maintained, and every price change noted in a release.
|
|
57
|
+
- A persistent gap against the cross-check, beyond the data-residency and
|
|
58
|
+
per-request gaps above, points to a missing price or a counting error.
|
|
59
|
+
|
|
60
|
+
## When to revisit
|
|
61
|
+
|
|
62
|
+
If a provider records per-response cost in the transcript: carry it as recorded,
|
|
63
|
+
and make the estimate the cross-check.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0095
|
|
3
|
+
title: Every cost finding shows in Fleet; each cost rule's Slack notifications can be switched off
|
|
4
|
+
status: proposed
|
|
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
|
+
Fleet posts every newly stored finding to Slack (`detections.py`, first
|
|
15
|
+
insert), with no filter by rule or severity. Phase 1 accepts that: its few
|
|
16
|
+
environment rules are checked on recorded sessions before they ship. Phase 2
|
|
17
|
+
adds Fleet's own rules, which compare people with the org and cannot be fully
|
|
18
|
+
tested before real org data exists. A rule that turns out noisy would keep
|
|
19
|
+
paging Fleet users until the next release.
|
|
20
|
+
|
|
21
|
+
## Decision
|
|
22
|
+
|
|
23
|
+
- Cost findings drain to Fleet over the existing upload, with **no wire change**,
|
|
24
|
+
and show in its console per environment and run from day one.
|
|
25
|
+
- In Phase 1, Fleet posts every cost finding to Slack, like any other finding.
|
|
26
|
+
- From Phase 2, Fleet's catalogue gives each cost rule a **`notify` switch**,
|
|
27
|
+
on by default, and the Slack outbox skips rules with it off.
|
|
28
|
+
- The Stacktrace team turns a rule's `notify` off when it proves noisy, and back
|
|
29
|
+
on once it is fixed. Its findings still show in Fleet.
|
|
30
|
+
- Reviewing findings as right or wrong is available to the team but optional,
|
|
31
|
+
and never a gate before a rule notifies.
|
|
32
|
+
- Developers get every cost finding locally either way.
|
|
33
|
+
|
|
34
|
+
## Alternatives considered
|
|
35
|
+
|
|
36
|
+
- **Keep findings local until Phase 2.** Rejected: Phase 1 would not be end to
|
|
37
|
+
end, and Fleet would have no evidence to evaluate.
|
|
38
|
+
- **Hold every new rule off until its findings are reviewed.** Rejected: manual
|
|
39
|
+
review does not scale, and every new rule would wait on reviewers.
|
|
40
|
+
- **No switch.** Rejected: a noisy rule would page until a release removed it,
|
|
41
|
+
and teach Fleet users to skip cost alerts.
|
|
42
|
+
- **Send them as low severity.** Rejected: severity says how bad a finding is,
|
|
43
|
+
not whether a rule is trustworthy, and Slack V1 has no severity filter.
|
|
44
|
+
|
|
45
|
+
## Consequences
|
|
46
|
+
|
|
47
|
+
- A small Fleet change: a per-rule setting and one outbox condition.
|
|
48
|
+
- Other rules keep today's behaviour, with `notify` on.
|
|
49
|
+
|
|
50
|
+
## When to revisit
|
|
51
|
+
|
|
52
|
+
When Fleet's Slack delivery gains severity or routing filters, which would make
|
|
53
|
+
this flag redundant.
|
stacktrace_cli-0.10.0/docs/adrs/0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0096
|
|
3
|
+
title: Cost usage may leave as token totals and work identifiers
|
|
4
|
+
status: accepted
|
|
5
|
+
date: 2026-10-06
|
|
6
|
+
supersedes: null
|
|
7
|
+
superseded-by: null
|
|
8
|
+
amends: 0006
|
|
9
|
+
amended-by: 0103, 0109, 0115, 0116
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
Cost Phase 2 (`docs/specs/cost-phase-2.md`) needs Fleet to judge an environment
|
|
15
|
+
owner's spend against their own past and against the org. Phase 1 already sends
|
|
16
|
+
findings and nothing else (ADR-0061, ADR-0095), and Fleet still has no usage.
|
|
17
|
+
The phase 2 upload, a new endpoint beside `detect-runs`, would send token totals
|
|
18
|
+
per run, session, model and minute, and per run the repo, branch, title and the
|
|
19
|
+
Anthropic account the agent is signed into.
|
|
20
|
+
|
|
21
|
+
That document is not a finding. [ADR-0006](0006-trust-boundary-and-detection-upload.md)
|
|
22
|
+
constraint 1 says detection findings are the one thing that may travel — amended
|
|
23
|
+
only by ADR-0039, for a different channel — and constraint 2 says the uploaded
|
|
24
|
+
document carries no user. The account is sent because, on a shared dev box or CI
|
|
25
|
+
runner, it names the person and the Fleet enrollment key does not. None of
|
|
26
|
+
ADR-0092 through ADR-0095 amends constraint 1 or 2, so an implementer who followed
|
|
27
|
+
the spec alone would cross the boundary those constraints still state.
|
|
28
|
+
|
|
29
|
+
## Decision
|
|
30
|
+
|
|
31
|
+
This amends ADR-0006 constraints 1 and 2 for one document: the cost usage upload,
|
|
32
|
+
and the cost findings Fleet draws from it. The rest of ADR-0006 stays in force,
|
|
33
|
+
including for every other finding family and for ADR-0039's telemetry.
|
|
34
|
+
|
|
35
|
+
1. **Token totals may travel. The session may not.** Counts per run, session,
|
|
36
|
+
model, minute and token type (input, output, cache read, cache write — the
|
|
37
|
+
rates differ by type), plus a local reduction of the last 30 days to those
|
|
38
|
+
same counts. The session id is the key already allowed on a finding's session
|
|
39
|
+
reference, not the session. Transcripts, correlation records and session
|
|
40
|
+
models stay on the machine. There is still no upload path for them.
|
|
41
|
+
2. **A closed set of work identifiers, and the provider account.** Per run: repo
|
|
42
|
+
name, branch name, title, and the Anthropic account the agent is signed into.
|
|
43
|
+
Per component: the tokens its definitions add to every call, whether it was
|
|
44
|
+
used, and how many calls carried it per model. Repo, branch and title are
|
|
45
|
+
names of the work, not a path, a working directory or a machine name. The
|
|
46
|
+
account may appear on a cost finding because that finding is about who spent;
|
|
47
|
+
it is how a shared environment names the person. No other finding family
|
|
48
|
+
gains a user.
|
|
49
|
+
3. **Nothing else.** Prompts, tool arguments, tool results and paths do not
|
|
50
|
+
travel. A title that reproduces the prompt is a prompt and does not travel.
|
|
51
|
+
Absolute paths and secret-shaped strings are still refused (ADR-0006
|
|
52
|
+
constraint 4). ADR-0039 is unchanged: its events still exclude repository
|
|
53
|
+
names.
|
|
54
|
+
|
|
55
|
+
The findings drain stays findings-only (ADR-0061). This is a separate endpoint.
|
|
56
|
+
|
|
57
|
+
## Alternatives considered
|
|
58
|
+
|
|
59
|
+
- **Cut the upload back to what ADR-0006 already allows.** Rejected. Findings
|
|
60
|
+
carry no usage, so Fleet cannot price an owner's past, separate a shared rise
|
|
61
|
+
from one person's, or say which work cost the money. That is the gap Phase 2
|
|
62
|
+
exists to close; Phase 1 already sends findings alone.
|
|
63
|
+
- **Upload the transcripts and price them in Fleet.** Rejected. ADR-0006 already
|
|
64
|
+
rejected central analysis of session content. The 30-day backfill is computed
|
|
65
|
+
locally and only the aggregates leave.
|
|
66
|
+
- **Put the rows on the findings drain.** Rejected. ADR-0061 keeps that drain
|
|
67
|
+
findings-only so the detection document does not grow a second shape.
|
|
68
|
+
- **Drop repo, branch, title and the account, and send token totals under the
|
|
69
|
+
Fleet key alone.** Rejected. A shared box enrolls as one Fleet member, so the
|
|
70
|
+
key is not the person who signed the agent in, and a finding that cannot name
|
|
71
|
+
the work cannot be acted on.
|
|
72
|
+
|
|
73
|
+
## Consequences
|
|
74
|
+
|
|
75
|
+
- The cost spec may name these fields because this decision does. A field that
|
|
76
|
+
is not in the list above is still a breach.
|
|
77
|
+
- Cost findings and their Slack text may repeat the account, the repo, the
|
|
78
|
+
branch and the title. Other families may not.
|
|
79
|
+
- A title is the easiest way for conversation to leak through a field this
|
|
80
|
+
decision allows. Watch for one that is the prompt.
|
|
81
|
+
|
|
82
|
+
## When to revisit
|
|
83
|
+
|
|
84
|
+
If Phase 2 ships without this upload, supersede this amendment. If the account
|
|
85
|
+
or the title is found to carry a credential or conversation in practice, narrow
|
|
86
|
+
clause 2 rather than widening what else may travel.
|