stacktrace-cli 0.9.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.9.0 → stacktrace_cli-0.10.0}/CLAUDE.md +3 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/PKG-INFO +23 -7
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/README.md +20 -4
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0006-trust-boundary-and-detection-upload.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0045-scan-every-session-and-outlive-them.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0061-the-drain-sends-findings-only.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0092-cost-is-its-own-rule-family.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0093-environment-cost-baselines-count-tokens-keyed-by-model.md +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md +1 -1
- 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.9.0 → stacktrace_cli-0.10.0}/docs/adrs/INDEX.md +22 -5
- 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.9.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.9.0 → stacktrace_cli-0.10.0}/docs/specs/cost-phase-1.md +54 -23
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/cost-phase-2.md +38 -7
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/cost.md +92 -66
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-store.md +10 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-uploads.md +5 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/detection-policies.md +49 -55
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/detection-upload.md +24 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/detector.md +11 -8
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/monitor.md +211 -46
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/notification-delivery.md +1 -1
- stacktrace_cli-0.10.0/docs/specs/usage-upload.md +401 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/pyproject.toml +19 -3
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/__init__.py +1 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cloud/setup.sh +5 -3
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/acquire.py +7 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/composition.py +46 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/join.py +102 -147
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/observed.py +18 -19
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/orchestrate.py +45 -18
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/baseline.py +174 -112
- stacktrace_cli-0.10.0/src/stacktrace_cli/cost/component_usage.py +324 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/components.py +5 -5
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/measures.py +8 -5
- 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.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/runs.py +44 -21
- 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.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/cli.py +46 -15
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/client.py +41 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/composition.py +53 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/config.py +11 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/costs.py +194 -296
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/db.py +250 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/fleet.py +85 -21
- stacktrace_cli-0.10.0/src/stacktrace_cli/daemon/observer.py +755 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/presentation.py +49 -3
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/runtime.py +153 -17
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/scan.py +1 -1
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/webhook.py +2 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/cache.py +4 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/deterministic.py +11 -12
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/__init__.py +0 -5
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/reasoning.py +4 -4
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/rules.py +12 -15
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/run.py +2 -2
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/render.py +69 -25
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/server.py +14 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/app.js +516 -135
- stacktrace_cli-0.10.0/src/stacktrace_cli/monitor/site/cost.js +1008 -0
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/index.html +35 -11
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/watch.py +39 -12
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/private_state.py +2 -3
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/client.py +93 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/detect_payload.py +34 -14
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/identity.py +39 -31
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/redact.py +0 -7
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/spool.py +8 -6
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/upload_contract.py +136 -4
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/access.py +96 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/protocols.py +18 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/events.py +3 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/agent_bom_fixture.py +10 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/conftest.py +22 -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.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_baseline.py +86 -48
- stacktrace_cli-0.10.0/tests/cost/test_component_usage.py +307 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_evidence_travels.py +22 -22
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_findings_are_dated_by_their_citations.py +56 -187
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_findings_carry_no_session_text.py +41 -38
- 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_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.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_activity_log.py +5 -6
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_cli.py +78 -7
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_client.py +58 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_composition.py +79 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_config.py +12 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_costs.py +327 -487
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_db.py +42 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_detection_needs_no_subscriber.py +4 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_fleet.py +151 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_observer.py +480 -50
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_runtime.py +116 -17
- stacktrace_cli-0.10.0/tests/daemon/test_session_cost_notices.py +117 -0
- stacktrace_cli-0.10.0/tests/daemon/test_subagent_routing.py +154 -0
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_webhook.py +2 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/detector_session_fixture.py +18 -24
- stacktrace_cli-0.10.0/tests/monitor/cost_harness.mjs +288 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/feed_harness.mjs +334 -1
- stacktrace_cli-0.10.0/tests/monitor/test_cost_page.py +548 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_cost_range_switch.py +17 -7
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_feed_model.py +232 -5
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_render.py +14 -13
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_render_cost.py +340 -44
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_site_assets.py +69 -34
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_watch.py +112 -2
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_activity.py +2 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_contract_is_exhaustive.py +16 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_facade_contract.py +12 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_identity.py +119 -42
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_seam.py +6 -0
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_every_derived_site.py +20 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_hooks.py +5 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_acquire.py +11 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_call_status_conventions.py +3 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_correlate_orchestrate.py +54 -1
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_correlate_render.py +5 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_correlated_session.py +5 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detection_subject.py +6 -2
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_priors.py +0 -35
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +3 -0
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/tests/test_observed.py +5 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_openaca_contract.py +7 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_openaidr_contract.py +14 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_project_map.py +5 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_session_identity_is_the_pair.py +9 -0
- stacktrace_cli-0.10.0/tests/test_signed_in_asks_the_agent.py +93 -0
- stacktrace_cli-0.10.0/tests/tool_fields.py +25 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/uv.lock +9 -9
- stacktrace_cli-0.9.0/.claude/skills/pr-review-loop/SKILL.md +0 -120
- stacktrace_cli-0.9.0/docs/plans/017-cost-phase-2.md +0 -89
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/rules.py +0 -1138
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/observer.py +0 -670
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/store.py +0 -1209
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/costs.py +0 -375
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/cost.js +0 -436
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/styles.css +0 -586
- stacktrace_cli-0.9.0/tests/cost/scenarios.py +0 -169
- stacktrace_cli-0.9.0/tests/cost/test_rules_baseline.py +0 -535
- stacktrace_cli-0.9.0/tests/monitor/cost_harness.mjs +0 -133
- stacktrace_cli-0.9.0/tests/monitor/test_cost_page.py +0 -232
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.agents/skills/release-stacktrace/SKILL.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.claude/settings.json +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.claude/skills/release-stacktrace/SKILL.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.codex/hooks.json +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.github/managed-autofix.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.github/pull_request_template.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.github/workflows/ci.yml +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.github/workflows/publish-pypi.yml +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/.gitignore +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/AGENTS.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0003-runtime-edges.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0004-three-stage-detector.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0011-verdict-cache.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0014-declared-project-mapping.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0021-two-command-kinds.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
- {stacktrace_cli-0.9.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.9.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.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0041-defer-native-windows-support.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
- {stacktrace_cli-0.9.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.9.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.9.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.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0083-each-block-reason-is-its-own-rule.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0086-a-refusal-names-who-answered-the-call.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0087-deploy-compiled-policy-with-a-privileged-scheduled-job.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0088-slack-alerts-leave-out-confidence.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0089-infra-gate-reads-commands-not-shell-semantics.md +0 -0
- {stacktrace_cli-0.9.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.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0091-mark-our-own-machines-and-name-what-failed.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0094-estimate-cost-from-tokens-the-agent-figure-is-a-cross-check.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0095-cost-findings-reach-fleet-each-rule-can-be-muted.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0097-the-daemon-makes-cost-findings-and-the-monitor-reads-them.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0098-a-run-is-its-main-session.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0099-cost-is-measured-in-tokens-and-relative-increases.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/0100-the-monitor-runs-offline-for-the-website.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/HOOK-PROMPT.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/adrs/TEMPLATE.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/cutover-openaca-remote.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/002-session-input.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/003-correlation.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/004-detector.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/005-remote-sync.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/006-cli-composition.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/007-detection-upload.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/008-monitor.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/009-reasoning-jev.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/010-session-daemon.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/011-daemon-store.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/012-daemon-scanning.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/013-daemon-uploads.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/014-asset-identity.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/015-managed-policy-deployment.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/plans/016-cost-phase-1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.0.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.1.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.2.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.2.3.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.3.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.3.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.4.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.4.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.2.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.5.3.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.6.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.6.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.7.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.7.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.8.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/releases/v0.9.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/research/001-intent-drift-metric.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/aidr.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/cli-composition.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/daemon-scanning.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/event-time.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/managed-policy-deployment.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/monitor-inventory.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/reasoning-jev.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/remote-sync.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/docs/specs/session-input.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/scripts/cost_latency.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/scripts/git-hooks/pre-push +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/scripts/install-hooks.sh +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/__main__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/analysis.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/build.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cloud/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/project_map.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/record.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/correlate/render.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/clock.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/evidence.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/ledger.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/models.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/tokens.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/cost/totals.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/activity_log.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/bom.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/identity.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/jobs.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/paths.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/protocol.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/daemon/service.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/analyzer.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/blocked.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/finding.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/history.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/jev.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/priors.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-infra-unsafe-action.json +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/render.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/secrets.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/detector/verdict.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/inventory.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/offline.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/reasoning.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/apple-icon.png +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/favicon.ico +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/site/icon.svg +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/state.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/monitor/verdicts.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/options.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/config.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/payload.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy_service.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/policy_worker.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/sync.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/remote/sync_detect.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/index.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/lineage.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/outcome.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/sessions/render.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/posthog.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/telemetry/state.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/src/stacktrace_cli/webhook/config.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/fakes.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_clock.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_components.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_is_tokens.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_cost_latency.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_evidence.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_ledger.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_measures.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_models.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_rules_budget.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_runs.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/cost/test_totals.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_cost_guidance.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_identity.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_job_thread.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_jobs.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_lifecycle.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_queue_reader.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_scan.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_service.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_socket.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_stage_times.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_store.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/inventory_harness.mjs +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_inventory.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_inventory_page.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_offline.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_reasoning_gates.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_server.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_state.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/monitor/test_verdicts.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/helpers.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_config.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_client.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_layers_compose.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_redaction.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_spool.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_upload_contract.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_detect_wire_payload.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_payload.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy_service.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_policy_service_cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_redact_payload.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_sync.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_sync_detect.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/remote/test_upload_contract.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_activity_log.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_events.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_every_internal_save_is_reported.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_release_gate.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_state.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/telemetry/test_uploader.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_agent_instance_id.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_analysis.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_bom_shape.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_build_commit.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_composition.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detection_components.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detection_event_time.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_analyzer_contract.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_analyzer_live.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_blocked.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_cache.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_deterministic.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_end_to_end.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_finding.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_history.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_infra_reasoning.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_jev.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_names_the_service.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_new_deterministic.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_prompts.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_reasoning.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_render.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_run.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_secrets.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_verdict.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_vulnerable_dep_invoked.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_why_it_stopped.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_detector_windows.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_evidence_is_dated_not_numbered.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_help_sections.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_monitor_cli.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_option_arity_matches_the_binary.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_readme_examples_are_real_output.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_release_gate_coverage.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_release_readiness.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_seam_boundary.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_access.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_end_to_end.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_protocol_typing.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_protocols.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_sessions_render.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_shell_separators_match_the_shell.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_title_disclosure_invariant.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_untrusted_content_never_travels.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_verification_subcommands_match_the_binary.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.10.0}/tests/test_what_jev_is_told_is_what_was_disclosed.py +0 -0
- {stacktrace_cli-0.9.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
|
|
@@ -279,9 +279,10 @@ silently editing an accepted ADR breaks that contract.
|
|
|
279
279
|
- Calibrate priority by impact and urgency:
|
|
280
280
|
- P0: critical, broadly applicable failure requiring immediate action.
|
|
281
281
|
- P1: serious defect that should be fixed before this change lands.
|
|
282
|
-
- P2: normal-priority defect
|
|
282
|
+
- P2: normal-priority defect.
|
|
283
283
|
- P3: low-priority suggestion.
|
|
284
|
-
|
|
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.
|
|
285
286
|
- On subsequent reviews, verify earlier fixes and inspect their effects on
|
|
286
287
|
callers and dependencies. Older code within the PR remains reviewable.
|
|
287
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,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0101
|
|
3
|
+
title: A run is named in Fleet by its own title, its repo's name, its branch and the account seen running it
|
|
4
|
+
status: proposed
|
|
5
|
+
date: 2026-10-08
|
|
6
|
+
supersedes: null
|
|
7
|
+
superseded-by: null
|
|
8
|
+
amends: null
|
|
9
|
+
amended-by: 0109, 0110, 0112
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
[ADR-0096](0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md)
|
|
15
|
+
allows four names per run on the usage upload: repo, branch, title and the
|
|
16
|
+
Anthropic account. It says what each may not be: a path, a working directory,
|
|
17
|
+
a machine name, or a prompt. It does not say where each comes from, and the
|
|
18
|
+
code offers a wrong answer for three of them:
|
|
19
|
+
|
|
20
|
+
- **Repo.** The only repo the code has is `working_directory`, which the cost
|
|
21
|
+
cohort keys on. It is a path, and the monitor shows it as one.
|
|
22
|
+
- **Title.** The monitor labels a run with the title a person set, then the
|
|
23
|
+
one the client generated, then the opening request (`render._topic`). The
|
|
24
|
+
third is the prompt.
|
|
25
|
+
- **Account.** No transcript records who was signed in. `login_type` reads
|
|
26
|
+
`oauthAccount.billingType` from Claude Code's config, today's value, and the
|
|
27
|
+
baseline marks it `assumed` for history.
|
|
28
|
+
|
|
29
|
+
## Decision
|
|
30
|
+
|
|
31
|
+
1. **Title: the session's own, cleaned, never the prompt.** The main session's
|
|
32
|
+
`title`, else its `generated_title`. Control characters are removed,
|
|
33
|
+
whitespace collapsed, and the result capped at 80 characters. It is dropped
|
|
34
|
+
when, case and spacing aside, it appears in the opening request, or the
|
|
35
|
+
opening request appears in it. A run with no title of its own sends none.
|
|
36
|
+
2. **Repo: a name, from the remote.** The `origin` remote of the git repository
|
|
37
|
+
holding the main session's working directory, as its last two path segments
|
|
38
|
+
(`owner/repo`), without `.git`, userinfo or host. With no `origin`, the
|
|
39
|
+
repository's top-level directory name. Outside a repository, none. Read by
|
|
40
|
+
the daemon from `.git/config`, never by running `git`.
|
|
41
|
+
3. **Branch: as the session records it** (`git_branch`).
|
|
42
|
+
4. **Account: an opaque id, read live, and only for work seen live.** The
|
|
43
|
+
daemon reads `oauthAccount.accountUuid` from the same config `login_type`
|
|
44
|
+
reads: stable per Anthropic account, it tells two people on a shared box
|
|
45
|
+
apart and names neither. A run takes the account signed in the first time
|
|
46
|
+
the daemon sees a response of it at or after the daemon's start, and keeps
|
|
47
|
+
it. A run whose responses all predate the start, including the 30-day
|
|
48
|
+
backfill, sends none.
|
|
49
|
+
5. **Each name passes the gate or travels as null.** Repo, branch, title,
|
|
50
|
+
account and model are checked with `enforce_usage_upload_contract`'s string
|
|
51
|
+
rules before they are stored, so a branch that looks like a path never costs
|
|
52
|
+
a page.
|
|
53
|
+
|
|
54
|
+
The cost cohort keeps `working_directory`. It is local, and a cohort per
|
|
55
|
+
checkout is what Phase 1 measures.
|
|
56
|
+
|
|
57
|
+
## Alternatives considered
|
|
58
|
+
|
|
59
|
+
- **The working directory's last component as the repo.** Rejected: outside a
|
|
60
|
+
repository it is often the home directory, so it names the user, and two
|
|
61
|
+
machines' checkouts of one repository get different names, which defeats
|
|
62
|
+
Fleet's "by repo" view.
|
|
63
|
+
- **Run `git remote get-url origin`.** Rejected: a subprocess per run per
|
|
64
|
+
pass, from a daemon that otherwise execs nothing, to read one line of a file.
|
|
65
|
+
- **The opening request, shortened, when there is no title.** Rejected:
|
|
66
|
+
ADR-0096 clause 3. A shortened prompt is a prompt.
|
|
67
|
+
- **Drop a title only when it equals the prompt.** Rejected: a generated title
|
|
68
|
+
that copies the first words of the request carries them verbatim. Dropping
|
|
69
|
+
any title found inside the request loses some good titles, which is the safe
|
|
70
|
+
direction.
|
|
71
|
+
- **Assume today's account for history**, as the baseline's `login` does.
|
|
72
|
+
Rejected for the wire: the account is what names a person on a shared box,
|
|
73
|
+
and a guess names the wrong one. The baseline's mark is local and says
|
|
74
|
+
`assumed`.
|
|
75
|
+
- **The account's email.** Rejected: it names the person directly, and
|
|
76
|
+
personal data that need not leave the machine does not. Unique and readable
|
|
77
|
+
per person is exactly what makes an identifier name someone, so no readable
|
|
78
|
+
field of `oauthAccount` is a safe alternative.
|
|
79
|
+
- **The account's display name, or the local username.** Rejected: both are
|
|
80
|
+
a person's name, neither is unique, and on a shared dev box or CI runner
|
|
81
|
+
the username is the same for everyone.
|
|
82
|
+
- **A hash of the UUID.** Not taken. It would stop anyone mapping the id to a
|
|
83
|
+
person, including an org that wants to. The UUID already names no one; only
|
|
84
|
+
someone with access to the org's Anthropic account can map it.
|
|
85
|
+
|
|
86
|
+
## Consequences
|
|
87
|
+
|
|
88
|
+
- Fleet's "by repo" view joins checkouts across machines by their remote.
|
|
89
|
+
- Backfilled history is attributed to the Fleet key only. A shared box's past
|
|
90
|
+
30 days cannot be split by person.
|
|
91
|
+
- Fleet shows the account as a readable label derived from the UUID, such as
|
|
92
|
+
`account brave-otter-7f3a`, keyed by the UUID so two accounts never merge.
|
|
93
|
+
An org that wants names attaches one to an account inside Fleet. That is
|
|
94
|
+
Fleet's to build; nothing more travels for it.
|
|
95
|
+
- The field name `accountUuid` is the one Claude Code writes: its
|
|
96
|
+
`oauthAccount` builder sets it beside `emailAddress` and `organizationUuid`
|
|
97
|
+
(checked against the shipped 2.1.294 binary on 2026-10-08). Claude Code
|
|
98
|
+
reads a legacy `.config.json` in its configuration directory before
|
|
99
|
+
`.claude.json`, and so does the daemon. A missing field reads as no account,
|
|
100
|
+
never as an error.
|
|
101
|
+
- A title is still the easiest place for conversation to leak (ADR-0096). Watch
|
|
102
|
+
generated titles that quote a file name or an error message.
|
|
103
|
+
|
|
104
|
+
## When to revisit
|
|
105
|
+
|
|
106
|
+
- If Claude Code records the signed-in account in transcripts, read it there
|
|
107
|
+
and send it for history too.
|
|
108
|
+
- If an org asks for titles off, through Task 12's policy field, add the switch
|
|
109
|
+
then.
|
|
110
|
+
- If titles are found to carry conversation in practice, narrow clause 1 rather
|
|
111
|
+
than add a filter per case.
|
stacktrace_cli-0.10.0/docs/adrs/0102-token-use-is-never-compared-with-a-providers-usage-api.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0102
|
|
3
|
+
title: Token use is never compared with a provider's usage API
|
|
4
|
+
status: accepted
|
|
5
|
+
date: 2026-10-08
|
|
6
|
+
supersedes: null
|
|
7
|
+
superseded-by: null
|
|
8
|
+
amends: null
|
|
9
|
+
amended-by: null
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
`cost-phase-2.md` listed a reconciliation: Fleet would compare each org's
|
|
15
|
+
daily token totals with the provider's usage API and show the share of
|
|
16
|
+
usage Stacktrace did not see. `cost.md` said Phase 2 would measure that
|
|
17
|
+
coverage gap this way, and its Phase 4 was done when each agent's recorded
|
|
18
|
+
tokens reconciled with the provider's counts. The spec left one question open:
|
|
19
|
+
whether to ask each org for an Anthropic admin key, which the usage API
|
|
20
|
+
needs. On 2026-10-08 the product owner answered it: drop the feature
|
|
21
|
+
completely, because Stacktrace doesn't do that.
|
|
22
|
+
|
|
23
|
+
## Decision
|
|
24
|
+
|
|
25
|
+
Stacktrace never compares, reconciles or checks its token figures against a
|
|
26
|
+
provider's usage API, billing export or invoice, in the environment or in
|
|
27
|
+
Fleet. It never asks an org for a provider admin key. Every figure is what the
|
|
28
|
+
transcripts record (ADR-0099), and the gap between that and what the provider
|
|
29
|
+
saw is stated in words where it matters, never measured.
|
|
30
|
+
|
|
31
|
+
## Alternatives considered
|
|
32
|
+
|
|
33
|
+
- **Reconcile daily totals with the Anthropic usage API, given an admin key.**
|
|
34
|
+
Rejected by the product owner. It would also make Fleet hold a credential
|
|
35
|
+
with organisation-wide reach on the provider's side, for a comparison the
|
|
36
|
+
product doesn't need.
|
|
37
|
+
- **Reconcile only for orgs that offer a key.** Rejected with it: the feature
|
|
38
|
+
is dropped, not made optional.
|
|
39
|
+
- **Compare against an uploaded billing export.** Rejected for the same
|
|
40
|
+
reason, and it brings money into a product measured in tokens (ADR-0099).
|
|
41
|
+
|
|
42
|
+
## Consequences
|
|
43
|
+
|
|
44
|
+
- No provider credential is asked for or held, in either repo.
|
|
45
|
+
- Usage from machines without Stacktrace, or from other tools on the same
|
|
46
|
+
key, stays invisible, and nothing estimates how much there is. The specs say
|
|
47
|
+
so rather than promising a measurement.
|
|
48
|
+
- Plan 017's Task 6 is removed, and with it Fleet's daily comparison and
|
|
49
|
+
"unattributed share".
|
|
50
|
+
- Phase 4 is done when Codex and Cursor sessions are counted by the same
|
|
51
|
+
rules as Claude Code's, not when anyone's totals match a provider's.
|
|
52
|
+
|
|
53
|
+
## When to revisit
|
|
54
|
+
|
|
55
|
+
If the product owner asks for a comparison with a provider's figures.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0103
|
|
3
|
+
title: A finished run may leave as its baseline numbers, for org-wide baselines
|
|
4
|
+
status: accepted
|
|
5
|
+
date: 2026-10-08
|
|
6
|
+
supersedes: null
|
|
7
|
+
superseded-by: null
|
|
8
|
+
amends: 0096
|
|
9
|
+
amended-by: 0114, 0115
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
Cost Phase 2 gives an environment with fewer than 20 similar sessions of its
|
|
15
|
+
own the org's baselines for the same repo, entrypoint and model, so its waste
|
|
16
|
+
rules work from day one (`cost-phase-2.md` §2, plan 017 Task 12). Fleet can
|
|
17
|
+
build those only from the figures each environment's baseline is made of: per
|
|
18
|
+
finished run, its tokens by active minute, its burn and its behaviour measures
|
|
19
|
+
(ADR-0093). [ADR-0096](0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md)
|
|
20
|
+
closes what the usage upload may carry to token totals and a short list of work
|
|
21
|
+
identifiers, so none of these may leave today. The product owner asked for the
|
|
22
|
+
amendment on 2026-10-08, on one condition: aggregate numbers only, never any of
|
|
23
|
+
the trace itself.
|
|
24
|
+
|
|
25
|
+
## Decision
|
|
26
|
+
|
|
27
|
+
This amends ADR-0096 clause 2 for the cost usage upload alone. Clauses 1 and 3,
|
|
28
|
+
and the rest of ADR-0006, stay in force.
|
|
29
|
+
|
|
30
|
+
1. **Per finished run, its baseline numbers.** For each run the environment's
|
|
31
|
+
baseline holds (ADR-0093), and only once it has finished, the upload may
|
|
32
|
+
carry these and nothing else:
|
|
33
|
+
- `tokens`: recorded tokens, the run's total;
|
|
34
|
+
- `curve`: cumulative recorded tokens at the end of each active minute, at
|
|
35
|
+
most 240 values;
|
|
36
|
+
- `burn`: recorded tokens in the 5 minutes ending at each active minute, at
|
|
37
|
+
most 240 values;
|
|
38
|
+
- `subagents_in_10m`: the most sub-agents started within 10 minutes;
|
|
39
|
+
- `repeats`: how many times the most repeated call returned an unchanged
|
|
40
|
+
result, as a count;
|
|
41
|
+
- `input_per_response`: the 90th percentile of tokens sent per call;
|
|
42
|
+
- `lowest_cache_share`: the lowest cache-read share over 5 calls in a row on
|
|
43
|
+
a large context, or null;
|
|
44
|
+
- `cache_rewrites`: how many times the cache was rewritten on a large
|
|
45
|
+
context;
|
|
46
|
+
- the run's cohort: its repo as ADR-0101 names it (`owner/repo` or a
|
|
47
|
+
directory name, never a path), its entrypoint, and the model that carried
|
|
48
|
+
most of its tokens;
|
|
49
|
+
- the time of its last response, and a revision.
|
|
50
|
+
2. **Numbers, never trace.** Each figure is a count, a token total or a ratio
|
|
51
|
+
the environment computes from the transcript. No call, tool name, argument,
|
|
52
|
+
result, file name, prompt, title or message travels with it, and none can be
|
|
53
|
+
recovered from it: `repeats` says how often, never what repeated. The
|
|
54
|
+
baseline's day slots (tokens by quarter hour of the day) stay on the
|
|
55
|
+
machine.
|
|
56
|
+
3. **Back from Fleet, percentiles only.** Fleet returns, beside the policy
|
|
57
|
+
document, each cohort's percentiles over the org's last 30 days (p5, p50,
|
|
58
|
+
p95, p99 of each measure, and p50, p95, p99 of the curve and the burn at
|
|
59
|
+
each active minute) for cohorts with at least 20 runs. Never a run's own
|
|
60
|
+
figures, and never who ran it.
|
|
61
|
+
4. **Runs a cost finding was raised on stay home.** They leave the local
|
|
62
|
+
baseline (ADR-0093), so they are not sent for the org's either.
|
|
63
|
+
|
|
64
|
+
## Alternatives considered
|
|
65
|
+
|
|
66
|
+
- **Send the day slots too, for an org day curve.** Rejected: they say when a
|
|
67
|
+
person works, the day curve is `personal-anomaly`'s, and Fleet already has
|
|
68
|
+
each owner's day from the token buckets.
|
|
69
|
+
- **Send which call repeated, or the tools a run used.** Rejected: that is the
|
|
70
|
+
trace. The rules need how often, not what.
|
|
71
|
+
- **Compute the org's percentiles from the token buckets alone.** Rejected:
|
|
72
|
+
buckets carry tokens per minute, not the behaviour measures the waste rules
|
|
73
|
+
judge (sub-agents, repeats, input per call, the cache).
|
|
74
|
+
- **Ship each environment's own percentiles and merge them in Fleet.**
|
|
75
|
+
Rejected: percentiles do not merge, and an environment below 20 runs, the
|
|
76
|
+
case this exists for, has none.
|
|
77
|
+
|
|
78
|
+
## Consequences
|
|
79
|
+
|
|
80
|
+
- `usage-upload.md` declares `run_figures`, and `enforce_usage_upload_contract`
|
|
81
|
+
refuses any key or string beyond it. A test walks the declared shape and
|
|
82
|
+
fails on any field that is not a number, other than the cohort names, the run
|
|
83
|
+
id and the time.
|
|
84
|
+
- An environment's evidence says "the org's runs" when an org cohort judged it,
|
|
85
|
+
never "this developer's".
|
|
86
|
+
- Fleet holds 30 days of per-run numbers per org.
|
|
87
|
+
|
|
88
|
+
## When to revisit
|
|
89
|
+
|
|
90
|
+
If any figure is found to carry content, or a new waste rule needs a measure
|
|
91
|
+
not listed here: amend clause 1, never widen it by implication.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: 0104
|
|
3
|
+
title: Usage is its own upload, with its own job, its own gate and the store as its backlog
|
|
4
|
+
status: proposed
|
|
5
|
+
date: 2026-10-08
|
|
6
|
+
supersedes: null
|
|
7
|
+
superseded-by: null
|
|
8
|
+
amends: 0061
|
|
9
|
+
amended-by: null
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
Cost Phase 2 needs every environment's tokens in Fleet (`cost-phase-2.md` §1).
|
|
15
|
+
[ADR-0096](0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md)
|
|
16
|
+
decides what may leave: token totals per run, session, model and minute, and a
|
|
17
|
+
closed set of names per run. It does not decide how.
|
|
18
|
+
|
|
19
|
+
Three things already in the code push on that:
|
|
20
|
+
|
|
21
|
+
- ADR-0061 made the findings drain send findings and unknowns, nothing else,
|
|
22
|
+
and stopped the daemon capturing counters at all, because nothing read them.
|
|
23
|
+
- The detect-run gate (`enforce_detect_upload_contract`) declares one document's
|
|
24
|
+
shape and refuses every key outside it. It cannot pass a usage document, and
|
|
25
|
+
should not learn to.
|
|
26
|
+
- The findings queue is append-only and drained by a `seq` cursor (ADR-0046). A
|
|
27
|
+
usage bucket is not an event: it changes in place as a response grows
|
|
28
|
+
(OpenAIDR ADR-0014), so a cursor over it needs an append per change.
|
|
29
|
+
|
|
30
|
+
## Decision
|
|
31
|
+
|
|
32
|
+
1. **A new endpoint**, `POST /api/v1/usage`, one request per agent kind, in the
|
|
33
|
+
shape [`usage-upload.md`](../specs/usage-upload.md) declares. `detect-runs`
|
|
34
|
+
is unchanged.
|
|
35
|
+
2. **A new job**, on its own thread, beside the findings drain and the BOM job.
|
|
36
|
+
It shares only the asset-transition lock with them (both can re-register an
|
|
37
|
+
asset). It is woken by the cost pass when a bucket changes, at most every
|
|
38
|
+
10 s, and runs every 60 s as a heartbeat otherwise.
|
|
39
|
+
3. **The daemon captures counters again, for this reader.** This amends
|
|
40
|
+
ADR-0061 clause 2, which stopped capture because nothing read it. Token
|
|
41
|
+
usage is a different counter with a reader, kept in its own tables
|
|
42
|
+
(`usage_buckets`, `usage_runs`, `usage_state`), additive under ADR-0057.
|
|
43
|
+
Clause 1 stands: the drain sends findings only.
|
|
44
|
+
4. **The store is the backlog.** Each row keeps its revision and the revision
|
|
45
|
+
Fleet last accepted. A row whose two differ is pending. Buckets merge by
|
|
46
|
+
max, so every writer commutes and a count never falls.
|
|
47
|
+
5. **Its own gate**, `enforce_usage_upload_contract`, built from the same walk
|
|
48
|
+
and the same three refusals as the detect-run gate: an undeclared key, a
|
|
49
|
+
rooted path or a URI naming a place, a credential. The producer checks each
|
|
50
|
+
name before the gate and sends `null` for one that would be refused.
|
|
51
|
+
6. **No bisection and no parking.** A 422 holds every row and is reported.
|
|
52
|
+
Usage carries counts and names checked locally, so a refusal is a wire
|
|
53
|
+
mismatch, and splitting a page cannot isolate one.
|
|
54
|
+
|
|
55
|
+
## Alternatives considered
|
|
56
|
+
|
|
57
|
+
- **Put usage on the findings drain.** Rejected, as ADR-0096 already rejected
|
|
58
|
+
it: ADR-0061 keeps the detection document one shape, and a usage backlog
|
|
59
|
+
would hold findings behind it.
|
|
60
|
+
- **A `seq` cursor over an append-only usage log.** Rejected: every rewrite of a
|
|
61
|
+
growing response appends a row, and the reader must collapse them to the
|
|
62
|
+
latest per key before it sends. A revision per row is the collapsed form.
|
|
63
|
+
- **Replace on write.** Rejected: the backfill thread and the pass both write,
|
|
64
|
+
and an older read landing last would lower a bucket Fleet already holds at a
|
|
65
|
+
higher count, at a higher revision Fleet would then keep.
|
|
66
|
+
- **Widen `_DETECT_RUN_SHAPE` to cover both documents.** Rejected: a declared
|
|
67
|
+
shape is what makes "a key it does not name is refused" mean something. One
|
|
68
|
+
shape for two documents lets a usage field ride on a detect run.
|
|
69
|
+
- **Reuse the drain's bisection.** Rejected: it exists to isolate one bad
|
|
70
|
+
finding among good ones. Usage has no row-shaped failure the producer can
|
|
71
|
+
reach, and bisecting a wire mismatch spends log₂(n) requests to refuse them
|
|
72
|
+
all.
|
|
73
|
+
- **Send usage through `remote sync`, daemon-less.** Not built. A cron cannot
|
|
74
|
+
keep a 10-second cadence or a heartbeat, and the backlog needs the store.
|
|
75
|
+
|
|
76
|
+
## Consequences
|
|
77
|
+
|
|
78
|
+
- Fleet's Task 3 implements the endpoint against `usage-upload.md`. Until it
|
|
79
|
+
ships, a configured machine meets a 404, re-registers once, and backs off for
|
|
80
|
+
an hour. `personal-anomaly` keeps running, since its retirement waits for an
|
|
81
|
+
accepted request.
|
|
82
|
+
- A row Fleet refuses holds the backlog until the cause is fixed. `daemon
|
|
83
|
+
status` names it.
|
|
84
|
+
- The store grows by one row per session, model and active minute, pruned at 7
|
|
85
|
+
days once sent and at 30 days regardless.
|
|
86
|
+
- A bucket that genuinely shrinks never says so. No case of one is known.
|
|
87
|
+
|
|
88
|
+
## When to revisit
|
|
89
|
+
|
|
90
|
+
- If Fleet answers usage refusals per row, bisection becomes worth its code.
|
|
91
|
+
- If a second producer, such as a daemon-less posture, needs to send usage, the
|
|
92
|
+
backlog cannot stay in the daemon's store alone.
|