stacktrace-cli 0.9.0__tar.gz → 0.11.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.11.0/.agents/skills/release-stacktrace/SKILL.md +249 -0
- stacktrace_cli-0.11.0/.github/workflows/bedrock-live.yml +55 -0
- stacktrace_cli-0.11.0/.github/workflows/guard-staging.yml +143 -0
- stacktrace_cli-0.11.0/.github/workflows/publish-pypi.yml +178 -0
- stacktrace_cli-0.11.0/.gitignore +15 -0
- stacktrace_cli-0.11.0/CLAUDE.md +399 -0
- stacktrace_cli-0.11.0/PKG-INFO +262 -0
- stacktrace_cli-0.11.0/README.md +234 -0
- stacktrace_cli-0.11.0/contracts/observations/v1/decision-request.example.json +23 -0
- stacktrace_cli-0.11.0/contracts/observations/v1/decision-request.schema.json +162 -0
- stacktrace_cli-0.11.0/contracts/observations/v1/decision-response.example.json +10 -0
- stacktrace_cli-0.11.0/contracts/observations/v1/decision-response.schema.json +66 -0
- stacktrace_cli-0.11.0/contracts/observations/v1/example.json +26 -0
- stacktrace_cli-0.11.0/contracts/observations/v1/schema.json +152 -0
- stacktrace_cli-0.11.0/docs/adrs/0001-session-telemetry-as-input.md +117 -0
- stacktrace_cli-0.11.0/docs/adrs/0004-three-stage-detector.md +159 -0
- stacktrace_cli-0.11.0/docs/adrs/0006-trust-boundary-and-detection-upload.md +179 -0
- stacktrace_cli-0.11.0/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +115 -0
- stacktrace_cli-0.11.0/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +94 -0
- stacktrace_cli-0.11.0/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +82 -0
- stacktrace_cli-0.11.0/docs/adrs/0045-scan-every-session-and-outlive-them.md +137 -0
- stacktrace_cli-0.11.0/docs/adrs/0061-the-drain-sends-findings-only.md +118 -0
- stacktrace_cli-0.11.0/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +119 -0
- stacktrace_cli-0.11.0/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +162 -0
- stacktrace_cli-0.11.0/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +74 -0
- stacktrace_cli-0.11.0/docs/adrs/0092-cost-is-its-own-rule-family.md +49 -0
- stacktrace_cli-0.11.0/docs/adrs/0093-environment-cost-baselines-count-tokens-keyed-by-model.md +78 -0
- stacktrace_cli-0.11.0/docs/adrs/0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md +86 -0
- stacktrace_cli-0.11.0/docs/adrs/0101-what-names-a-run-in-fleet.md +111 -0
- stacktrace_cli-0.11.0/docs/adrs/0102-token-use-is-never-compared-with-a-providers-usage-api.md +55 -0
- stacktrace_cli-0.11.0/docs/adrs/0103-finished-runs-may-leave-as-numbers-for-org-baselines.md +91 -0
- stacktrace_cli-0.11.0/docs/adrs/0104-usage-is-its-own-upload.md +92 -0
- stacktrace_cli-0.11.0/docs/adrs/0105-an-asset-key-is-a-bare-uuid.md +76 -0
- stacktrace_cli-0.11.0/docs/adrs/0106-boot-id-is-salted-with-the-pid-namespace.md +69 -0
- stacktrace_cli-0.11.0/docs/adrs/0107-the-daemon-follows-every-kind-openaidr-reads.md +114 -0
- stacktrace_cli-0.11.0/docs/adrs/0108-a-kind-renamed-before-any-release-read-it-keeps-no-alias.md +68 -0
- stacktrace_cli-0.11.0/docs/adrs/0109-a-detection-carries-its-runs-title-and-the-persons-name.md +106 -0
- stacktrace_cli-0.11.0/docs/adrs/0110-every-kinds-account-comes-from-openaidr.md +70 -0
- stacktrace_cli-0.11.0/docs/adrs/0111-built-in-sub-agents-and-skills-come-from-the-bom.md +74 -0
- stacktrace_cli-0.11.0/docs/adrs/0112-a-person-is-known-by-the-accounts-on-the-host.md +137 -0
- stacktrace_cli-0.11.0/docs/adrs/0113-size-triggers-behaviour-explains-session-cost-carries-reasons.md +103 -0
- stacktrace_cli-0.11.0/docs/adrs/0114-similar-sessions-are-the-same-agent-in-the-same-repo.md +79 -0
- stacktrace_cli-0.11.0/docs/adrs/0115-usage-states-its-coverage-and-fleet-returns-expected-runs.md +93 -0
- stacktrace_cli-0.11.0/docs/adrs/0116-a-component-row-carries-what-its-results-cost-under-one-closed-key.md +84 -0
- stacktrace_cli-0.11.0/docs/adrs/0117-a-component-row-on-the-day-of-a-switch-counts-from-the-switch.md +60 -0
- stacktrace_cli-0.11.0/docs/adrs/0118-observe-agents-through-adapters-and-a-shared-analyzer.md +165 -0
- stacktrace_cli-0.11.0/docs/adrs/0119-read-sessions-from-an-ai-gateway-and-block-inline.md +184 -0
- stacktrace_cli-0.11.0/docs/adrs/0120-own-the-adapter-event-envelope.md +49 -0
- stacktrace_cli-0.11.0/docs/adrs/0121-a-cloud-sessions-runs-are-its-persons-and-a-card-says-where-its-name-came-from.md +84 -0
- stacktrace_cli-0.11.0/docs/adrs/0122-use-stacktrace-as-the-python-package.md +45 -0
- stacktrace_cli-0.11.0/docs/adrs/0123-the-cloud-boot-hook-brings-the-client-up-to-the-latest-release.md +128 -0
- stacktrace_cli-0.11.0/docs/adrs/0124-fleet-imports-core-from-the-stacktrace-distribution.md +48 -0
- stacktrace_cli-0.11.0/docs/adrs/INDEX.md +160 -0
- stacktrace_cli-0.11.0/docs/plans/017-cost-phase-2.md +325 -0
- stacktrace_cli-0.11.0/docs/releases/v0.10.0.md +136 -0
- stacktrace_cli-0.11.0/docs/releases/v0.11.0.md +91 -0
- stacktrace_cli-0.11.0/docs/specs/agent-observability.md +324 -0
- stacktrace_cli-0.11.0/docs/specs/aidr.md +511 -0
- stacktrace_cli-0.11.0/docs/specs/correlation.md +592 -0
- stacktrace_cli-0.11.0/docs/specs/cost-notifications.md +721 -0
- stacktrace_cli-0.11.0/docs/specs/cost-phase-1.md +508 -0
- stacktrace_cli-0.11.0/docs/specs/cost-phase-2.md +190 -0
- stacktrace_cli-0.11.0/docs/specs/cost.md +274 -0
- stacktrace_cli-0.11.0/docs/specs/daemon-store.md +256 -0
- stacktrace_cli-0.11.0/docs/specs/daemon-uploads.md +382 -0
- stacktrace_cli-0.11.0/docs/specs/detection-policies.md +518 -0
- stacktrace_cli-0.11.0/docs/specs/detection-upload.md +490 -0
- stacktrace_cli-0.11.0/docs/specs/detector.md +1117 -0
- stacktrace_cli-0.11.0/docs/specs/monitor.md +878 -0
- stacktrace_cli-0.11.0/docs/specs/notification-delivery.md +304 -0
- stacktrace_cli-0.11.0/docs/specs/production-agent-observability.md +136 -0
- stacktrace_cli-0.11.0/docs/specs/reasoning-jev.md +463 -0
- stacktrace_cli-0.11.0/docs/specs/usage-upload.md +402 -0
- stacktrace_cli-0.11.0/examples/observations/custom_agent.py +50 -0
- stacktrace_cli-0.11.0/infra/README.md +30 -0
- stacktrace_cli-0.11.0/infra/bedrock-sandbox/.gitignore +5 -0
- stacktrace_cli-0.11.0/infra/bedrock-sandbox/ci.tf +63 -0
- stacktrace_cli-0.11.0/infra/bedrock-sandbox/main.tf +177 -0
- stacktrace_cli-0.11.0/infra/bedrock-sandbox/outputs.tf +24 -0
- stacktrace_cli-0.11.0/infra/bedrock-sandbox/variables.tf +63 -0
- stacktrace_cli-0.11.0/infra/guard-staging/.gitignore +5 -0
- stacktrace_cli-0.11.0/infra/guard-staging/README.md +207 -0
- stacktrace_cli-0.11.0/infra/guard-staging/check.sh +259 -0
- stacktrace_cli-0.11.0/infra/guard-staging/ci.tf +57 -0
- stacktrace_cli-0.11.0/infra/guard-staging/connect.sh +64 -0
- stacktrace_cli-0.11.0/infra/guard-staging/images/envoy/Dockerfile +36 -0
- stacktrace_cli-0.11.0/infra/guard-staging/images/envoy/entrypoint.sh +13 -0
- stacktrace_cli-0.11.0/infra/guard-staging/images/envoy/litellm.yaml +43 -0
- stacktrace_cli-0.11.0/infra/guard-staging/images/litellm/Dockerfile +30 -0
- stacktrace_cli-0.11.0/infra/guard-staging/images/litellm/config.subscription.yaml +44 -0
- stacktrace_cli-0.11.0/infra/guard-staging/images/litellm/config.yaml +49 -0
- stacktrace_cli-0.11.0/infra/guard-staging/images/litellm/entrypoint.sh +8 -0
- stacktrace_cli-0.11.0/infra/guard-staging/main.tf +184 -0
- stacktrace_cli-0.11.0/infra/guard-staging/moved.tf +32 -0
- stacktrace_cli-0.11.0/infra/guard-staging/outputs.tf +55 -0
- stacktrace_cli-0.11.0/infra/guard-staging/smoke.sh +95 -0
- stacktrace_cli-0.11.0/infra/guard-staging/user-key.sh +26 -0
- stacktrace_cli-0.11.0/infra/guard-staging/variables.tf +67 -0
- stacktrace_cli-0.11.0/infra/modules/express-gateway/main.tf +62 -0
- stacktrace_cli-0.11.0/infra/modules/express-gateway/outputs.tf +19 -0
- stacktrace_cli-0.11.0/infra/modules/express-gateway/variables.tf +63 -0
- stacktrace_cli-0.11.0/integrations/e2e/claude.sh +12 -0
- stacktrace_cli-0.11.0/integrations/e2e/scenarios.sh +20 -0
- stacktrace_cli-0.11.0/integrations/envoy/envoy.yaml +147 -0
- stacktrace_cli-0.11.0/integrations/envoy/run.sh +3 -0
- stacktrace_cli-0.11.0/integrations/litellm/README.md +104 -0
- stacktrace_cli-0.11.0/integrations/litellm/config.example.yaml +28 -0
- stacktrace_cli-0.11.0/integrations/litellm/config.subscription.yaml +30 -0
- stacktrace_cli-0.11.0/integrations/litellm/e2e/config.baseten.yaml +20 -0
- stacktrace_cli-0.11.0/integrations/litellm/e2e/config.mock.yaml +12 -0
- stacktrace_cli-0.11.0/integrations/litellm/e2e/mock_upstream.py +431 -0
- stacktrace_cli-0.11.0/integrations/litellm/e2e/parity.py +70 -0
- stacktrace_cli-0.11.0/integrations/litellm/stacktrace_keys.py +111 -0
- stacktrace_cli-0.11.0/integrations/litellm/stacktrace_litellm.py +454 -0
- stacktrace_cli-0.11.0/pyproject.toml +124 -0
- stacktrace_cli-0.11.0/scripts/cost_latency.py +85 -0
- stacktrace_cli-0.11.0/src/stacktrace/__init__.py +14 -0
- stacktrace_cli-0.11.0/src/stacktrace/__main__.py +14 -0
- stacktrace_cli-0.11.0/src/stacktrace/analysis.py +664 -0
- stacktrace_cli-0.11.0/src/stacktrace/cli.py +643 -0
- stacktrace_cli-0.11.0/src/stacktrace/cloud/__init__.py +60 -0
- stacktrace_cli-0.11.0/src/stacktrace/cloud/setup.sh +469 -0
- stacktrace_cli-0.11.0/src/stacktrace/core/__init__.py +27 -0
- stacktrace_cli-0.11.0/src/stacktrace/core/observations.py +222 -0
- stacktrace_cli-0.11.0/src/stacktrace/correlate/acquire.py +541 -0
- stacktrace_cli-0.11.0/src/stacktrace/correlate/composition.py +479 -0
- stacktrace_cli-0.11.0/src/stacktrace/correlate/join.py +381 -0
- stacktrace_cli-0.11.0/src/stacktrace/correlate/observed.py +1917 -0
- stacktrace_cli-0.11.0/src/stacktrace/correlate/orchestrate.py +534 -0
- stacktrace_cli-0.11.0/src/stacktrace/correlate/record.py +287 -0
- stacktrace_cli-0.11.0/src/stacktrace/correlate/render.py +768 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/baseline.py +548 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/component_usage.py +324 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/components.py +143 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/ledger.py +58 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/measures.py +346 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/org_baselines.py +258 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/reasons.py +592 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/rules.py +662 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/runs.py +149 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/tokens.py +69 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/totals.py +62 -0
- stacktrace_cli-0.11.0/src/stacktrace/cost/usage.py +298 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/accounts.py +272 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/activity_log.py +94 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/bom.py +56 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/cli.py +740 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/client.py +396 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/composition.py +294 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/config.py +322 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/costs.py +780 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/db.py +957 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/fleet.py +729 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/identity.py +99 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/lifecycle.py +172 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/observer.py +755 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/paths.py +40 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/presentation.py +180 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/runtime.py +978 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/scan.py +287 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/server.py +317 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/store.py +2454 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/usage.py +1170 -0
- stacktrace_cli-0.11.0/src/stacktrace/daemon/webhook.py +529 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/analyzer.py +205 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/blocked.py +462 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/cache.py +723 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/deterministic.py +2908 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/finding.py +507 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/history.py +210 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/jev.py +213 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/priors.py +270 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/prompts/__init__.py +51 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/reasoning.py +1861 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/render.py +478 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/rules.py +262 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/run.py +1185 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/secrets.py +519 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/verdict.py +266 -0
- stacktrace_cli-0.11.0/src/stacktrace/detector/windows.py +443 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/__init__.py +1 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/analyzer.py +392 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/check.py +117 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/cli.py +63 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/exchange.py +77 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/formats/__init__.py +179 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/formats/_json.py +180 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/formats/anthropic.py +158 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/formats/bedrock.py +141 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/formats/body.py +196 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/formats/openai_chat.py +194 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/formats/openai_responses.py +186 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/service.py +117 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/session.py +274 -0
- stacktrace_cli-0.11.0/src/stacktrace/gateway/sink.py +207 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/__init__.py +12 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/costs.py +650 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/inventory.py +495 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/offline.py +266 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/reasoning.py +306 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/render.py +835 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/server.py +749 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/site/app.js +3269 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/site/cost.js +1008 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/site/fonts/OFL.txt +309 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/site/fonts/playfair-display-600-italic-latin.woff2 +0 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/site/index.html +179 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/site/inventory.js +561 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/site/styles.css +902 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/verdicts.py +52 -0
- stacktrace_cli-0.11.0/src/stacktrace/monitor/watch.py +805 -0
- stacktrace_cli-0.11.0/src/stacktrace/options.py +107 -0
- stacktrace_cli-0.11.0/src/stacktrace/private_state.py +37 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/cli.py +655 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/client.py +448 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/detect_payload.py +508 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/identity.py +342 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/payload.py +443 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/policy.py +88 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/policy_service.py +1637 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/redact.py +1306 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/spool.py +449 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/sync.py +807 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/sync_detect.py +536 -0
- stacktrace_cli-0.11.0/src/stacktrace/remote/upload_contract.py +1143 -0
- stacktrace_cli-0.11.0/src/stacktrace/sdk.py +232 -0
- stacktrace_cli-0.11.0/src/stacktrace/sessions/access.py +222 -0
- stacktrace_cli-0.11.0/src/stacktrace/sessions/outcome.py +65 -0
- stacktrace_cli-0.11.0/src/stacktrace/sessions/protocols.py +316 -0
- stacktrace_cli-0.11.0/src/stacktrace/sessions/render.py +301 -0
- stacktrace_cli-0.11.0/src/stacktrace/telemetry/events.py +500 -0
- stacktrace_cli-0.11.0/src/stacktrace/telemetry/state.py +219 -0
- stacktrace_cli-0.11.0/src/stacktrace/webhook/cli.py +200 -0
- stacktrace_cli-0.11.0/src/stacktrace/webhook/config.py +193 -0
- stacktrace_cli-0.11.0/tests/agent_bom_fixture.py +261 -0
- stacktrace_cli-0.11.0/tests/conftest.py +177 -0
- stacktrace_cli-0.11.0/tests/cost/scenarios.py +313 -0
- stacktrace_cli-0.11.0/tests/cost/test_as_of_cuts_every_timed_collection.py +150 -0
- stacktrace_cli-0.11.0/tests/cost/test_baseline.py +261 -0
- stacktrace_cli-0.11.0/tests/cost/test_clock.py +61 -0
- stacktrace_cli-0.11.0/tests/cost/test_component_usage.py +307 -0
- stacktrace_cli-0.11.0/tests/cost/test_components.py +129 -0
- stacktrace_cli-0.11.0/tests/cost/test_cost_evidence_travels.py +135 -0
- stacktrace_cli-0.11.0/tests/cost/test_cost_findings_are_dated_by_their_citations.py +426 -0
- stacktrace_cli-0.11.0/tests/cost/test_cost_findings_carry_no_session_text.py +123 -0
- stacktrace_cli-0.11.0/tests/cost/test_cost_is_tokens.py +96 -0
- stacktrace_cli-0.11.0/tests/cost/test_cost_latency.py +82 -0
- stacktrace_cli-0.11.0/tests/cost/test_evidence.py +40 -0
- stacktrace_cli-0.11.0/tests/cost/test_ledger.py +44 -0
- stacktrace_cli-0.11.0/tests/cost/test_measures.py +251 -0
- stacktrace_cli-0.11.0/tests/cost/test_models.py +15 -0
- stacktrace_cli-0.11.0/tests/cost/test_org_baselines.py +333 -0
- stacktrace_cli-0.11.0/tests/cost/test_reasons.py +261 -0
- stacktrace_cli-0.11.0/tests/cost/test_rules_baseline.py +189 -0
- stacktrace_cli-0.11.0/tests/cost/test_rules_budget.py +189 -0
- stacktrace_cli-0.11.0/tests/cost/test_runs.py +43 -0
- stacktrace_cli-0.11.0/tests/cost/test_totals.py +55 -0
- stacktrace_cli-0.11.0/tests/cost/test_usage.py +255 -0
- stacktrace_cli-0.11.0/tests/daemon/observing.py +47 -0
- stacktrace_cli-0.11.0/tests/daemon/test_accounts.py +532 -0
- stacktrace_cli-0.11.0/tests/daemon/test_activity_log.py +350 -0
- stacktrace_cli-0.11.0/tests/daemon/test_cli.py +1440 -0
- stacktrace_cli-0.11.0/tests/daemon/test_client.py +396 -0
- stacktrace_cli-0.11.0/tests/daemon/test_composition.py +343 -0
- stacktrace_cli-0.11.0/tests/daemon/test_config.py +205 -0
- stacktrace_cli-0.11.0/tests/daemon/test_cost_guidance.py +23 -0
- stacktrace_cli-0.11.0/tests/daemon/test_costs.py +1350 -0
- stacktrace_cli-0.11.0/tests/daemon/test_db.py +900 -0
- stacktrace_cli-0.11.0/tests/daemon/test_detection_needs_no_subscriber.py +117 -0
- stacktrace_cli-0.11.0/tests/daemon/test_fleet.py +889 -0
- stacktrace_cli-0.11.0/tests/daemon/test_identity.py +91 -0
- stacktrace_cli-0.11.0/tests/daemon/test_job_thread.py +63 -0
- stacktrace_cli-0.11.0/tests/daemon/test_jobs.py +465 -0
- stacktrace_cli-0.11.0/tests/daemon/test_lifecycle.py +115 -0
- stacktrace_cli-0.11.0/tests/daemon/test_observer.py +1485 -0
- stacktrace_cli-0.11.0/tests/daemon/test_queue_reader.py +200 -0
- stacktrace_cli-0.11.0/tests/daemon/test_runtime.py +1735 -0
- stacktrace_cli-0.11.0/tests/daemon/test_scan.py +517 -0
- stacktrace_cli-0.11.0/tests/daemon/test_service.py +198 -0
- stacktrace_cli-0.11.0/tests/daemon/test_session_cost_notices.py +117 -0
- stacktrace_cli-0.11.0/tests/daemon/test_socket.py +547 -0
- stacktrace_cli-0.11.0/tests/daemon/test_stage_times.py +80 -0
- stacktrace_cli-0.11.0/tests/daemon/test_store.py +800 -0
- stacktrace_cli-0.11.0/tests/daemon/test_subagent_routing.py +154 -0
- stacktrace_cli-0.11.0/tests/daemon/test_the_drained_payload_is_the_cold_one.py +288 -0
- stacktrace_cli-0.11.0/tests/daemon/test_the_stored_row_is_sufficient.py +247 -0
- stacktrace_cli-0.11.0/tests/daemon/test_usage.py +1884 -0
- stacktrace_cli-0.11.0/tests/daemon/test_usage_store.py +988 -0
- stacktrace_cli-0.11.0/tests/daemon/test_webhook.py +1165 -0
- stacktrace_cli-0.11.0/tests/daemon/test_wire_frames_are_bounded.py +156 -0
- stacktrace_cli-0.11.0/tests/detector_session_fixture.py +156 -0
- stacktrace_cli-0.11.0/tests/gateway/fixtures/claude-code-2.1.296-suite/gateway-last-turn.json +259 -0
- stacktrace_cli-0.11.0/tests/gateway/fixtures/claude-code-2.1.296-suite/projects/run/b23c3bab-a677-4b5f-ac36-e132c7df29e5.jsonl +49 -0
- stacktrace_cli-0.11.0/tests/gateway/test_analyzer.py +400 -0
- stacktrace_cli-0.11.0/tests/gateway/test_bodies_and_logs.py +217 -0
- stacktrace_cli-0.11.0/tests/gateway/test_call_records.py +47 -0
- stacktrace_cli-0.11.0/tests/gateway/test_check.py +202 -0
- stacktrace_cli-0.11.0/tests/gateway/test_every_choice_is_read.py +37 -0
- stacktrace_cli-0.11.0/tests/gateway/test_every_read_field_is_validated.py +632 -0
- stacktrace_cli-0.11.0/tests/gateway/test_every_shortfall_is_a_recorded_fallback.py +350 -0
- stacktrace_cli-0.11.0/tests/gateway/test_gateway_keys.py +162 -0
- stacktrace_cli-0.11.0/tests/gateway/test_gateway_scripts.py +88 -0
- stacktrace_cli-0.11.0/tests/gateway/test_litellm_stream.py +283 -0
- stacktrace_cli-0.11.0/tests/gateway/test_litellm_subscription_config.py +48 -0
- stacktrace_cli-0.11.0/tests/gateway/test_parity_live_capture.py +103 -0
- stacktrace_cli-0.11.0/tests/gateway/test_service.py +291 -0
- stacktrace_cli-0.11.0/tests/gateway/test_session.py +371 -0
- stacktrace_cli-0.11.0/tests/gateway/test_unstated_outcomes.py +127 -0
- stacktrace_cli-0.11.0/tests/monitor/cost_harness.mjs +288 -0
- stacktrace_cli-0.11.0/tests/monitor/feed_harness.mjs +4052 -0
- stacktrace_cli-0.11.0/tests/monitor/inventory_harness.mjs +481 -0
- stacktrace_cli-0.11.0/tests/monitor/test_cost_page.py +548 -0
- stacktrace_cli-0.11.0/tests/monitor/test_cost_range_switch.py +143 -0
- stacktrace_cli-0.11.0/tests/monitor/test_feed_model.py +2181 -0
- stacktrace_cli-0.11.0/tests/monitor/test_inventory.py +866 -0
- stacktrace_cli-0.11.0/tests/monitor/test_offline.py +242 -0
- stacktrace_cli-0.11.0/tests/monitor/test_reasoning_gates.py +688 -0
- stacktrace_cli-0.11.0/tests/monitor/test_render.py +1150 -0
- stacktrace_cli-0.11.0/tests/monitor/test_render_cost.py +937 -0
- stacktrace_cli-0.11.0/tests/monitor/test_server.py +828 -0
- stacktrace_cli-0.11.0/tests/monitor/test_site_assets.py +473 -0
- stacktrace_cli-0.11.0/tests/monitor/test_state.py +148 -0
- stacktrace_cli-0.11.0/tests/monitor/test_verdicts.py +136 -0
- stacktrace_cli-0.11.0/tests/monitor/test_watch.py +2134 -0
- stacktrace_cli-0.11.0/tests/observations/test_contract.py +245 -0
- stacktrace_cli-0.11.0/tests/observations/test_decisions.py +54 -0
- stacktrace_cli-0.11.0/tests/observations/test_event_envelope.py +126 -0
- stacktrace_cli-0.11.0/tests/remote/__init__.py +0 -0
- stacktrace_cli-0.11.0/tests/remote/helpers.py +127 -0
- stacktrace_cli-0.11.0/tests/remote/test_cli.py +1018 -0
- stacktrace_cli-0.11.0/tests/remote/test_client.py +575 -0
- stacktrace_cli-0.11.0/tests/remote/test_cloud_boot_updates_the_client.py +264 -0
- stacktrace_cli-0.11.0/tests/remote/test_cloud_setup_asset_id.py +56 -0
- stacktrace_cli-0.11.0/tests/remote/test_config.py +129 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_activity.py +220 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_cli.py +72 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_client.py +82 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_contract_is_exhaustive.py +927 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_gate_matches_the_cloud.py +351 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_layers_compose.py +162 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_payload_reaches_the_cloud_model.py +286 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_redaction.py +823 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_spool.py +329 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_upload_contract.py +180 -0
- stacktrace_cli-0.11.0/tests/remote/test_detect_wire_payload.py +185 -0
- stacktrace_cli-0.11.0/tests/remote/test_facade_contract.py +415 -0
- stacktrace_cli-0.11.0/tests/remote/test_identity.py +486 -0
- stacktrace_cli-0.11.0/tests/remote/test_no_local_path_survives_redaction.py +376 -0
- stacktrace_cli-0.11.0/tests/remote/test_payload.py +940 -0
- stacktrace_cli-0.11.0/tests/remote/test_policy.py +259 -0
- stacktrace_cli-0.11.0/tests/remote/test_policy_service.py +2432 -0
- stacktrace_cli-0.11.0/tests/remote/test_policy_service_cli.py +334 -0
- stacktrace_cli-0.11.0/tests/remote/test_redact_payload.py +1022 -0
- stacktrace_cli-0.11.0/tests/remote/test_seam.py +286 -0
- stacktrace_cli-0.11.0/tests/remote/test_spool.py +706 -0
- stacktrace_cli-0.11.0/tests/remote/test_sync.py +2215 -0
- stacktrace_cli-0.11.0/tests/remote/test_sync_detect.py +886 -0
- stacktrace_cli-0.11.0/tests/remote/test_upload_contract.py +853 -0
- stacktrace_cli-0.11.0/tests/remote/test_usage_client.py +111 -0
- stacktrace_cli-0.11.0/tests/remote/test_usage_contract.py +284 -0
- stacktrace_cli-0.11.0/tests/sdk/test_observation_client.py +278 -0
- stacktrace_cli-0.11.0/tests/telemetry/__init__.py +0 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_activity_log.py +135 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_cli.py +260 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_events.py +655 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_every_derived_site.py +222 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_every_internal_save_is_reported.py +55 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_hooks.py +591 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_release_gate.py +14 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_state.py +150 -0
- stacktrace_cli-0.11.0/tests/telemetry/test_uploader.py +190 -0
- stacktrace_cli-0.11.0/tests/test_acquire.py +818 -0
- stacktrace_cli-0.11.0/tests/test_agent_instance_id.py +207 -0
- stacktrace_cli-0.11.0/tests/test_analysis.py +636 -0
- stacktrace_cli-0.11.0/tests/test_bom_shape.py +196 -0
- stacktrace_cli-0.11.0/tests/test_build_commit.py +244 -0
- stacktrace_cli-0.11.0/tests/test_call_status_conventions.py +363 -0
- stacktrace_cli-0.11.0/tests/test_cli.py +717 -0
- stacktrace_cli-0.11.0/tests/test_composition.py +520 -0
- stacktrace_cli-0.11.0/tests/test_correlate_orchestrate.py +576 -0
- stacktrace_cli-0.11.0/tests/test_correlate_render.py +766 -0
- stacktrace_cli-0.11.0/tests/test_correlated_session.py +283 -0
- stacktrace_cli-0.11.0/tests/test_detection_components.py +194 -0
- stacktrace_cli-0.11.0/tests/test_detection_event_time.py +245 -0
- stacktrace_cli-0.11.0/tests/test_detection_subject.py +585 -0
- stacktrace_cli-0.11.0/tests/test_detector_analyzer_contract.py +243 -0
- stacktrace_cli-0.11.0/tests/test_detector_analyzer_live.py +178 -0
- stacktrace_cli-0.11.0/tests/test_detector_blocked.py +744 -0
- stacktrace_cli-0.11.0/tests/test_detector_cache.py +1109 -0
- stacktrace_cli-0.11.0/tests/test_detector_deterministic.py +315 -0
- stacktrace_cli-0.11.0/tests/test_detector_end_to_end.py +290 -0
- stacktrace_cli-0.11.0/tests/test_detector_finding.py +321 -0
- stacktrace_cli-0.11.0/tests/test_detector_history.py +291 -0
- stacktrace_cli-0.11.0/tests/test_detector_infra_reasoning.py +564 -0
- stacktrace_cli-0.11.0/tests/test_detector_jev.py +306 -0
- stacktrace_cli-0.11.0/tests/test_detector_names_the_service.py +252 -0
- stacktrace_cli-0.11.0/tests/test_detector_new_deterministic.py +4624 -0
- stacktrace_cli-0.11.0/tests/test_detector_priors.py +466 -0
- stacktrace_cli-0.11.0/tests/test_detector_prompts.py +42 -0
- stacktrace_cli-0.11.0/tests/test_detector_reasoning.py +1793 -0
- stacktrace_cli-0.11.0/tests/test_detector_render.py +560 -0
- stacktrace_cli-0.11.0/tests/test_detector_run.py +1395 -0
- stacktrace_cli-0.11.0/tests/test_detector_secrets.py +668 -0
- stacktrace_cli-0.11.0/tests/test_detector_verdict.py +465 -0
- stacktrace_cli-0.11.0/tests/test_detector_vulnerable_dep_invoked.py +478 -0
- stacktrace_cli-0.11.0/tests/test_detector_why_it_stopped.py +383 -0
- stacktrace_cli-0.11.0/tests/test_detector_windows.py +547 -0
- stacktrace_cli-0.11.0/tests/test_evidence_is_dated_not_numbered.py +266 -0
- stacktrace_cli-0.11.0/tests/test_fingerprint_covers_what_the_analyzer_reads.py +407 -0
- stacktrace_cli-0.11.0/tests/test_help_sections.py +147 -0
- stacktrace_cli-0.11.0/tests/test_join.py +333 -0
- stacktrace_cli-0.11.0/tests/test_kind_conformance.py +163 -0
- stacktrace_cli-0.11.0/tests/test_monitor_cli.py +149 -0
- stacktrace_cli-0.11.0/tests/test_no_agent_kind_is_named.py +88 -0
- stacktrace_cli-0.11.0/tests/test_no_live_document_states_the_old_stage_three_default.py +171 -0
- stacktrace_cli-0.11.0/tests/test_observed.py +752 -0
- stacktrace_cli-0.11.0/tests/test_openaca_contract.py +79 -0
- stacktrace_cli-0.11.0/tests/test_openaidr_contract.py +254 -0
- stacktrace_cli-0.11.0/tests/test_option_arity_matches_the_binary.py +516 -0
- stacktrace_cli-0.11.0/tests/test_project_map.py +275 -0
- stacktrace_cli-0.11.0/tests/test_python_namespace.py +28 -0
- stacktrace_cli-0.11.0/tests/test_readme_examples_are_real_output.py +106 -0
- stacktrace_cli-0.11.0/tests/test_seam_boundary.py +110 -0
- stacktrace_cli-0.11.0/tests/test_session_identity_is_the_pair.py +390 -0
- stacktrace_cli-0.11.0/tests/test_sessions_access.py +268 -0
- stacktrace_cli-0.11.0/tests/test_sessions_protocol_typing.py +44 -0
- stacktrace_cli-0.11.0/tests/test_sessions_protocols.py +92 -0
- stacktrace_cli-0.11.0/tests/test_sessions_render.py +567 -0
- stacktrace_cli-0.11.0/tests/test_shell_separators_match_the_shell.py +1339 -0
- stacktrace_cli-0.11.0/tests/test_signed_in_asks_the_agent.py +93 -0
- stacktrace_cli-0.11.0/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +74 -0
- stacktrace_cli-0.11.0/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +144 -0
- stacktrace_cli-0.11.0/tests/test_the_jev_spec_states_the_shipped_thresholds.py +108 -0
- stacktrace_cli-0.11.0/tests/test_the_locality_claim_is_qualified_everywhere.py +76 -0
- stacktrace_cli-0.11.0/tests/test_title_disclosure_invariant.py +166 -0
- stacktrace_cli-0.11.0/tests/test_untrusted_content_never_travels.py +813 -0
- stacktrace_cli-0.11.0/tests/test_verification_subcommands_match_the_binary.py +185 -0
- stacktrace_cli-0.11.0/tests/test_what_jev_is_told_is_what_was_disclosed.py +318 -0
- stacktrace_cli-0.11.0/tests/tool_fields.py +25 -0
- stacktrace_cli-0.11.0/tests/webhook/test_cli.py +744 -0
- stacktrace_cli-0.11.0/uv.lock +960 -0
- stacktrace_cli-0.9.0/.agents/skills/release-stacktrace/SKILL.md +0 -249
- stacktrace_cli-0.9.0/.claude/skills/pr-review-loop/SKILL.md +0 -120
- stacktrace_cli-0.9.0/.github/workflows/publish-pypi.yml +0 -178
- stacktrace_cli-0.9.0/.gitignore +0 -11
- stacktrace_cli-0.9.0/CLAUDE.md +0 -401
- stacktrace_cli-0.9.0/PKG-INFO +0 -230
- stacktrace_cli-0.9.0/README.md +0 -203
- stacktrace_cli-0.9.0/docs/adrs/0001-session-telemetry-as-input.md +0 -116
- stacktrace_cli-0.9.0/docs/adrs/0004-three-stage-detector.md +0 -159
- stacktrace_cli-0.9.0/docs/adrs/0006-trust-boundary-and-detection-upload.md +0 -179
- stacktrace_cli-0.9.0/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +0 -115
- stacktrace_cli-0.9.0/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +0 -94
- stacktrace_cli-0.9.0/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +0 -82
- stacktrace_cli-0.9.0/docs/adrs/0045-scan-every-session-and-outlive-them.md +0 -137
- stacktrace_cli-0.9.0/docs/adrs/0061-the-drain-sends-findings-only.md +0 -118
- stacktrace_cli-0.9.0/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +0 -119
- stacktrace_cli-0.9.0/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -162
- stacktrace_cli-0.9.0/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +0 -74
- stacktrace_cli-0.9.0/docs/adrs/0092-cost-is-its-own-rule-family.md +0 -49
- stacktrace_cli-0.9.0/docs/adrs/0093-environment-cost-baselines-count-tokens-keyed-by-model.md +0 -78
- stacktrace_cli-0.9.0/docs/adrs/0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md +0 -86
- stacktrace_cli-0.9.0/docs/adrs/INDEX.md +0 -132
- stacktrace_cli-0.9.0/docs/plans/017-cost-phase-2.md +0 -89
- stacktrace_cli-0.9.0/docs/specs/aidr.md +0 -505
- stacktrace_cli-0.9.0/docs/specs/correlation.md +0 -585
- stacktrace_cli-0.9.0/docs/specs/cost-phase-1.md +0 -477
- stacktrace_cli-0.9.0/docs/specs/cost-phase-2.md +0 -159
- stacktrace_cli-0.9.0/docs/specs/cost.md +0 -248
- stacktrace_cli-0.9.0/docs/specs/daemon-store.md +0 -246
- stacktrace_cli-0.9.0/docs/specs/daemon-uploads.md +0 -377
- stacktrace_cli-0.9.0/docs/specs/detection-policies.md +0 -524
- stacktrace_cli-0.9.0/docs/specs/detection-upload.md +0 -467
- stacktrace_cli-0.9.0/docs/specs/detector.md +0 -1114
- stacktrace_cli-0.9.0/docs/specs/monitor.md +0 -713
- stacktrace_cli-0.9.0/docs/specs/notification-delivery.md +0 -304
- stacktrace_cli-0.9.0/docs/specs/reasoning-jev.md +0 -463
- stacktrace_cli-0.9.0/pyproject.toml +0 -107
- stacktrace_cli-0.9.0/scripts/cost_latency.py +0 -85
- stacktrace_cli-0.9.0/src/stacktrace_cli/__init__.py +0 -10
- stacktrace_cli-0.9.0/src/stacktrace_cli/__main__.py +0 -16
- stacktrace_cli-0.9.0/src/stacktrace_cli/analysis.py +0 -664
- stacktrace_cli-0.9.0/src/stacktrace_cli/cli.py +0 -641
- stacktrace_cli-0.9.0/src/stacktrace_cli/cloud/__init__.py +0 -49
- stacktrace_cli-0.9.0/src/stacktrace_cli/cloud/setup.sh +0 -287
- stacktrace_cli-0.9.0/src/stacktrace_cli/correlate/acquire.py +0 -535
- stacktrace_cli-0.9.0/src/stacktrace_cli/correlate/composition.py +0 -434
- stacktrace_cli-0.9.0/src/stacktrace_cli/correlate/join.py +0 -426
- stacktrace_cli-0.9.0/src/stacktrace_cli/correlate/observed.py +0 -1918
- stacktrace_cli-0.9.0/src/stacktrace_cli/correlate/orchestrate.py +0 -507
- stacktrace_cli-0.9.0/src/stacktrace_cli/correlate/record.py +0 -287
- stacktrace_cli-0.9.0/src/stacktrace_cli/correlate/render.py +0 -768
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/baseline.py +0 -493
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/components.py +0 -143
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/ledger.py +0 -58
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/measures.py +0 -351
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/rules.py +0 -1138
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/runs.py +0 -126
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/tokens.py +0 -69
- stacktrace_cli-0.9.0/src/stacktrace_cli/cost/totals.py +0 -62
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/activity_log.py +0 -94
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/bom.py +0 -56
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/cli.py +0 -709
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/client.py +0 -355
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/composition.py +0 -242
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/config.py +0 -313
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/costs.py +0 -882
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/db.py +0 -690
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/fleet.py +0 -665
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/identity.py +0 -99
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/lifecycle.py +0 -172
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/observer.py +0 -670
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/paths.py +0 -40
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/presentation.py +0 -134
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/runtime.py +0 -833
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/scan.py +0 -287
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/server.py +0 -303
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/store.py +0 -1209
- stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/webhook.py +0 -529
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/analyzer.py +0 -205
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/blocked.py +0 -462
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/cache.py +0 -719
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/deterministic.py +0 -2909
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/finding.py +0 -507
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/history.py +0 -210
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/jev.py +0 -213
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/priors.py +0 -270
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/prompts/__init__.py +0 -56
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/reasoning.py +0 -1861
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/render.py +0 -478
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/rules.py +0 -265
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/run.py +0 -1185
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/secrets.py +0 -205
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/verdict.py +0 -266
- stacktrace_cli-0.9.0/src/stacktrace_cli/detector/windows.py +0 -443
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/__init__.py +0 -12
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/costs.py +0 -375
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/inventory.py +0 -495
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/offline.py +0 -266
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/reasoning.py +0 -306
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/render.py +0 -791
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/server.py +0 -736
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/app.js +0 -2888
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/cost.js +0 -436
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/fonts/OFL.txt +0 -210
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/index.html +0 -155
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/inventory.js +0 -558
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/styles.css +0 -586
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/verdicts.py +0 -52
- stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/watch.py +0 -778
- stacktrace_cli-0.9.0/src/stacktrace_cli/options.py +0 -107
- stacktrace_cli-0.9.0/src/stacktrace_cli/private_state.py +0 -38
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/cli.py +0 -655
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/client.py +0 -356
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/detect_payload.py +0 -488
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/identity.py +0 -334
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/payload.py +0 -443
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/policy.py +0 -88
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/policy_service.py +0 -1637
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/redact.py +0 -1313
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/spool.py +0 -447
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/sync.py +0 -807
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/sync_detect.py +0 -536
- stacktrace_cli-0.9.0/src/stacktrace_cli/remote/upload_contract.py +0 -1010
- stacktrace_cli-0.9.0/src/stacktrace_cli/sessions/access.py +0 -103
- stacktrace_cli-0.9.0/src/stacktrace_cli/sessions/outcome.py +0 -65
- stacktrace_cli-0.9.0/src/stacktrace_cli/sessions/protocols.py +0 -298
- stacktrace_cli-0.9.0/src/stacktrace_cli/sessions/render.py +0 -301
- stacktrace_cli-0.9.0/src/stacktrace_cli/telemetry/events.py +0 -494
- stacktrace_cli-0.9.0/src/stacktrace_cli/telemetry/state.py +0 -219
- stacktrace_cli-0.9.0/src/stacktrace_cli/webhook/cli.py +0 -200
- stacktrace_cli-0.9.0/src/stacktrace_cli/webhook/config.py +0 -193
- stacktrace_cli-0.9.0/tests/agent_bom_fixture.py +0 -252
- stacktrace_cli-0.9.0/tests/conftest.py +0 -157
- stacktrace_cli-0.9.0/tests/cost/scenarios.py +0 -169
- stacktrace_cli-0.9.0/tests/cost/test_baseline.py +0 -223
- stacktrace_cli-0.9.0/tests/cost/test_clock.py +0 -61
- stacktrace_cli-0.9.0/tests/cost/test_components.py +0 -129
- stacktrace_cli-0.9.0/tests/cost/test_cost_evidence_travels.py +0 -135
- stacktrace_cli-0.9.0/tests/cost/test_cost_findings_are_dated_by_their_citations.py +0 -557
- stacktrace_cli-0.9.0/tests/cost/test_cost_findings_carry_no_session_text.py +0 -120
- stacktrace_cli-0.9.0/tests/cost/test_cost_is_tokens.py +0 -72
- stacktrace_cli-0.9.0/tests/cost/test_cost_latency.py +0 -82
- stacktrace_cli-0.9.0/tests/cost/test_evidence.py +0 -40
- stacktrace_cli-0.9.0/tests/cost/test_ledger.py +0 -44
- stacktrace_cli-0.9.0/tests/cost/test_measures.py +0 -251
- stacktrace_cli-0.9.0/tests/cost/test_models.py +0 -15
- stacktrace_cli-0.9.0/tests/cost/test_rules_baseline.py +0 -535
- stacktrace_cli-0.9.0/tests/cost/test_rules_budget.py +0 -189
- stacktrace_cli-0.9.0/tests/cost/test_runs.py +0 -43
- stacktrace_cli-0.9.0/tests/cost/test_totals.py +0 -55
- stacktrace_cli-0.9.0/tests/daemon/test_activity_log.py +0 -351
- stacktrace_cli-0.9.0/tests/daemon/test_cli.py +0 -1373
- stacktrace_cli-0.9.0/tests/daemon/test_client.py +0 -338
- stacktrace_cli-0.9.0/tests/daemon/test_composition.py +0 -245
- stacktrace_cli-0.9.0/tests/daemon/test_config.py +0 -195
- stacktrace_cli-0.9.0/tests/daemon/test_cost_guidance.py +0 -23
- stacktrace_cli-0.9.0/tests/daemon/test_costs.py +0 -1510
- stacktrace_cli-0.9.0/tests/daemon/test_db.py +0 -829
- stacktrace_cli-0.9.0/tests/daemon/test_detection_needs_no_subscriber.py +0 -115
- stacktrace_cli-0.9.0/tests/daemon/test_fleet.py +0 -737
- stacktrace_cli-0.9.0/tests/daemon/test_identity.py +0 -91
- stacktrace_cli-0.9.0/tests/daemon/test_job_thread.py +0 -63
- stacktrace_cli-0.9.0/tests/daemon/test_jobs.py +0 -465
- stacktrace_cli-0.9.0/tests/daemon/test_lifecycle.py +0 -115
- stacktrace_cli-0.9.0/tests/daemon/test_observer.py +0 -1055
- stacktrace_cli-0.9.0/tests/daemon/test_queue_reader.py +0 -200
- stacktrace_cli-0.9.0/tests/daemon/test_runtime.py +0 -1636
- stacktrace_cli-0.9.0/tests/daemon/test_scan.py +0 -517
- stacktrace_cli-0.9.0/tests/daemon/test_service.py +0 -198
- stacktrace_cli-0.9.0/tests/daemon/test_socket.py +0 -547
- stacktrace_cli-0.9.0/tests/daemon/test_stage_times.py +0 -80
- stacktrace_cli-0.9.0/tests/daemon/test_store.py +0 -800
- stacktrace_cli-0.9.0/tests/daemon/test_the_drained_payload_is_the_cold_one.py +0 -287
- stacktrace_cli-0.9.0/tests/daemon/test_the_stored_row_is_sufficient.py +0 -247
- stacktrace_cli-0.9.0/tests/daemon/test_webhook.py +0 -1164
- stacktrace_cli-0.9.0/tests/daemon/test_wire_frames_are_bounded.py +0 -156
- stacktrace_cli-0.9.0/tests/detector_session_fixture.py +0 -162
- stacktrace_cli-0.9.0/tests/monitor/cost_harness.mjs +0 -133
- stacktrace_cli-0.9.0/tests/monitor/feed_harness.mjs +0 -3719
- stacktrace_cli-0.9.0/tests/monitor/inventory_harness.mjs +0 -481
- stacktrace_cli-0.9.0/tests/monitor/test_cost_page.py +0 -232
- stacktrace_cli-0.9.0/tests/monitor/test_cost_range_switch.py +0 -133
- stacktrace_cli-0.9.0/tests/monitor/test_feed_model.py +0 -1954
- stacktrace_cli-0.9.0/tests/monitor/test_inventory.py +0 -866
- stacktrace_cli-0.9.0/tests/monitor/test_offline.py +0 -242
- stacktrace_cli-0.9.0/tests/monitor/test_reasoning_gates.py +0 -688
- stacktrace_cli-0.9.0/tests/monitor/test_render.py +0 -1149
- stacktrace_cli-0.9.0/tests/monitor/test_render_cost.py +0 -641
- stacktrace_cli-0.9.0/tests/monitor/test_server.py +0 -830
- stacktrace_cli-0.9.0/tests/monitor/test_site_assets.py +0 -438
- stacktrace_cli-0.9.0/tests/monitor/test_state.py +0 -148
- stacktrace_cli-0.9.0/tests/monitor/test_verdicts.py +0 -136
- stacktrace_cli-0.9.0/tests/monitor/test_watch.py +0 -2024
- stacktrace_cli-0.9.0/tests/remote/helpers.py +0 -127
- stacktrace_cli-0.9.0/tests/remote/test_cli.py +0 -1028
- stacktrace_cli-0.9.0/tests/remote/test_client.py +0 -524
- stacktrace_cli-0.9.0/tests/remote/test_config.py +0 -129
- stacktrace_cli-0.9.0/tests/remote/test_detect_activity.py +0 -220
- stacktrace_cli-0.9.0/tests/remote/test_detect_cli.py +0 -72
- stacktrace_cli-0.9.0/tests/remote/test_detect_client.py +0 -82
- stacktrace_cli-0.9.0/tests/remote/test_detect_contract_is_exhaustive.py +0 -912
- stacktrace_cli-0.9.0/tests/remote/test_detect_gate_matches_the_cloud.py +0 -351
- stacktrace_cli-0.9.0/tests/remote/test_detect_layers_compose.py +0 -162
- stacktrace_cli-0.9.0/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -286
- stacktrace_cli-0.9.0/tests/remote/test_detect_redaction.py +0 -823
- stacktrace_cli-0.9.0/tests/remote/test_detect_spool.py +0 -329
- stacktrace_cli-0.9.0/tests/remote/test_detect_upload_contract.py +0 -180
- stacktrace_cli-0.9.0/tests/remote/test_detect_wire_payload.py +0 -185
- stacktrace_cli-0.9.0/tests/remote/test_facade_contract.py +0 -403
- stacktrace_cli-0.9.0/tests/remote/test_identity.py +0 -409
- stacktrace_cli-0.9.0/tests/remote/test_no_local_path_survives_redaction.py +0 -376
- stacktrace_cli-0.9.0/tests/remote/test_payload.py +0 -940
- stacktrace_cli-0.9.0/tests/remote/test_policy.py +0 -259
- stacktrace_cli-0.9.0/tests/remote/test_policy_service.py +0 -2432
- stacktrace_cli-0.9.0/tests/remote/test_policy_service_cli.py +0 -334
- stacktrace_cli-0.9.0/tests/remote/test_redact_payload.py +0 -1022
- stacktrace_cli-0.9.0/tests/remote/test_seam.py +0 -280
- stacktrace_cli-0.9.0/tests/remote/test_spool.py +0 -694
- stacktrace_cli-0.9.0/tests/remote/test_sync.py +0 -2217
- stacktrace_cli-0.9.0/tests/remote/test_sync_detect.py +0 -888
- stacktrace_cli-0.9.0/tests/remote/test_upload_contract.py +0 -853
- stacktrace_cli-0.9.0/tests/telemetry/test_activity_log.py +0 -135
- stacktrace_cli-0.9.0/tests/telemetry/test_cli.py +0 -260
- stacktrace_cli-0.9.0/tests/telemetry/test_events.py +0 -673
- stacktrace_cli-0.9.0/tests/telemetry/test_every_derived_site.py +0 -202
- stacktrace_cli-0.9.0/tests/telemetry/test_every_internal_save_is_reported.py +0 -55
- stacktrace_cli-0.9.0/tests/telemetry/test_hooks.py +0 -588
- stacktrace_cli-0.9.0/tests/telemetry/test_release_gate.py +0 -14
- stacktrace_cli-0.9.0/tests/telemetry/test_state.py +0 -150
- stacktrace_cli-0.9.0/tests/telemetry/test_uploader.py +0 -190
- stacktrace_cli-0.9.0/tests/test_acquire.py +0 -807
- stacktrace_cli-0.9.0/tests/test_agent_instance_id.py +0 -207
- stacktrace_cli-0.9.0/tests/test_analysis.py +0 -646
- stacktrace_cli-0.9.0/tests/test_bom_shape.py +0 -196
- stacktrace_cli-0.9.0/tests/test_build_commit.py +0 -244
- stacktrace_cli-0.9.0/tests/test_call_status_conventions.py +0 -362
- stacktrace_cli-0.9.0/tests/test_cli.py +0 -717
- stacktrace_cli-0.9.0/tests/test_composition.py +0 -520
- stacktrace_cli-0.9.0/tests/test_correlate_orchestrate.py +0 -523
- stacktrace_cli-0.9.0/tests/test_correlate_render.py +0 -761
- stacktrace_cli-0.9.0/tests/test_correlated_session.py +0 -278
- stacktrace_cli-0.9.0/tests/test_detection_components.py +0 -194
- stacktrace_cli-0.9.0/tests/test_detection_event_time.py +0 -245
- stacktrace_cli-0.9.0/tests/test_detection_subject.py +0 -581
- stacktrace_cli-0.9.0/tests/test_detector_analyzer_contract.py +0 -243
- stacktrace_cli-0.9.0/tests/test_detector_analyzer_live.py +0 -178
- stacktrace_cli-0.9.0/tests/test_detector_blocked.py +0 -744
- stacktrace_cli-0.9.0/tests/test_detector_cache.py +0 -1109
- stacktrace_cli-0.9.0/tests/test_detector_deterministic.py +0 -315
- stacktrace_cli-0.9.0/tests/test_detector_end_to_end.py +0 -290
- stacktrace_cli-0.9.0/tests/test_detector_finding.py +0 -321
- stacktrace_cli-0.9.0/tests/test_detector_history.py +0 -291
- stacktrace_cli-0.9.0/tests/test_detector_infra_reasoning.py +0 -564
- stacktrace_cli-0.9.0/tests/test_detector_jev.py +0 -306
- stacktrace_cli-0.9.0/tests/test_detector_names_the_service.py +0 -252
- stacktrace_cli-0.9.0/tests/test_detector_new_deterministic.py +0 -4624
- stacktrace_cli-0.9.0/tests/test_detector_priors.py +0 -501
- stacktrace_cli-0.9.0/tests/test_detector_prompts.py +0 -42
- stacktrace_cli-0.9.0/tests/test_detector_reasoning.py +0 -1793
- stacktrace_cli-0.9.0/tests/test_detector_render.py +0 -560
- stacktrace_cli-0.9.0/tests/test_detector_run.py +0 -1395
- stacktrace_cli-0.9.0/tests/test_detector_secrets.py +0 -292
- stacktrace_cli-0.9.0/tests/test_detector_verdict.py +0 -465
- stacktrace_cli-0.9.0/tests/test_detector_vulnerable_dep_invoked.py +0 -478
- stacktrace_cli-0.9.0/tests/test_detector_why_it_stopped.py +0 -383
- stacktrace_cli-0.9.0/tests/test_detector_windows.py +0 -547
- stacktrace_cli-0.9.0/tests/test_evidence_is_dated_not_numbered.py +0 -266
- stacktrace_cli-0.9.0/tests/test_fingerprint_covers_what_the_analyzer_reads.py +0 -404
- stacktrace_cli-0.9.0/tests/test_help_sections.py +0 -147
- stacktrace_cli-0.9.0/tests/test_join.py +0 -255
- stacktrace_cli-0.9.0/tests/test_monitor_cli.py +0 -149
- stacktrace_cli-0.9.0/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -171
- stacktrace_cli-0.9.0/tests/test_observed.py +0 -747
- stacktrace_cli-0.9.0/tests/test_openaca_contract.py +0 -72
- stacktrace_cli-0.9.0/tests/test_openaidr_contract.py +0 -240
- stacktrace_cli-0.9.0/tests/test_option_arity_matches_the_binary.py +0 -519
- stacktrace_cli-0.9.0/tests/test_project_map.py +0 -270
- stacktrace_cli-0.9.0/tests/test_readme_examples_are_real_output.py +0 -106
- stacktrace_cli-0.9.0/tests/test_seam_boundary.py +0 -110
- stacktrace_cli-0.9.0/tests/test_session_identity_is_the_pair.py +0 -365
- stacktrace_cli-0.9.0/tests/test_sessions_access.py +0 -268
- stacktrace_cli-0.9.0/tests/test_sessions_protocol_typing.py +0 -44
- stacktrace_cli-0.9.0/tests/test_sessions_protocols.py +0 -92
- stacktrace_cli-0.9.0/tests/test_sessions_render.py +0 -567
- stacktrace_cli-0.9.0/tests/test_shell_separators_match_the_shell.py +0 -1339
- stacktrace_cli-0.9.0/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -74
- stacktrace_cli-0.9.0/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +0 -144
- stacktrace_cli-0.9.0/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -108
- stacktrace_cli-0.9.0/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -76
- stacktrace_cli-0.9.0/tests/test_title_disclosure_invariant.py +0 -166
- stacktrace_cli-0.9.0/tests/test_untrusted_content_never_travels.py +0 -813
- stacktrace_cli-0.9.0/tests/test_verification_subcommands_match_the_binary.py +0 -185
- stacktrace_cli-0.9.0/tests/test_what_jev_is_told_is_what_was_disclosed.py +0 -318
- stacktrace_cli-0.9.0/tests/webhook/test_cli.py +0 -744
- stacktrace_cli-0.9.0/uv.lock +0 -958
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/.claude/settings.json +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/.claude/skills/release-stacktrace/SKILL.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/.codex/hooks.json +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/.github/managed-autofix.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/.github/pull_request_template.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/.github/workflows/ci.yml +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/AGENTS.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0003-runtime-edges.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0011-verdict-cache.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0014-declared-project-mapping.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0021-two-command-kinds.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.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.11.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.11.0}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0041-defer-native-windows-support.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.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.11.0}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.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.11.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.11.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.11.0}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0083-each-block-reason-is-its-own-rule.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0086-a-refusal-names-who-answered-the-call.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0087-deploy-compiled-policy-with-a-privileged-scheduled-job.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0088-slack-alerts-leave-out-confidence.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0089-infra-gate-reads-commands-not-shell-semantics.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.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.11.0}/docs/adrs/0091-mark-our-own-machines-and-name-what-failed.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.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.11.0}/docs/adrs/0095-cost-findings-reach-fleet-each-rule-can-be-muted.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.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.11.0}/docs/adrs/0098-a-run-is-its-main-session.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0099-cost-is-measured-in-tokens-and-relative-increases.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/0100-the-monitor-runs-offline-for-the-website.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/HOOK-PROMPT.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/adrs/TEMPLATE.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/cutover-openaca-remote.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/002-session-input.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/003-correlation.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/004-detector.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/005-remote-sync.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/006-cli-composition.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/007-detection-upload.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/008-monitor.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/009-reasoning-jev.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/010-session-daemon.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/011-daemon-store.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/012-daemon-scanning.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/013-daemon-uploads.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/014-asset-identity.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/015-managed-policy-deployment.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/plans/016-cost-phase-1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.0.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.1.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.2.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.2.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.2.2.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.2.3.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.3.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.3.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.4.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.4.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.5.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.5.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.5.2.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.5.3.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.6.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.6.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.7.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.7.1.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.8.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/releases/v0.9.0.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/research/001-intent-drift-metric.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/specs/cli-composition.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/specs/daemon-scanning.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/specs/event-time.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/specs/managed-policy-deployment.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/specs/monitor-inventory.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/specs/remote-sync.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/docs/specs/session-input.md +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/scripts/git-hooks/pre-push +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/scripts/install-hooks.sh +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/build.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/correlate/__init__.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/correlate/project_map.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/cost/__init__.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/cost/clock.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/cost/evidence.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/cost/models.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/daemon/__init__.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/daemon/jobs.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/daemon/protocol.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/daemon/service.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/detector/__init__.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/detector/prompts/jev-v2/stacktrace-infra-unsafe-action.json +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/detector/prompts/v1/exclusions.md +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/detector/prompts/v1/framing.md +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/monitor/site/apple-icon.png +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/monitor/site/favicon.ico +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/monitor/site/icon.svg +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/monitor/state.py +0 -0
- /stacktrace_cli-0.9.0/tests/__init__.py → /stacktrace_cli-0.11.0/src/stacktrace/py.typed +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/remote/__init__.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/remote/config.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/remote/policy_worker.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/sessions/__init__.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/sessions/index.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/sessions/lineage.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/telemetry/__init__.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/telemetry/cli.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/telemetry/posthog.py +0 -0
- {stacktrace_cli-0.9.0/src/stacktrace_cli → stacktrace_cli-0.11.0/src/stacktrace}/webhook/__init__.py +0 -0
- {stacktrace_cli-0.9.0/tests/cost → stacktrace_cli-0.11.0/tests}/__init__.py +0 -0
- {stacktrace_cli-0.9.0/tests/monitor → stacktrace_cli-0.11.0/tests/cost}/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/tests/cost/fakes.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/tests/daemon/__init__.py +0 -0
- {stacktrace_cli-0.9.0/tests/remote → stacktrace_cli-0.11.0/tests/gateway}/__init__.py +0 -0
- {stacktrace_cli-0.9.0/tests/telemetry → stacktrace_cli-0.11.0/tests/monitor}/__init__.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/tests/monitor/test_inventory_page.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/tests/test_release_gate_coverage.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/tests/test_release_readiness.py +0 -0
- {stacktrace_cli-0.9.0 → stacktrace_cli-0.11.0}/tests/test_sessions_end_to_end.py +0 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-stacktrace
|
|
3
|
+
description: Use when cutting a new stacktrace-cli PyPI release. Walks through version bump, release-notes drafting, pre-flight checks, tag, and push — enforces the publish-pypi.yml notes-file gate so the GitHub Releases page can't silently drift from PyPI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# release-stacktrace
|
|
7
|
+
|
|
8
|
+
End-to-end release procedure for the `stacktrace-cli` distribution.
|
|
9
|
+
`.github/workflows/publish-pypi.yml` enforces the machine-checkable gates
|
|
10
|
+
(tag on main, tag matches both version strings, notes file present, four
|
|
11
|
+
CI gates green). This skill is the human-side counterpart: it drafts the
|
|
12
|
+
notes with judgment, runs the pre-flight checks, and pushes the tag.
|
|
13
|
+
|
|
14
|
+
**Announce at start:** "I'm using the release-stacktrace skill to cut a new
|
|
15
|
+
stacktrace-cli release."
|
|
16
|
+
|
|
17
|
+
## When to invoke
|
|
18
|
+
|
|
19
|
+
User says any of: "cut a release", "ship 0.0.N", "release stacktrace",
|
|
20
|
+
"tag a new version", or starts editing `pyproject.toml`'s version field
|
|
21
|
+
in this repo.
|
|
22
|
+
|
|
23
|
+
## Inputs
|
|
24
|
+
|
|
25
|
+
1. **Target version** (e.g. `0.1.0`). Inferred from `pyproject.toml` if
|
|
26
|
+
the user already bumped it; otherwise ask.
|
|
27
|
+
2. **Theme** — the H1 line of the notes file. Ask the user; a commit log
|
|
28
|
+
can't infer it.
|
|
29
|
+
|
|
30
|
+
## Procedure
|
|
31
|
+
|
|
32
|
+
### Step 1. Pre-flight checks
|
|
33
|
+
|
|
34
|
+
Run from the repo root. Stop and ask if any fails — do not "fix" a dirty
|
|
35
|
+
tree or out-of-sync main automatically, those signal in-flight work.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git rev-parse --abbrev-ref HEAD # must be main
|
|
39
|
+
git status --porcelain # must be empty
|
|
40
|
+
git fetch --tags origin
|
|
41
|
+
git rev-parse --verify "v<version>" 2>/dev/null # MUST FAIL — tag must not exist
|
|
42
|
+
test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The `release_gate` marker is **not** run here: `test_release_readiness.py`'s
|
|
46
|
+
share of it requires `openaca`/`openaidr` pinned exactly, which is not true of
|
|
47
|
+
a normal checkout (both float on `>=` between releases) and is only made true
|
|
48
|
+
by Step 4. Running it against an unpinned tree would fail on every release,
|
|
49
|
+
not just a broken one. It runs at the end of Step 4, once its precondition
|
|
50
|
+
holds.
|
|
51
|
+
|
|
52
|
+
PyPI versions are immutable, including yanked ones. If `<version>` is
|
|
53
|
+
already on PyPI, the only path forward is a new version number:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
curl -s https://pypi.org/pypi/stacktrace-cli/json | python3 -c 'import json,sys; print(sorted(json.load(sys.stdin)["releases"]))'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Step 2. Gather the commit log
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
prev_tag=$(git describe --tags --abbrev=0) # empty on the first release
|
|
63
|
+
git log --oneline "${prev_tag}..HEAD"
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Raw material only — do not dump it into the notes file verbatim.
|
|
67
|
+
|
|
68
|
+
### Step 3. Draft `docs/releases/v<version>.md`
|
|
69
|
+
|
|
70
|
+
Follow the shape of the existing files in `docs/releases/`:
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+
# <version> — <theme>
|
|
74
|
+
|
|
75
|
+
## Highlights
|
|
76
|
+
|
|
77
|
+
- **<Theme A>.** 1-3 sentences pitched at someone who installs the CLI.
|
|
78
|
+
Reference ADRs by number when a design doc backs the change.
|
|
79
|
+
- **Bug fixes.** Combine small fixes into one bullet, comma-separated.
|
|
80
|
+
|
|
81
|
+
## Install
|
|
82
|
+
|
|
83
|
+
`uv tool install stacktrace-cli==<version>` or `pip install stacktrace-cli==<version>`.
|
|
84
|
+
|
|
85
|
+
## Compatibility
|
|
86
|
+
|
|
87
|
+
<Behavior changes existing users will notice. Say "pre-alpha, no
|
|
88
|
+
back-compat hedging" while that's still true.>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Judgment guidelines (apply ruthlessly):**
|
|
92
|
+
|
|
93
|
+
- **Group by theme, not by commit.** Five commits adding one capability
|
|
94
|
+
are one bullet.
|
|
95
|
+
- **Lead with user-visible impact**, not implementation.
|
|
96
|
+
- **Cut chore/format/docs-only and release-machinery commits.** They
|
|
97
|
+
aren't release-visible.
|
|
98
|
+
- **Acknowledge breaking changes explicitly** under `## Compatibility` —
|
|
99
|
+
a renamed subcommand or changed output shape goes there.
|
|
100
|
+
|
|
101
|
+
Show the draft to the user and iterate until they agree it captures what
|
|
102
|
+
shipped.
|
|
103
|
+
|
|
104
|
+
### Step 4. Bump the version, pin workspace dependencies, and gate
|
|
105
|
+
|
|
106
|
+
`pyproject.toml`'s `version`, `src/stacktrace/__init__.py`'s
|
|
107
|
+
`__version__` and the `--version` console block in `README.md` are three
|
|
108
|
+
separate copies of the version string. The workflow fails the build if the
|
|
109
|
+
first two disagree with the tag. Move them together:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
sed -i.bak 's/^version = ".*"/version = "<version>"/' pyproject.toml && rm pyproject.toml.bak
|
|
113
|
+
sed -i.bak 's/^__version__ = ".*"/__version__ = "<version>"/' src/stacktrace/__init__.py && rm src/stacktrace/__init__.py.bak
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`openaca` and `openaidr` are developed alongside this package and float on
|
|
117
|
+
`>=` during normal development, but a prior release will have left them
|
|
118
|
+
pinned exactly with `==` (see below), which would stop `uv lock` from ever
|
|
119
|
+
resolving a newer release. Loosen both back to a floor first — the
|
|
120
|
+
replacement matches either operator, so this is safe to run whether the tree
|
|
121
|
+
is currently floating or still pinned from last time:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
sed -i.bak -E 's/^ "openaca(>=|==)[^"]*"/ "openaca>=0"/' pyproject.toml && rm pyproject.toml.bak
|
|
125
|
+
sed -i.bak -E 's/^ "openaidr(>=|==)[^"]*"/ "openaidr>=0"/' pyproject.toml && rm pyproject.toml.bak
|
|
126
|
+
uv lock # refresh uv.lock, now free to pick the newest release
|
|
127
|
+
uv run stacktrace --version # sanity: prints <version>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Paste that exact output over the console block under `## Installation` in
|
|
131
|
+
`README.md`. `readme = "README.md"` makes that file the PyPI long description,
|
|
132
|
+
and a description is baked into the artifact at upload — releases being
|
|
133
|
+
immutable, a stale line there is only ever corrected by burning the next
|
|
134
|
+
version number, which is what 0.3.1 was for. The block sat at `0.2.1` through
|
|
135
|
+
three releases before anything checked it;
|
|
136
|
+
`tests/test_readme_examples_are_real_output.py` now fails the build when it
|
|
137
|
+
drifts, so this is a step you are reminded of rather than one you must
|
|
138
|
+
remember.
|
|
139
|
+
|
|
140
|
+
Now pin both to whatever `uv lock` just resolved — the one point in the
|
|
141
|
+
procedure where the lockfile has just picked the newest available versions
|
|
142
|
+
and a release is actually being cut:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
openaca_version=$(grep -A1 '^name = "openaca"' uv.lock | grep version | cut -d'"' -f2)
|
|
146
|
+
openaidr_version=$(grep -A1 '^name = "openaidr"' uv.lock | grep version | cut -d'"' -f2)
|
|
147
|
+
sed -i.bak -E "s/^ \"openaca(>=|==)[^\"]*\"/ \"openaca==${openaca_version}\"/" pyproject.toml && rm pyproject.toml.bak
|
|
148
|
+
sed -i.bak -E "s/^ \"openaidr(>=|==)[^\"]*\"/ \"openaidr==${openaidr_version}\"/" pyproject.toml && rm pyproject.toml.bak
|
|
149
|
+
uv lock # refresh uv.lock for the exact pin
|
|
150
|
+
uv run pytest -m release_gate
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
By marker, not by file: a second `release_gate` test can be added anywhere
|
|
154
|
+
under `tests/` (as `tests/telemetry/test_release_gate.py` was, checking that
|
|
155
|
+
PostHog's project key is set) and this command picks it up without the skill
|
|
156
|
+
needing to name it. The gate is not covered by `.github/workflows/publish-pypi.yml`,
|
|
157
|
+
which runs the default `uv run pytest -q` — and `pyproject.toml`'s `addopts`
|
|
158
|
+
excludes `release_gate` from that default run on purpose (it fails throughout
|
|
159
|
+
normal development, before this step pins the floors and, for the PostHog key,
|
|
160
|
+
before Micheal fills it in). This skill is the only place any `release_gate`
|
|
161
|
+
test runs before a tag is pushed, so skipping it here, or naming only one file
|
|
162
|
+
here, is the one way an unpinned `openaidr`/`openaca` requirement or an unset
|
|
163
|
+
PostHog key reaches PyPI. Stop and ask if it fails.
|
|
164
|
+
|
|
165
|
+
### Step 5. Release-prep commit + PR
|
|
166
|
+
|
|
167
|
+
If the user's original request did not explicitly ask to cut, ship, or
|
|
168
|
+
publish a release, stop before the push and ask. Editing the version
|
|
169
|
+
field is enough to invoke this skill; it is not permission to publish.
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
git checkout -b release/<version>
|
|
173
|
+
git add pyproject.toml uv.lock src/stacktrace/__init__.py docs/releases/v<version>.md
|
|
174
|
+
git status --porcelain # inspect anything still unstaged; stage intentionally or stop
|
|
175
|
+
git commit -m "release: <version> — <theme>"
|
|
176
|
+
git push -u origin release/<version>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Opening the PR needs its own explicit ask. Then:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
gh pr create --title "release: <version>" --body "Release prep for <version>.
|
|
183
|
+
|
|
184
|
+
- Bumps \`pyproject.toml\` and \`__version__\` to <version>
|
|
185
|
+
- Adds release notes at \`docs/releases/v<version>.md\`
|
|
186
|
+
- After merge: tag \`v<version>\` on main and push to trigger PyPI publish + GitHub Release"
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Surface the PR URL. **Stop here.** The user reviews and merges.
|
|
190
|
+
|
|
191
|
+
### Step 6. After merge: tag + push
|
|
192
|
+
|
|
193
|
+
After the user confirms the PR merged, on a clean main:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
git checkout main
|
|
197
|
+
git pull --ff-only
|
|
198
|
+
git tag v<version>
|
|
199
|
+
git push origin v<version>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The tag-triggered run registers asynchronously, so `--limit 1` can grab a
|
|
203
|
+
stale earlier run. Poll for the run tied to the tagged commit:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
tag_sha=$(git rev-parse "v<version>^{commit}")
|
|
207
|
+
run_id=""
|
|
208
|
+
until [ -n "$run_id" ]; do
|
|
209
|
+
run_id=$(gh run list --repo stacktrace-ai/stacktrace \
|
|
210
|
+
--workflow publish-pypi.yml --commit "$tag_sha" \
|
|
211
|
+
--json databaseId --jq '.[0].databaseId // empty')
|
|
212
|
+
[ -z "$run_id" ] && sleep 5
|
|
213
|
+
done
|
|
214
|
+
gh run watch --repo stacktrace-ai/stacktrace "$run_id"
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Step 7. Verify
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
curl -s https://pypi.org/pypi/stacktrace-cli/json | python3 -c 'import json,sys; print(sorted(json.load(sys.stdin)["releases"]))'
|
|
221
|
+
gh release view v<version> --repo stacktrace-ai/stacktrace --json name,body
|
|
222
|
+
uvx --from stacktrace-cli==<version> stacktrace --version # installs from PyPI, must print <version>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
All three must succeed. If any fails, surface the workflow run URL rather
|
|
226
|
+
than guessing.
|
|
227
|
+
|
|
228
|
+
## Failure modes this prevents
|
|
229
|
+
|
|
230
|
+
1. **On PyPI but not on GitHub Releases.** The workflow's notes-file gate
|
|
231
|
+
runs before publish: no notes file at the tag → no PyPI upload.
|
|
232
|
+
2. **Notes file is a raw commit dump.** Step 3's judgment guidelines.
|
|
233
|
+
3. **Tagging a non-main commit.** The workflow's "Verify tag is on main".
|
|
234
|
+
4. **Tag ≠ `pyproject.toml` version, or `__version__` drift.** Two
|
|
235
|
+
separate workflow steps; Step 4 keeps them moving together.
|
|
236
|
+
5. **Forgetting to refresh `uv.lock`.** `uv sync --frozen` fails in the
|
|
237
|
+
build job; Step 4 bumps the lock to avoid the round-trip.
|
|
238
|
+
|
|
239
|
+
## What this skill does NOT do
|
|
240
|
+
|
|
241
|
+
- **Doesn't publish to PyPI directly.** The workflow does, via Trusted
|
|
242
|
+
Publishing (OIDC). There is no PyPI token anywhere in this repo, and
|
|
243
|
+
none should be added.
|
|
244
|
+
- **Doesn't create the GitHub Release directly.** The workflow's
|
|
245
|
+
`release-github` job does, from the notes file.
|
|
246
|
+
- **Doesn't write a CHANGELOG.md.** The convention is per-release files
|
|
247
|
+
under `docs/releases/`.
|
|
248
|
+
- **Doesn't yank.** PyPI versions are immutable; a broken release is
|
|
249
|
+
fixed by shipping the next version, not by re-uploading.
|
|
@@ -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
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
name: guard-staging
|
|
2
|
+
|
|
3
|
+
# Build the LiteLLM and Envoy staging images (each with Stacktrace Guard),
|
|
4
|
+
# deploy them to their ECS Express services in the sandbox account, and
|
|
5
|
+
# smoke-test all three: LiteLLM, Envoy, and the subscription service, which
|
|
6
|
+
# runs the LiteLLM image with its subscription config. Manual only.
|
|
7
|
+
# Infrastructure: infra/guard-staging.
|
|
8
|
+
# Credentials come from GitHub OIDC; no AWS key is stored. Variables live on the
|
|
9
|
+
# litellm-staging environment: AWS_DEPLOY_ROLE_ARN, ECR_REPOSITORY_URL,
|
|
10
|
+
# ENVOY_ECR_REPOSITORY_URL, SUBSCRIPTION_ECR_REPOSITORY_URL, ECS_CLUSTER,
|
|
11
|
+
# ECS_SERVICE, ENVOY_SERVICE, SUBSCRIPTION_SERVICE, LOG_GROUP, MASTER_KEY_SECRET,
|
|
12
|
+
# STAGING_ENDPOINT, ENVOY_ENDPOINT, SUBSCRIPTION_ENDPOINT, GUARD_MODE.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
inputs:
|
|
17
|
+
ref:
|
|
18
|
+
description: Branch, tag or commit to deploy
|
|
19
|
+
required: true
|
|
20
|
+
default: main
|
|
21
|
+
|
|
22
|
+
permissions:
|
|
23
|
+
id-token: write
|
|
24
|
+
contents: read
|
|
25
|
+
|
|
26
|
+
concurrency:
|
|
27
|
+
group: guard-staging
|
|
28
|
+
cancel-in-progress: false
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
deploy:
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
environment: litellm-staging
|
|
34
|
+
timeout-minutes: 45
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
with:
|
|
38
|
+
ref: ${{ inputs.ref }}
|
|
39
|
+
|
|
40
|
+
- uses: aws-actions/configure-aws-credentials@v4
|
|
41
|
+
with:
|
|
42
|
+
role-to-assume: ${{ vars.AWS_DEPLOY_ROLE_ARN }}
|
|
43
|
+
aws-region: us-east-1
|
|
44
|
+
|
|
45
|
+
- uses: docker/setup-buildx-action@v3
|
|
46
|
+
|
|
47
|
+
- name: Build and push
|
|
48
|
+
env:
|
|
49
|
+
REPO: ${{ vars.ECR_REPOSITORY_URL }}
|
|
50
|
+
ENVOY_REPO: ${{ vars.ENVOY_ECR_REPOSITORY_URL }}
|
|
51
|
+
SUB_REPO: ${{ vars.SUBSCRIPTION_ECR_REPOSITORY_URL }}
|
|
52
|
+
run: |
|
|
53
|
+
aws ecr get-login-password | docker login --username AWS --password-stdin "${REPO%%/*}"
|
|
54
|
+
sha=$(git rev-parse --short HEAD)
|
|
55
|
+
# Layers are cached in each image's own ECR repository under the
|
|
56
|
+
# buildcache tag, so a fresh runner reuses the LiteLLM install. A
|
|
57
|
+
# missing or unreadable cache only makes the build slower.
|
|
58
|
+
cache() { echo "--cache-from type=registry,ref=$1:buildcache" \
|
|
59
|
+
"--cache-to type=registry,ref=$1:buildcache,mode=max,image-manifest=true,oci-mediatypes=true"; }
|
|
60
|
+
# shellcheck disable=SC2046
|
|
61
|
+
docker buildx build --push $(cache "$REPO") -f infra/guard-staging/images/litellm/Dockerfile \
|
|
62
|
+
-t "$REPO:$sha" -t "$REPO:staging" -t "$SUB_REPO:$sha" -t "$SUB_REPO:staging" .
|
|
63
|
+
# shellcheck disable=SC2046
|
|
64
|
+
docker buildx build --push $(cache "$ENVOY_REPO") -f infra/guard-staging/images/envoy/Dockerfile \
|
|
65
|
+
-t "$ENVOY_REPO:$sha" -t "$ENVOY_REPO:staging" .
|
|
66
|
+
|
|
67
|
+
- name: Roll all three services onto the new images
|
|
68
|
+
run: |
|
|
69
|
+
# Inline, not a script in the checkout: the checkout is the deploy ref,
|
|
70
|
+
# which may predate any helper. Each update's own deployment id is
|
|
71
|
+
# kept, and that deployment must be the service's only one, with every
|
|
72
|
+
# task running and rolloutState COMPLETED (or none, as services-stable
|
|
73
|
+
# allows). Express Mode rolls a failed canary back to the old revision,
|
|
74
|
+
# which then looks stable too; ours being gone from the list, or
|
|
75
|
+
# FAILED, fails the step. aws ecs wait services-stable allows only 10
|
|
76
|
+
# minutes and the first rollout took 9.5, so this waits up to 25, and
|
|
77
|
+
# on any failure prints each service's latest ECS events.
|
|
78
|
+
cluster="${{ vars.ECS_CLUSTER }}"
|
|
79
|
+
services=("${{ vars.ECS_SERVICE }}" "${{ vars.ENVOY_SERVICE }}" "${{ vars.SUBSCRIPTION_SERVICE }}")
|
|
80
|
+
declare -A ours
|
|
81
|
+
for s in "${services[@]}"; do
|
|
82
|
+
ours[$s]=$(aws ecs update-service --cluster "$cluster" --service "$s" \
|
|
83
|
+
--force-new-deployment --output text \
|
|
84
|
+
--query "service.deployments[?status=='PRIMARY'] | [0].id")
|
|
85
|
+
if [ -z "${ours[$s]}" ] || [ "${ours[$s]}" = None ]; then
|
|
86
|
+
# Without it a rollback to the old revision would pass as stable.
|
|
87
|
+
echo "::error::$s: update-service named no PRIMARY deployment, so a rollback can't be told apart"
|
|
88
|
+
exit 1
|
|
89
|
+
fi
|
|
90
|
+
echo "$s: deployment ${ours[$s]}"
|
|
91
|
+
done
|
|
92
|
+
events() {
|
|
93
|
+
for s in "${services[@]}"; do
|
|
94
|
+
echo "--- $s: latest events"
|
|
95
|
+
aws ecs describe-services --cluster "$cluster" --services "$s" \
|
|
96
|
+
--query 'services[0].events[:10].[createdAt,message]' --output text
|
|
97
|
+
done
|
|
98
|
+
}
|
|
99
|
+
deadline=$(( $(date +%s) + 1500 ))
|
|
100
|
+
while :; do
|
|
101
|
+
pending=0
|
|
102
|
+
for s in "${services[@]}"; do
|
|
103
|
+
read -r deployments primary state running desired <<< "$(aws ecs describe-services \
|
|
104
|
+
--cluster "$cluster" --services "$s" --output text \
|
|
105
|
+
--query 'services[0].[length(deployments), deployments[0].id, deployments[0].rolloutState, runningCount, desiredCount]')"
|
|
106
|
+
if [ "$primary" != "${ours[$s]}" ]; then
|
|
107
|
+
echo "::error::$s: our deployment ${ours[$s]} is gone; $primary is primary (rolled back)"
|
|
108
|
+
events; exit 1
|
|
109
|
+
fi
|
|
110
|
+
if [ "$state" = FAILED ]; then
|
|
111
|
+
echo "::error::$s: rollout FAILED"; events; exit 1
|
|
112
|
+
fi
|
|
113
|
+
if [ "$deployments" = 1 ] && [ "$running" = "$desired" ] \
|
|
114
|
+
&& { [ "$state" = COMPLETED ] || [ "$state" = None ]; }; then
|
|
115
|
+
continue
|
|
116
|
+
fi
|
|
117
|
+
pending=1
|
|
118
|
+
echo "wait $s: $deployments deployment(s), $state, $running/$desired running"
|
|
119
|
+
done
|
|
120
|
+
[ "$pending" = 0 ] && { echo "all stable on this run's deployments"; break; }
|
|
121
|
+
if [ "$(date +%s)" -ge "$deadline" ]; then
|
|
122
|
+
echo "::error::not stable after 25 minutes"; events; exit 1
|
|
123
|
+
fi
|
|
124
|
+
sleep 20
|
|
125
|
+
done
|
|
126
|
+
|
|
127
|
+
- name: Smoke test all three
|
|
128
|
+
env:
|
|
129
|
+
MODE: ${{ vars.GUARD_MODE }}
|
|
130
|
+
LOG_GROUP: ${{ vars.LOG_GROUP }}
|
|
131
|
+
run: |
|
|
132
|
+
MASTER_KEY=$(aws secretsmanager get-secret-value --secret-id "${{ vars.MASTER_KEY_SECRET }}" \
|
|
133
|
+
--query SecretString --output text)
|
|
134
|
+
echo "::add-mask::$MASTER_KEY"
|
|
135
|
+
fail=0
|
|
136
|
+
for endpoint in "${{ vars.STAGING_ENDPOINT }}" "${{ vars.ENVOY_ENDPOINT }}"; do
|
|
137
|
+
echo "== $endpoint"
|
|
138
|
+
ENDPOINT="$endpoint" MASTER_KEY="$MASTER_KEY" infra/guard-staging/smoke.sh || fail=1
|
|
139
|
+
done
|
|
140
|
+
echo "== ${{ vars.SUBSCRIPTION_ENDPOINT }} (subscription)"
|
|
141
|
+
ENDPOINT="${{ vars.SUBSCRIPTION_ENDPOINT }}" MASTER_KEY="$MASTER_KEY" SUBSCRIPTION=1 \
|
|
142
|
+
infra/guard-staging/smoke.sh || fail=1
|
|
143
|
+
exit $fail
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
name: Publish PyPI
|
|
2
|
+
|
|
3
|
+
# Publishes the `stacktrace-cli` distribution to PyPI from version Git tags.
|
|
4
|
+
#
|
|
5
|
+
# One-time PyPI setup (done once, by a human, before the first tag):
|
|
6
|
+
# 1. On https://pypi.org/manage/account/publishing/, add a *pending*
|
|
7
|
+
# Trusted Publisher (pending, because the project does not exist on
|
|
8
|
+
# PyPI until the first successful upload):
|
|
9
|
+
# - PyPI Project Name: stacktrace-cli
|
|
10
|
+
# - Owner: stacktrace-ai
|
|
11
|
+
# - Repository name: stacktrace
|
|
12
|
+
# - Workflow name: publish-pypi.yml
|
|
13
|
+
# - Environment name: pypi
|
|
14
|
+
# 2. Create the `pypi` environment on this repo (the name must match the
|
|
15
|
+
# publisher config exactly, or the OIDC exchange is rejected).
|
|
16
|
+
# 3. Publish by pushing a tag whose name matches pyproject.toml's version,
|
|
17
|
+
# e.g. `git tag v0.0.1 && git push origin v0.0.1`.
|
|
18
|
+
#
|
|
19
|
+
# No PyPI token is needed, and none should be added. `pypa/gh-action-pypi-publish`
|
|
20
|
+
# exchanges the GitHub OIDC token for a short-lived, scope-limited PyPI publish
|
|
21
|
+
# token — nothing long-lived sits in repo secrets waiting to leak.
|
|
22
|
+
#
|
|
23
|
+
# Workflow-injection safety: no step consumes user/PR-controlled input.
|
|
24
|
+
# GITHUB_REF_NAME is GitHub-injected (the tag name) and can only contain
|
|
25
|
+
# git-ref-safe characters.
|
|
26
|
+
|
|
27
|
+
on:
|
|
28
|
+
push:
|
|
29
|
+
tags:
|
|
30
|
+
- "v*"
|
|
31
|
+
|
|
32
|
+
permissions:
|
|
33
|
+
contents: read
|
|
34
|
+
|
|
35
|
+
jobs:
|
|
36
|
+
build:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- name: Verify tag is on main
|
|
42
|
+
run: |
|
|
43
|
+
git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main
|
|
44
|
+
if ! git merge-base --is-ancestor HEAD refs/remotes/origin/main; then
|
|
45
|
+
echo "::error::Tagged commit $(git rev-parse --short HEAD) is not reachable from origin/main. Release tags must be cut from main."
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
- uses: astral-sh/setup-uv@v6
|
|
50
|
+
with:
|
|
51
|
+
enable-cache: true
|
|
52
|
+
# Match pyproject.toml `requires-python` and ci.yml.
|
|
53
|
+
python-version: "3.11"
|
|
54
|
+
|
|
55
|
+
- name: Sync deps
|
|
56
|
+
run: uv sync --frozen
|
|
57
|
+
|
|
58
|
+
- name: Verify tag matches package version
|
|
59
|
+
run: |
|
|
60
|
+
package_version="$(uv run python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')"
|
|
61
|
+
tag_version="${GITHUB_REF_NAME#v}"
|
|
62
|
+
if [ "$package_version" != "$tag_version" ]; then
|
|
63
|
+
echo "::error::tag $GITHUB_REF_NAME does not match pyproject.toml version $package_version"
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
- name: Verify __version__ matches package version
|
|
68
|
+
# `--version` output comes from src/stacktrace/__init__.py, not
|
|
69
|
+
# pyproject.toml. If the two drift, PyPI ships a wheel whose CLI
|
|
70
|
+
# reports a version that doesn't exist — and PyPI versions are
|
|
71
|
+
# immutable, so the only fix is burning another version number.
|
|
72
|
+
run: |
|
|
73
|
+
dunder_version="$(uv run python -c 'import stacktrace; print(stacktrace.__version__)')"
|
|
74
|
+
tag_version="${GITHUB_REF_NAME#v}"
|
|
75
|
+
if [ "$dunder_version" != "$tag_version" ]; then
|
|
76
|
+
echo "::error::stacktrace.__version__ is $dunder_version but the tag is $GITHUB_REF_NAME. Bump both together."
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
- name: Verify release notes file exists
|
|
81
|
+
# Fail BEFORE PyPI publish if no notes file is committed. PyPI
|
|
82
|
+
# publishes are immutable — a missing notes file caught after
|
|
83
|
+
# publish would mean shipping to PyPI while leaving the GitHub
|
|
84
|
+
# Releases page silently inconsistent. The release-stacktrace
|
|
85
|
+
# skill writes this file during the release prep PR.
|
|
86
|
+
run: |
|
|
87
|
+
notes_path="docs/releases/${GITHUB_REF_NAME}.md"
|
|
88
|
+
if [ ! -f "$notes_path" ]; then
|
|
89
|
+
echo "::error::missing release notes file at $notes_path. The release-stacktrace skill drafts this file from the commit log; run it before tagging."
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
- name: Ruff check
|
|
94
|
+
run: uv run ruff check .
|
|
95
|
+
|
|
96
|
+
- name: Ruff format check
|
|
97
|
+
run: uv run ruff format --check .
|
|
98
|
+
|
|
99
|
+
- name: Pyright
|
|
100
|
+
run: uv run pyright
|
|
101
|
+
|
|
102
|
+
- name: Pytest
|
|
103
|
+
run: uv run pytest -q
|
|
104
|
+
|
|
105
|
+
- name: Build package
|
|
106
|
+
run: uv build
|
|
107
|
+
|
|
108
|
+
- name: Check package metadata
|
|
109
|
+
# twine >=7 required: hatchling emits `Metadata-Version: 2.5` (PEP 794),
|
|
110
|
+
# and twine 6.2.0 and earlier hard-cap recognized metadata versions at
|
|
111
|
+
# 2.4, so they reject a perfectly valid wheel. Unpinned `uvx twine` can
|
|
112
|
+
# resolve an older cached twine from the uv cache this workflow warms.
|
|
113
|
+
run: uvx --from 'twine>=7' twine check dist/*
|
|
114
|
+
|
|
115
|
+
- name: Upload package artifact
|
|
116
|
+
uses: actions/upload-artifact@v4
|
|
117
|
+
with:
|
|
118
|
+
name: python-package
|
|
119
|
+
path: dist/*
|
|
120
|
+
retention-days: 7
|
|
121
|
+
|
|
122
|
+
publish:
|
|
123
|
+
needs: build
|
|
124
|
+
runs-on: ubuntu-latest
|
|
125
|
+
environment:
|
|
126
|
+
name: pypi
|
|
127
|
+
url: https://pypi.org/project/stacktrace-cli/
|
|
128
|
+
permissions:
|
|
129
|
+
contents: read
|
|
130
|
+
id-token: write # required for Trusted Publishing (OIDC)
|
|
131
|
+
steps:
|
|
132
|
+
- name: Download package artifact
|
|
133
|
+
uses: actions/download-artifact@v4
|
|
134
|
+
with:
|
|
135
|
+
name: python-package
|
|
136
|
+
path: dist
|
|
137
|
+
|
|
138
|
+
- name: Publish to PyPI
|
|
139
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
140
|
+
|
|
141
|
+
release-github:
|
|
142
|
+
# Create the GitHub Release object so the Releases page reflects what
|
|
143
|
+
# actually shipped. Runs only after PyPI publish succeeds — if PyPI
|
|
144
|
+
# failed there's no reason to advertise the release on GitHub. The
|
|
145
|
+
# notes file's presence was verified in the build job, so the only
|
|
146
|
+
# failure modes here are gh/API errors.
|
|
147
|
+
needs: publish
|
|
148
|
+
runs-on: ubuntu-latest
|
|
149
|
+
permissions:
|
|
150
|
+
contents: write # gh release create writes the release
|
|
151
|
+
steps:
|
|
152
|
+
- uses: actions/checkout@v4
|
|
153
|
+
with:
|
|
154
|
+
ref: ${{ github.ref }}
|
|
155
|
+
fetch-depth: 1
|
|
156
|
+
|
|
157
|
+
- name: Create GitHub Release
|
|
158
|
+
env:
|
|
159
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
160
|
+
TAG: ${{ github.ref_name }}
|
|
161
|
+
run: |
|
|
162
|
+
notes_path="docs/releases/${TAG}.md"
|
|
163
|
+
# The first H1 line in the notes file becomes the Release title.
|
|
164
|
+
title="$(grep -m1 '^# ' "$notes_path" | sed 's/^# //' || true)"
|
|
165
|
+
if [ -z "$title" ]; then
|
|
166
|
+
title="$TAG"
|
|
167
|
+
fi
|
|
168
|
+
# Mark PEP 440 pre-releases (aN/bN/rcN suffix) as GitHub prereleases.
|
|
169
|
+
# `gh release create` defaults to "latest stable" otherwise.
|
|
170
|
+
prerelease_flag=""
|
|
171
|
+
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(a|b|rc)[0-9]+$ ]]; then
|
|
172
|
+
prerelease_flag="--prerelease"
|
|
173
|
+
fi
|
|
174
|
+
gh release create "$TAG" \
|
|
175
|
+
--title "$title" \
|
|
176
|
+
--notes-file "$notes_path" \
|
|
177
|
+
--verify-tag \
|
|
178
|
+
$prerelease_flag
|