drift-analyzer 2.2.0__tar.gz → 2.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/_partials/konventionen.md +25 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-agent-ux.prompt.md +4 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-agent-workflow-test.prompt.md +4 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-ai-integration.prompt.md +7 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-ci-gate.prompt.md +7 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-onboarding.prompt.md +7 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-signal-quality.prompt.md +7 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/field-tests/drift-context-eval.prompt.md +12 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/field-tests/drift-field-test.prompt.md +12 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/field-tests/drift-finding-audit.prompt.md +12 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.gitignore +1 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/CHANGELOG.md +18 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/PKG-INFO +1 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/SECURITY.md +3 -1
- drift_analyzer-2.3.1/decisions/ADR-011-csv-output-format.md +52 -0
- drift_analyzer-2.3.1/docs-site/reference/signals/pfs.md +184 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/mkdocs.yml +2 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/pyproject.toml +1 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/analyzer.py +12 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/api.py +48 -5
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/cli.py +3 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/analyze.py +19 -4
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/baseline.py +1 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/check.py +39 -3
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/self_analyze.py +5 -1
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/errors.py +2 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/ingestion/git_history.py +45 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/output/__init__.py +2 -0
- drift_analyzer-2.3.1/src/drift/output/csv_output.py +48 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/doc_impl_drift.py +55 -6
- drift_analyzer-2.3.1/tests/test_analysis_edge_cases.py +100 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_baseline.py +29 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_compat.py +8 -0
- drift_analyzer-2.3.1/tests/test_csv_output.py +93 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_dia_enhanced.py +17 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_git_history_safety.py +7 -2
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_insecure_default.py +223 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_mcp_copilot.py +6 -3
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_negative_context_export.py +6 -3
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_scan_diversity.py +84 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.detect-secrets.cfg +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.devcontainer/devcontainer.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.githooks/commit-msg +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.githooks/pre-commit +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.githooks/pre-push +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/AGENTS.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/CODEOWNERS +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/DISCUSSION_TEMPLATE/questions.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/FUNDING.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/contribution_proposal.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/false_positive.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/good_first_issue.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/study_finding_rating.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/study_repo_benchmark.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/ISSUE_TEMPLATE/study_self_analysis.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/copilot-instructions.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/dependabot.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/instructions/drift-policy.instructions.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/instructions/drift-push-gates.instructions.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/instructions/drift-release-automation.instructions.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/instructions/drift-release-mandatory.instructions.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/labeler.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/labels.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/PR-Orchestrator.prompt.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/_partials/bewertungs-taxonomie.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/_partials/issue-filing-external.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/_partials/issue-filing.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/field-tests/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/release.prompt.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/repo-guard.blocklist +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/repo-root-allowlist +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/skills/drift-pr-review/SKILL.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/skills/drift-release/SKILL.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/skills/drift-security-triage/SKILL.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/ci.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/codeql.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/dependency-review.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/docs.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/install-smoke.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/labeler.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/package-kpis.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/publish.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/release.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/repo-guard.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/security-hygiene.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/stale.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/validate-release.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/welcome.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/workflows/workflow-sanity.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.markdownlint-cli2.jsonc +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.pre-commit-config.yaml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.pre-commit-hooks.yaml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.secrets.baseline +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.shellcheckrc +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.vscode/mcp.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.vscode/settings.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.vscode/tasks.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/CITATION.cff +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/CLAUDE.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/CODE_OF_CONDUCT.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/CONTRIBUTING.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/DEVELOPER.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/LICENSE +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/Makefile +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/POLICY.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/ROADMAP.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/SUPPORT.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/action.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/manifest.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/connectors/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/connectors/db.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/handler_v1.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/handler_v2.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/handlers/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/handlers/auth.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/handlers/orders.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/handlers/payments.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/handlers/shipping.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/models/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/models/core.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/models/enriched.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/outlier_module.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/processors/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/processors/pricing.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/processors/transform.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/processors/validator.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/service_a.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/service_b.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/utils/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/utils/formatting.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/utils/helpers.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/src/myapp/utils/naming.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/tests/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/benchmarks/corpus/tests/test_api.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/conda.recipe/meta.yaml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/decisions/ADR-010-finding-context-triage-policy.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/decisions/templates/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/decisions/templates/adr-template.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/decisions/templates/signal-design-template.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/EPISTEMICS.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/LAUNCH_CHECKLIST.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/OUTREACH.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/PRODUCT_STRATEGY.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/ROOT_POLICY.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/STUDY.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/adr/001-deterministic-analysis-pipeline.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/adr/002-ast-fingerprinting-for-patterns.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/adr/003-composite-scoring-model.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/adr/004-subprocess-git-parsing.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/adr/005-delta-first-score-interpretation.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/adr/006-context-tagging.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/adr/007-consistency-proxy-signals.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/adr/008-intention-contract-proxy-signals.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/distribution/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/distribution/awesome-submissions.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/distribution/devto-hashnode-5-repos.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/distribution/ide-discovery-mvp-spec.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/distribution/week1-rollout-runbook.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/drift-architecture-erosion-analysis.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/go-mvp-scope.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/language-roadmap.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/language-support-matrix.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/migration.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/python-baseline.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/python-rule-inventory.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs/tsjs-mvp-scope.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/algorithms/deep-dive.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/algorithms/scoring.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/algorithms/signals.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/assets/logo.svg +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/benchmarking.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/case-studies/django.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/case-studies/fastapi.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/case-studies/index.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/case-studies/pydantic.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/changelog.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/comparisons/drift-vs-architecture-conformance.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/comparisons/drift-vs-ruff.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/comparisons/drift-vs-semgrep-codeql.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/comparisons/index.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/contributing.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/faq.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/getting-started/configuration.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/getting-started/finding-triage.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/getting-started/installation.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/getting-started/quickstart.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/getting-started/team-rollout.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/getting-started/troubleshooting.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/glossary.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/index.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/integrations.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/product/example-findings.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/product/press-brand.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/product-strategy.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/reference/api-outputs.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/reference/negative-context.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/reference/performance.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/stability.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/start-here.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/study.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/trust-evidence.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/use-cases/architectural-linter-ai-teams.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/use-cases/architecture-drift-python.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/use-cases/ci-architecture-checks-sarif.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/use-cases/index.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/docs-site/use-cases/technical-debt-ai-codebases.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/drift.example.yaml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/api/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/api/routes.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/db/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/db/models.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/services/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/services/email_service.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/services/order_service.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/services/user_service.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/utils/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo-project/utils/validators.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/demo_fastapi.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/drift-check.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/package-kpis/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/package-kpis/defects.csv +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/package-kpis/kpi-thresholds.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/package-kpis/usage.csv +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/vibe-coding/README.md +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/vibe-coding/drift-gate.yml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/vibe-coding/drift.yaml +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/vibe-coding/mcp.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/vibe-coding/pre-push +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/vibe-coding/setup-baseline.sh +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/examples/vibe-coding/weekly-check.sh +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/llms.txt +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/overrides/home.html +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/overrides/main.html +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/__main__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/analyzers/typescript/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/analyzers/typescript/_path_utils.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/analyzers/typescript/alias_resolver.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/analyzers/typescript/barrel_resolver.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/analyzers/typescript/import_graph.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/analyzers/typescript/shared.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/analyzers/typescript/workspace_boundaries.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/api_helpers.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/baseline.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/cache.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/_io.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/badge.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/config_cmd.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/copilot_context.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/diff_cmd.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/explain.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/export_context.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/fix_plan.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/init_cmd.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/mcp.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/patterns.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/scan.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/timeline.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/trend.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/commands/validate_cmd.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/config.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/context_tags.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/copilot_context.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/embeddings.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/finding_context.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/incremental.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/ingestion/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/ingestion/ast_parser.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/ingestion/file_discovery.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/ingestion/ts_parser.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/mcp_server.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/models.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/negative_context.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/negative_context_export.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/output/agent_tasks.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/output/github_format.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/output/json_output.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/output/rich_output.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/pipeline.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/profiles.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/py.typed +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/recommendations.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/rules/tsjs/circular_module_detection.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/rules/tsjs/cross_package_import_ban.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/rules/tsjs/layer_leak_detection.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/rules/tsjs/ui_to_infra_import_ban.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/scoring/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/scoring/engine.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/_utils.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/architecture_violation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/base.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/broad_exception_monoculture.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/bypass_accumulation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/circular_import.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/co_change_coupling.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/cognitive_complexity.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/cohesion_deficit.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/dead_code_accumulation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/exception_contract_drift.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/explainability_deficit.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/fan_out_explosion.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/guard_clause_deficit.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/hardcoded_secret.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/insecure_default.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/missing_authorization.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/mutant_duplicates.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/naming_contract_violation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/pattern_fragmentation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/system_misalignment.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/temporal_volatility.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/test_polarity_deficit.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/signals/ts_architecture.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/suppression.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/telemetry.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/timeline.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/src/drift/trend_history.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/conftest.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/__init__.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/ground_truth.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/study_samples/debt_correlation.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/study_samples/rater_matrix.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/study_samples/self_analysis_reports.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution/src/app.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution/src/core/logger.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution/src/shared/config.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution/tsconfig.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/src/app.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/src/base/logger.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/src/leaf/feature.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/src/mid/util.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/src/override/config.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/src/shared/config.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/tsconfig.base.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/tsconfig.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_alias_resolution_extends/tsconfig.mid.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_barrel_resolution/src/app.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_barrel_resolution/src/app_tsx.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_barrel_resolution/src/button.tsx +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_barrel_resolution/src/index.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_barrel_resolution/src/view/card.tsx +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_barrel_resolution/src/view/index.tsx +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_graph_relative/app.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_graph_relative/components/button.tsx +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_graph_relative/components/index.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_graph_relative/lib/util.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cross_package/negative/cross_package_import_ban.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cross_package/negative/package.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cross_package/negative/packages/app/src/main.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cross_package/negative/packages/ui/src/button.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cross_package/positive/cross_package_import_ban.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cross_package/positive/package.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cross_package/positive/packages/app/src/main.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cross_package/positive/packages/ui/src/button.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cycles/negative/src/a.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cycles/negative/src/b.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cycles/positive/src/a.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_cycles/positive/src/b.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_layer_leak/negative/layer_leak_detection.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_layer_leak/negative/src/infra/storage.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_layer_leak/negative/src/ui/view.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_layer_leak/positive/layer_leak_detection.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_layer_leak/positive/src/infra/storage.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_layer_leak/positive/src/ui/view.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_ui_to_infra/negative/src/infra/storage.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_ui_to_infra/negative/src/ui/components/button.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_ui_to_infra/negative/src/ui/view.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_ui_to_infra/negative/ui_to_infra_import_ban.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_ui_to_infra/positive/src/infra/storage.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_ui_to_infra/positive/src/ui/view.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_rule_ui_to_infra/positive/ui_to_infra_import_ban.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_workspace_boundaries/package.json +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_workspace_boundaries/packages/app/src/main.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_workspace_boundaries/packages/ui/src/button.tsx +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/fixtures/tsjs_workspace_boundaries/vite.config.ts +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_ablation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_agent_native_cli.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_agent_tasks.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_ai_tool_indicators.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_analysis_degradation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_architecture_violation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_ast_parser.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_avs_enhanced.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_avs_missing_patterns_evidence.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_avs_mutations.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_badge_command.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_benchmark_label_keys.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_benchmark_structure.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_bypass_accumulation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_cache_resilience.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_ci_reality.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_circular_import.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_cli_runtime.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_co_change_coupling.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_cognitive_complexity.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_cohesion_deficit.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_config.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_config_validate.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_consistency_proxies.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_console_scripts.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_context_tags.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_copilot_context_coverage.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_dead_code_accumulation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_delta_first.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_dx_features.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_embeddings.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_enterprise_governance_assets.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_exception_contract_drift.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_fan_out_explosion.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_fetch_github_usage.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_fetch_pypistats.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_file_discovery.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_finding_context.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_fix_actionability.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_git_history_edge_cases.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_guard_clause_deficit.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_hardcoded_secret.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_incremental.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_init_cmd.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_integration.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_json_output.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_mcp_hardening.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_mirofish_signal_improvements.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_missing_authorization.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_model_consistency.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_module_entrypoint.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_mutant_duplicates_edge_cases.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_naming_contract_violation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_negative_context.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_nudge.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_output_golden.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_output_minimal_and_signal_labels.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_package_kpis.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_path_overrides.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_pattern_fragmentation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_pipeline_components.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_precision_recall.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_property_based.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_recommendations.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_recommendations_edge_cases.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_release_automation.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_release_discipline.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_repo_hygiene.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_rule_ids.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_sarif_contract.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_scoring.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_scoring_edge_cases.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_self_command.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_signal_contract.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_signal_utils.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_smoke_real_repos.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_study_infrastructure.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_suppression.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_telemetry.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_test_polarity_deficit.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_timeline.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_trend_chart.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_trend_command_history.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_ts_signals_phase2.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_ts_signals_phase3.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_tsjs_alias_resolution.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_tsjs_barrel_resolution.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_tsjs_import_graph_relative.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_tsjs_rule_circular_module_detection.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_tsjs_rule_cross_package_import_ban.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_tsjs_rule_layer_leak_detection.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_tsjs_rule_ui_to_infra_import_ban.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_tsjs_workspace_boundaries.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_typescript_parser.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/tests/test_workspace_value.py +0 -0
- {drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/uv.lock +0 -0
|
@@ -60,6 +60,31 @@ Keine Prompt-spezifischen Bewertungssysteme einführen.
|
|
|
60
60
|
Bei GitHub-Issue-Erstellung den Template-Block aus `_partials/issue-filing.md` verwenden.
|
|
61
61
|
Keine individuellen Issue-Templates pro Prompt.
|
|
62
62
|
|
|
63
|
+
## Versions-Freshness
|
|
64
|
+
|
|
65
|
+
Jeder Prompt MUSS sicherstellen, dass die aktuellste `drift-analyzer`-Version verwendet wird.
|
|
66
|
+
Ein Test gegen eine veraltete Version hat keinen Erkenntniswert.
|
|
67
|
+
|
|
68
|
+
**Field-Test-Prompts** (externe Repos — PyPI-Release):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install --upgrade drift-analyzer # Immer zuerst upgraden
|
|
72
|
+
drift --version # Installierte Version dokumentieren
|
|
73
|
+
pip index versions drift-analyzer 2>/dev/null | head -1 # Optional: Verfügbare Versionen prüfen
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Falls `pip install --upgrade` scheitert (Netzwerk, Index), MUSS dies im Report dokumentiert
|
|
77
|
+
und die aktuell installierte Version explizit angegeben werden.
|
|
78
|
+
|
|
79
|
+
**Interne Prompts** (Drift-Workspace — Dev-Version):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install -e . # Dev-Version aus dem Workspace installieren
|
|
83
|
+
drift --version # Muss mit pyproject.toml übereinstimmen
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Beide Szenarien: Die genutzte drift-Version MUSS im Report-Header oder Repo-Profil erscheinen.
|
|
87
|
+
|
|
63
88
|
## Querverweise
|
|
64
89
|
|
|
65
90
|
Jeder Prompt SOLLTE am Ende seines Frontmatter-Bereichs oder in einem dedizierten Abschnitt
|
|
@@ -73,9 +73,12 @@ Erstelle Artefakte unter `work_artifacts/agent_ux_<YYYY-MM-DD>/`:
|
|
|
73
73
|
|
|
74
74
|
Erkunde die CLI als Zero-Knowledge-Agent.
|
|
75
75
|
|
|
76
|
+
**Dev-Version sicherstellen** (siehe `_partials/konventionen.md` → Versions-Freshness):
|
|
77
|
+
|
|
76
78
|
```bash
|
|
79
|
+
pip install -e . # Dev-Version aus Workspace
|
|
77
80
|
drift --help
|
|
78
|
-
drift --version
|
|
81
|
+
drift --version # Muss mit pyproject.toml übereinstimmen
|
|
79
82
|
```
|
|
80
83
|
|
|
81
84
|
Für jedes Top-Level-Kommando:
|
{drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-agent-workflow-test.prompt.md
RENAMED
|
@@ -82,8 +82,11 @@ New-Item -ItemType Directory -Path $sandbox -Force
|
|
|
82
82
|
|
|
83
83
|
### Phase 1: Installation & Discovery
|
|
84
84
|
|
|
85
|
+
**Dev-Version sicherstellen** (siehe `_partials/konventionen.md` → Versions-Freshness):
|
|
86
|
+
|
|
85
87
|
```bash
|
|
86
|
-
|
|
88
|
+
pip install -e . # Dev-Version aus Workspace
|
|
89
|
+
drift --version # Muss mit pyproject.toml übereinstimmen
|
|
87
90
|
drift --help
|
|
88
91
|
```
|
|
89
92
|
|
{drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-ai-integration.prompt.md
RENAMED
|
@@ -74,6 +74,13 @@ Erstelle Artefakte unter `work_artifacts/ai_integration_<YYYY-MM-DD>/`:
|
|
|
74
74
|
|
|
75
75
|
### Phase 0: AI-facing Oberflächen inventarisieren
|
|
76
76
|
|
|
77
|
+
**Dev-Version sicherstellen** (siehe `_partials/konventionen.md` → Versions-Freshness):
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install -e . # Dev-Version aus Workspace
|
|
81
|
+
drift --version # Muss mit pyproject.toml übereinstimmen
|
|
82
|
+
```
|
|
83
|
+
|
|
77
84
|
Identifiziere alle derzeit exponierten AI-facing Features:
|
|
78
85
|
- `copilot-context`
|
|
79
86
|
- `export-context` (Formate: `instructions`, `prompt`, `raw`)
|
|
@@ -70,6 +70,13 @@ Erstelle Artefakte unter `work_artifacts/ci_gate_<YYYY-MM-DD>/`:
|
|
|
70
70
|
|
|
71
71
|
### Phase 0: Gate-relevante Kommandos inventarisieren
|
|
72
72
|
|
|
73
|
+
**Dev-Version sicherstellen** (siehe `_partials/konventionen.md` → Versions-Freshness):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install -e . # Dev-Version aus Workspace
|
|
77
|
+
drift --version # Muss mit pyproject.toml übereinstimmen
|
|
78
|
+
```
|
|
79
|
+
|
|
73
80
|
Identifiziere die für CI relevanten Kommandos und Optionen, insbesondere:
|
|
74
81
|
- `check` (mit `--fail-on`, `--json`, `--compact`, `--output-format`)
|
|
75
82
|
- `validate`
|
|
@@ -69,6 +69,13 @@ Erstelle Artefakte unter `work_artifacts/onboarding_<YYYY-MM-DD>/`:
|
|
|
69
69
|
|
|
70
70
|
### Phase 0: Neueinsteiger-Perspektive einnehmen
|
|
71
71
|
|
|
72
|
+
**Dev-Version sicherstellen** (siehe `_partials/konventionen.md` → Versions-Freshness):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install -e . # Dev-Version aus Workspace
|
|
76
|
+
drift --version # Muss mit pyproject.toml übereinstimmen
|
|
77
|
+
```
|
|
78
|
+
|
|
72
79
|
Nimm an, du hast kein repo-spezifisches Drift-Wissen außer dem, was CLI und generierte Dateien liefern.
|
|
73
80
|
|
|
74
81
|
Dokumentiere:
|
{drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/drift-signal-quality.prompt.md
RENAMED
|
@@ -78,6 +78,13 @@ Erstelle Artefakte unter `work_artifacts/signal_quality_<YYYY-MM-DD>/`:
|
|
|
78
78
|
|
|
79
79
|
### Phase 0: Signal-Inventar erstellen
|
|
80
80
|
|
|
81
|
+
**Dev-Version sicherstellen** (siehe `_partials/konventionen.md` → Versions-Freshness):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install -e . # Dev-Version aus Workspace
|
|
85
|
+
drift --version # Muss mit pyproject.toml übereinstimmen
|
|
86
|
+
```
|
|
87
|
+
|
|
81
88
|
Signale aus realer CLI-Ausgabe inventarisieren und Abkürzungen, Namen und verfügbare Beschreibungen erfassen.
|
|
82
89
|
|
|
83
90
|
Mindestens prüfen:
|
|
@@ -70,7 +70,17 @@ Erstelle Artefakte unter `work_artifacts/context_eval_<YYYY-MM-DD>/`:
|
|
|
70
70
|
|
|
71
71
|
### Phase 0: Repo-Profil erstellen
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
**Versions-Freshness sicherstellen:**
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install --upgrade drift-analyzer # Aktuellste Version von PyPI
|
|
77
|
+
drift --version # Version dokumentieren
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Falls das Upgrade scheitert (Netzwerk, Index), dies im Report dokumentieren
|
|
81
|
+
und mit der aktuell installierten Version fortfahren.
|
|
82
|
+
|
|
83
|
+
**Identisches Profil wie in `drift-finding-audit` Phase 0:**
|
|
74
84
|
|
|
75
85
|
| Eigenschaft | Wert |
|
|
76
86
|
|-------------|------|
|
|
@@ -79,6 +89,7 @@ Identisches Profil wie in `drift-finding-audit` Phase 0:
|
|
|
79
89
|
| Sprache(n) | [Python / TypeScript / Mixed] |
|
|
80
90
|
| Framework(s) | [Django / Flask / FastAPI / Express / None / ...] |
|
|
81
91
|
| Ungefähre Größe | [Dateien / LOC] |
|
|
92
|
+
| drift-Version | [VERSION] |
|
|
82
93
|
|
|
83
94
|
### Phase 1: Alle Export-Formate ausführen
|
|
84
95
|
|
{drift_analyzer-2.2.0 → drift_analyzer-2.3.1}/.github/prompts/field-tests/drift-field-test.prompt.md
RENAMED
|
@@ -67,6 +67,18 @@ Erstelle Artefakte unter `work_artifacts/field_test_<YYYY-MM-DD>/`:
|
|
|
67
67
|
|
|
68
68
|
### Phase 0: Voraussetzungen prüfen
|
|
69
69
|
|
|
70
|
+
**Versions-Freshness sicherstellen:**
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install --upgrade drift-analyzer # Aktuellste Version von PyPI
|
|
74
|
+
drift --version # Version dokumentieren
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Falls das Upgrade scheitert (Netzwerk, Index), dies im Report dokumentieren
|
|
78
|
+
und mit der aktuell installierten Version fortfahren.
|
|
79
|
+
|
|
80
|
+
**System-Voraussetzungen:**
|
|
81
|
+
|
|
70
82
|
```bash
|
|
71
83
|
python --version # ≥ 3.11 erforderlich
|
|
72
84
|
git --version # Git muss vorhanden sein
|
|
@@ -75,7 +75,17 @@ Erstelle Artefakte unter `work_artifacts/finding_audit_<YYYY-MM-DD>/`:
|
|
|
75
75
|
|
|
76
76
|
### Phase 0: Architektur-Profil erstellen
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
**Versions-Freshness sicherstellen:**
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install --upgrade drift-analyzer # Aktuellste Version von PyPI
|
|
82
|
+
drift --version # Version dokumentieren
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Falls das Upgrade scheitert (Netzwerk, Index), dies im Report dokumentieren
|
|
86
|
+
und mit der aktuell installierten Version fortfahren.
|
|
87
|
+
|
|
88
|
+
**Repository analysieren**, um einen informierten Oracle aufzubauen:
|
|
79
89
|
|
|
80
90
|
```bash
|
|
81
91
|
# Struktur verstehen
|
|
@@ -98,6 +108,7 @@ ls -la # oder: Get-ChildItem
|
|
|
98
108
|
| Sprache(n) | [Python / TypeScript / Mixed] |
|
|
99
109
|
| Framework(s) | [Django / Flask / FastAPI / Express / None / ...] |
|
|
100
110
|
| Ungefähre Größe | [Dateien / LOC] |
|
|
111
|
+
| drift-Version | [VERSION] |
|
|
101
112
|
| Bekannte Architekturentscheidungen | [z.B. "Django-apps-Struktur", "Hexagonal", "Layered"] |
|
|
102
113
|
|
|
103
114
|
### Phase 1: Oracle aufbauen
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
- Introduce configurable finding-context triage policy with precedence-based glob rules to keep non-operational findings out of default remediation queues unless explicitly requested.
|
|
6
6
|
- Add `--progress json` option to `scan` and `analyze` commands for structured JSON-lines progress feedback on stderr, enabling agents to distinguish running from hung processes (#104).
|
|
7
|
+
- `drift check` now supports `--save-baseline` and `--max-findings` options for CI parity with `drift analyze` (#116).
|
|
8
|
+
- `drift diff` JSON output now includes `score_basis` field (`"historical"` or `"zero_default"`) to clarify when `score_before` reflects actual repo baseline vs. synthetic zero (#119).
|
|
9
|
+
- Add `csv` output format for `drift analyze` and `drift check` to export findings as one-row-per-finding tabular output (`signal,severity,score,title,file,start_line,end_line`) (#14).
|
|
10
|
+
- Add a dedicated PFS signal reference page in docs with detection details, scoring formula, severity thresholds, remediation guidance, and example outputs (#24).
|
|
11
|
+
- Add regression test suites for edge-case projects and framework-specific ISD fixtures to improve signal robustness across minimal and real-world repository shapes (#13, #26).
|
|
7
12
|
|
|
8
13
|
### Changed
|
|
9
14
|
|
|
@@ -11,6 +16,8 @@
|
|
|
11
16
|
|
|
12
17
|
### Fixed
|
|
13
18
|
|
|
19
|
+
- Reduce DIA false positives by requiring structural context for plain markdown slash-tokens (e.g. `async/`, `scan/`, `connectors/`) before emitting missing-directory findings, while preserving explicit path references in code spans/backticks (#121).
|
|
20
|
+
- Add trailing newlines in CSV formatter and CSV tests to satisfy lint gate requirements and keep pre-push checks green.
|
|
14
21
|
- Surface file I/O errors in `analyze`, `check`, and `scan` commands as structured `DRIFT-2003` errors with exit code 2 instead of unhandled `OSError` tracebacks.
|
|
15
22
|
- Validate `--max-findings` range (1–200) in `drift scan` via `click.IntRange` and reject out-of-range values with exit code 2.
|
|
16
23
|
- Improve `DRIFT-2003` action message to explicitly suggest checking output path writability and parent directory existence.
|
|
@@ -26,11 +33,21 @@
|
|
|
26
33
|
- Add `description` fields to all MCP tool parameters via `Annotated[type, Field(description=...)]` and include descriptions in `drift mcp --schema` catalog output so agents can infer valid parameter ranges and formats (#110).
|
|
27
34
|
- Replace all non-ASCII characters (emoji severity icons, arrows, ellipsis) in Markdown export output with ASCII equivalents to eliminate mojibake on Windows (#111).
|
|
28
35
|
- Add cross-reference notes between `copilot-context` and `export-context` outputs so agents using either surface are made aware of the complementary context (#112).
|
|
36
|
+
- Suppress Rich progress bar on stderr for machine-readable output formats (`--json`, `--sarif`) to prevent PowerShell `NativeCommandError` from non-JSON prelude (#118).
|
|
37
|
+
- Map git-root-relative paths to repo-relative paths in `analyze_diff` and `parse_git_history` so `--repo` on nested subdirectories no longer leaks parent-repo file scope (#117).
|
|
38
|
+
- `drift self` error guidance now suggests valid next actions (`drift scan`/`drift analyze`) instead of invalid `--repo` flag (#120).
|
|
39
|
+
|
|
40
|
+
## [2.3.0] - 2026-04-03
|
|
41
|
+
|
|
42
|
+
Short version: Align release metadata with current project version.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- Sync top changelog release marker to 2.2.0 so release-discipline checks match [project] version in pyproject.toml.
|
|
29
47
|
|
|
30
48
|
## [2.1.3] - 2026-04-02
|
|
31
49
|
|
|
32
50
|
Short version: Keep release metadata aligned after CI runner hardening updates.
|
|
33
|
-
|
|
34
51
|
### Fixed
|
|
35
52
|
|
|
36
53
|
- Align release bookkeeping so `pyproject.toml` and top changelog release stay in sync for pre-push release-discipline checks.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drift-analyzer
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.1
|
|
4
4
|
Summary: Deterministic architectural drift detection for AI-accelerated Python repositories through cross-file coherence analysis
|
|
5
5
|
Project-URL: Homepage, https://sauremilk.github.io/drift/
|
|
6
6
|
Project-URL: Repository, https://github.com/mick-gsk/drift
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
| Version | Supported |
|
|
6
6
|
| ------- | ------------------ |
|
|
7
|
+
| 2.3.x | :white_check_mark: |
|
|
8
|
+
| 2.2.x | :white_check_mark: |
|
|
7
9
|
| 2.1.x | :white_check_mark: |
|
|
8
10
|
| 2.0.x | :white_check_mark: |
|
|
9
11
|
| 1.5.x | :white_check_mark: |
|
|
@@ -17,7 +19,7 @@
|
|
|
17
19
|
| 0.7.x | :white_check_mark: |
|
|
18
20
|
| < 0.7 | :x: |
|
|
19
21
|
|
|
20
|
-
Current release line: **v2.
|
|
22
|
+
Current release line: **v2.3.0**.
|
|
21
23
|
|
|
22
24
|
## Reporting a Vulnerability
|
|
23
25
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ADR-011
|
|
3
|
+
status: proposed
|
|
4
|
+
date: 2026-04-03
|
|
5
|
+
supersedes:
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ADR-011: CSV-Ausgabeformat fuer Findings
|
|
9
|
+
|
|
10
|
+
## Kontext
|
|
11
|
+
|
|
12
|
+
Drift bietet derzeit rich-, json-, sarif-, agent-tasks- und github-Ausgaben.
|
|
13
|
+
Fuer viele Teams fehlt ein leicht importierbares Tabellenformat fuer schnelle
|
|
14
|
+
Weiterverarbeitung in Kalkulation, einfache Filter-Pipelines oder PM-Boards.
|
|
15
|
+
|
|
16
|
+
## Entscheidung
|
|
17
|
+
|
|
18
|
+
Wir fuehren ein neues Output-Format `csv` fuer `drift analyze` und `drift check`
|
|
19
|
+
ein. Die Ausgabe enthaelt pro Finding genau eine Zeile mit stabilem Header:
|
|
20
|
+
|
|
21
|
+
`signal,severity,score,title,file,start_line,end_line`
|
|
22
|
+
|
|
23
|
+
Rahmenbedingungen:
|
|
24
|
+
|
|
25
|
+
- Implementierung in `src/drift/output/csv_output.py`.
|
|
26
|
+
- Nutzung des Python-Standardmoduls `csv` (keine neue Abhaengigkeit).
|
|
27
|
+
- Deterministische Zeilenreihenfolge analog zu bestehenden
|
|
28
|
+
maschinenlesbaren Ausgaben.
|
|
29
|
+
- Keine Aenderung an Signalberechnung, Scoring oder Severity-Logik.
|
|
30
|
+
|
|
31
|
+
Explizit nicht Teil dieser ADR:
|
|
32
|
+
|
|
33
|
+
- keine neuen Felder im CSV-Schema in dieser Iteration
|
|
34
|
+
- keine Aenderung an `self`/`scan`-Format-Optionen
|
|
35
|
+
|
|
36
|
+
## Begründung
|
|
37
|
+
|
|
38
|
+
CSV verbessert Einfuehrbarkeit und Handlungsfaehigkeit bei minimaler
|
|
39
|
+
Komplexitaet: einfacher Datenaustausch ohne Schema-Parser, reproduzierbar und
|
|
40
|
+
mit bestehender CLI-Ausgabe konsistent.
|
|
41
|
+
|
|
42
|
+
## Konsequenzen
|
|
43
|
+
|
|
44
|
+
- Additiver CLI-Output-Kanal ohne Breaking Change.
|
|
45
|
+
- Zusätzlicher Pflegeaufwand fuer einen weiteren Serializer (niedrig).
|
|
46
|
+
- CSV bleibt bewusst kompakt; tiefe Metadaten bleiben in JSON/SARIF.
|
|
47
|
+
|
|
48
|
+
## Validierung
|
|
49
|
+
|
|
50
|
+
- Unit-Tests fuer Header, Feldreihenfolge und CSV-Escaping.
|
|
51
|
+
- CLI-Choice-Test fuer `--output-format csv`.
|
|
52
|
+
- Policy §10 Lernzyklus-Status: unklar (Nutzerfeedback nach Feldnutzung).
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Pattern Fragmentation Signal (PFS)
|
|
2
|
+
|
|
3
|
+
**Signal ID:** `PFS`
|
|
4
|
+
**Full name:** Pattern Fragmentation Score
|
|
5
|
+
**Type:** Scoring signal (contributes to drift score)
|
|
6
|
+
**Default weight:** `0.16`
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## What PFS detects
|
|
11
|
+
|
|
12
|
+
PFS identifies modules where the **same category of code pattern** (e.g. error handling, data validation, logging) is implemented in **multiple incompatible ways**. This fragmentation is a strong indicator of architectural drift — often caused by different AI generation sessions producing slightly different implementations of the same concept.
|
|
13
|
+
|
|
14
|
+
### Before — fragmented error handling
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
# services/payment_service.py
|
|
18
|
+
def process_payment(amount):
|
|
19
|
+
try:
|
|
20
|
+
validate(amount)
|
|
21
|
+
return {"status": "ok"}
|
|
22
|
+
except ValueError as e:
|
|
23
|
+
raise PaymentError(str(e)) from e
|
|
24
|
+
|
|
25
|
+
def refund_payment(transaction_id):
|
|
26
|
+
try:
|
|
27
|
+
result = lookup(transaction_id)
|
|
28
|
+
return True
|
|
29
|
+
except Exception as e: # ← bare except, different style
|
|
30
|
+
print(e)
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
def cancel_payment(payment_id):
|
|
34
|
+
result = lookup(payment_id)
|
|
35
|
+
if result is None: # ← no try/except at all
|
|
36
|
+
logger.warning("Not found")
|
|
37
|
+
return False
|
|
38
|
+
return True
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Three functions, three different error handling approaches in the same module. PFS flags this as fragmentation.
|
|
42
|
+
|
|
43
|
+
### After — consolidated pattern
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
# services/payment_service.py
|
|
47
|
+
class PaymentError(Exception):
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
def process_payment(amount):
|
|
51
|
+
try:
|
|
52
|
+
validate(amount)
|
|
53
|
+
return {"status": "ok"}
|
|
54
|
+
except ValueError as e:
|
|
55
|
+
raise PaymentError(str(e)) from e
|
|
56
|
+
|
|
57
|
+
def refund_payment(transaction_id):
|
|
58
|
+
try:
|
|
59
|
+
result = lookup(transaction_id)
|
|
60
|
+
return True
|
|
61
|
+
except LookupError as e:
|
|
62
|
+
raise PaymentError(str(e)) from e
|
|
63
|
+
|
|
64
|
+
def cancel_payment(payment_id):
|
|
65
|
+
try:
|
|
66
|
+
result = lookup(payment_id)
|
|
67
|
+
return True
|
|
68
|
+
except LookupError as e:
|
|
69
|
+
raise PaymentError(str(e)) from e
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
One consistent error handling pattern across the module.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Why pattern fragmentation matters
|
|
77
|
+
|
|
78
|
+
- **Maintenance cost multiplies** — each variant requires separate understanding and testing.
|
|
79
|
+
- **Bugs hide in deviations** — the `except Exception: print(e)` variant silently swallows errors that the other variants would propagate.
|
|
80
|
+
- **Onboarding friction** — new contributors cannot determine which pattern is the intended standard.
|
|
81
|
+
- **AI generation amplifies fragmentation** — LLMs generate plausible but subtly different implementations each session, leading to variant accumulation over time.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## How the score is calculated
|
|
86
|
+
|
|
87
|
+
$$
|
|
88
|
+
\text{fragmentation\_score} = 1 - \frac{1}{\text{num\_variants}}
|
|
89
|
+
$$
|
|
90
|
+
|
|
91
|
+
| Variants | Score | Severity |
|
|
92
|
+
|----------|-------|----------|
|
|
93
|
+
| 2 | 0.50 | MEDIUM |
|
|
94
|
+
| 3 | 0.67 | MEDIUM |
|
|
95
|
+
| 4 | 0.75 | HIGH |
|
|
96
|
+
| 5+ | 0.80+ | HIGH |
|
|
97
|
+
|
|
98
|
+
**Spread boost:** When non-canonical instances spread across many files (> 2), a spread factor is applied:
|
|
99
|
+
|
|
100
|
+
$$
|
|
101
|
+
\text{spread\_factor} = \min\!\bigl(1.5,\; 1.0 + (\text{non\_canonical\_count} - 2) \times 0.04\bigr)
|
|
102
|
+
$$
|
|
103
|
+
|
|
104
|
+
The score is capped at 1.0.
|
|
105
|
+
|
|
106
|
+
**Severity thresholds:**
|
|
107
|
+
|
|
108
|
+
| Score range | Severity |
|
|
109
|
+
|-------------|----------|
|
|
110
|
+
| ≥ 0.7 | HIGH |
|
|
111
|
+
| ≥ 0.5 | MEDIUM |
|
|
112
|
+
| ≥ 0.3 | LOW |
|
|
113
|
+
| < 0.3 | INFO |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## How to fix PFS findings
|
|
118
|
+
|
|
119
|
+
1. **Identify the canonical variant** — PFS reports which variant is used most often (the "canonical" pattern). This is your consolidation target.
|
|
120
|
+
2. **Migrate deviating instances** — Refactor non-canonical usages to match the dominant pattern. PFS lists affected files and line numbers.
|
|
121
|
+
3. **Extract shared abstractions** — If variants serve genuinely different purposes, extract them into clearly named helpers or base classes.
|
|
122
|
+
4. **Add linting rules** — Once consolidated, add project-specific lint rules or code review checklists to prevent re-fragmentation.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Configuration
|
|
127
|
+
|
|
128
|
+
In `drift.yaml` or `pyproject.toml`:
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
# drift.yaml
|
|
132
|
+
weights:
|
|
133
|
+
pattern_fragmentation: 0.16 # default weight (0.0 to 1.0)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```toml
|
|
137
|
+
# pyproject.toml
|
|
138
|
+
[tool.drift.weights]
|
|
139
|
+
pattern_fragmentation = 0.16
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Set to `0.0` to disable PFS scoring entirely. Increase the weight to prioritize fragmentation findings.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Example output
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"signal_type": "pattern_fragmentation",
|
|
151
|
+
"severity": "high",
|
|
152
|
+
"score": 0.75,
|
|
153
|
+
"title": "error handling: 4 variants in services/",
|
|
154
|
+
"description": "4 error handling variants in services/ (6/10 use canonical pattern).\n - payment_service.py:14 (refund_payment)\n - payment_service.py:22 (cancel_payment)\n - order_service.py:8 (create_order)",
|
|
155
|
+
"fix": "Consolidate to the dominant pattern (6×). 4 deviations in: payment_service.py, order_service.py.",
|
|
156
|
+
"metadata": {
|
|
157
|
+
"category": "error handling",
|
|
158
|
+
"num_variants": 4,
|
|
159
|
+
"canonical_count": 6,
|
|
160
|
+
"total_instances": 10
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Detection details
|
|
168
|
+
|
|
169
|
+
PFS uses the following algorithm:
|
|
170
|
+
|
|
171
|
+
1. **Collect patterns** from all parsed files (AST-extracted pattern instances with category and fingerprint).
|
|
172
|
+
2. **Group by module** (parent directory) and pattern category.
|
|
173
|
+
3. **Normalize fingerprints** — async/sync variants are treated as equivalent to reduce false positives.
|
|
174
|
+
4. **Count unique variants** per module using fingerprint hashing.
|
|
175
|
+
5. **Identify the canonical variant** (most-used) and report deviations.
|
|
176
|
+
|
|
177
|
+
PFS is deterministic, AST-only, and does not require git history or LLM calls.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Related signals
|
|
182
|
+
|
|
183
|
+
- **MDS (Mutant Duplicates)** — detects near-identical functions. MDS finds copy-paste code; PFS finds the same *intent* implemented differently.
|
|
184
|
+
- **COD (Code Duplication)** — detects exact or near-exact code blocks. COD finds duplication; PFS finds inconsistency.
|
|
@@ -83,6 +83,8 @@ nav:
|
|
|
83
83
|
- API and Outputs: reference/api-outputs.md
|
|
84
84
|
- Negative Context: reference/negative-context.md
|
|
85
85
|
- Performance: reference/performance.md
|
|
86
|
+
- Signals:
|
|
87
|
+
- PFS (Pattern Fragmentation): reference/signals/pfs.md
|
|
86
88
|
- Product:
|
|
87
89
|
- Product Strategy: product-strategy.md
|
|
88
90
|
- Example Findings: product/example-findings.md
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "drift-analyzer"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.3.1"
|
|
8
8
|
description = "Deterministic architectural drift detection for AI-accelerated Python repositories through cross-file coherence analysis"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -312,6 +312,18 @@ def analyze_diff(
|
|
|
312
312
|
)
|
|
313
313
|
return analysis
|
|
314
314
|
|
|
315
|
+
# Map git-root-relative paths to repo-relative paths when repo_path is
|
|
316
|
+
# a subdirectory of the git root (#117).
|
|
317
|
+
from drift.ingestion.git_history import _git_repo_prefix
|
|
318
|
+
|
|
319
|
+
prefix = _git_repo_prefix(repo_path)
|
|
320
|
+
if prefix:
|
|
321
|
+
mapped: list[str] = []
|
|
322
|
+
for fp in changed_files:
|
|
323
|
+
if fp.startswith(prefix):
|
|
324
|
+
mapped.append(fp[len(prefix):])
|
|
325
|
+
changed_files = mapped
|
|
326
|
+
|
|
315
327
|
if not changed_files:
|
|
316
328
|
return RepoAnalysis(
|
|
317
329
|
repo_path=repo_path,
|
|
@@ -9,6 +9,7 @@ contract.
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
11
|
import json
|
|
12
|
+
from collections import Counter
|
|
12
13
|
from collections.abc import Callable
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
from types import SimpleNamespace
|
|
@@ -248,6 +249,28 @@ def _format_scan_response(
|
|
|
248
249
|
)
|
|
249
250
|
limited = ranked[:max_findings]
|
|
250
251
|
|
|
252
|
+
selected_signal_counts: Counter[str] = Counter(
|
|
253
|
+
signal_abbrev(f.signal_type) for f in selected_findings
|
|
254
|
+
)
|
|
255
|
+
included_signal_counts: Counter[str] = Counter(
|
|
256
|
+
signal_abbrev(f.signal_type) for f in limited
|
|
257
|
+
)
|
|
258
|
+
omitted_signals: list[dict[str, Any]] = []
|
|
259
|
+
for signal in sorted(selected_signal_counts.keys()):
|
|
260
|
+
total = selected_signal_counts[signal]
|
|
261
|
+
included = included_signal_counts.get(signal, 0)
|
|
262
|
+
omitted = max(total - included, 0)
|
|
263
|
+
if omitted:
|
|
264
|
+
omitted_signals.append({
|
|
265
|
+
"signal": signal,
|
|
266
|
+
"total": total,
|
|
267
|
+
"included": included,
|
|
268
|
+
"omitted": omitted,
|
|
269
|
+
"reason": "deprioritized_by_strategy",
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
omitted_signals.sort(key=lambda item: (-int(item["omitted"]), item["signal"]))
|
|
273
|
+
|
|
251
274
|
prioritized_for_fix_first, excluded_for_fix_first, context_counts = split_findings_by_context(
|
|
252
275
|
selected_findings,
|
|
253
276
|
config,
|
|
@@ -308,6 +331,17 @@ def _format_scan_response(
|
|
|
308
331
|
},
|
|
309
332
|
)
|
|
310
333
|
|
|
334
|
+
if omitted_signals:
|
|
335
|
+
result["selection_diagnostics"] = {
|
|
336
|
+
"strategy": strategy,
|
|
337
|
+
"max_findings": max_findings,
|
|
338
|
+
"signals_with_omitted_findings": omitted_signals,
|
|
339
|
+
"note": (
|
|
340
|
+
"Some findings are not returned due to max_findings truncation "
|
|
341
|
+
"and selection strategy."
|
|
342
|
+
),
|
|
343
|
+
}
|
|
344
|
+
|
|
311
345
|
# detailed mode adds fix_first, recommended_next_actions, agent_instruction
|
|
312
346
|
if detail == "detailed":
|
|
313
347
|
result["fix_first"] = _fix_first_concise(
|
|
@@ -523,13 +557,21 @@ def diff(
|
|
|
523
557
|
|
|
524
558
|
# Score comparison via trend context
|
|
525
559
|
score_after = diff_analysis.drift_score
|
|
526
|
-
score_before =
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
)
|
|
560
|
+
score_before: float = 0.0
|
|
561
|
+
if (
|
|
562
|
+
diff_analysis.trend is not None
|
|
563
|
+
and diff_analysis.trend.previous_score is not None
|
|
564
|
+
):
|
|
565
|
+
score_before = diff_analysis.trend.previous_score
|
|
566
|
+
has_trend_baseline = True
|
|
567
|
+
else:
|
|
568
|
+
has_trend_baseline = False
|
|
531
569
|
delta = round(score_after - score_before, 4)
|
|
532
570
|
|
|
571
|
+
# When no historical baseline exists, flag the score fields as
|
|
572
|
+
# synthetic so agents don't misinterpret zero as the repo baseline (#119).
|
|
573
|
+
score_basis = "historical" if has_trend_baseline else "zero_default"
|
|
574
|
+
|
|
533
575
|
from drift.output.json_output import _priority_class
|
|
534
576
|
|
|
535
577
|
drift_categories = sorted({_priority_class(f) for f in scoped_new}) if scoped_new else []
|
|
@@ -666,6 +708,7 @@ def diff(
|
|
|
666
708
|
score_before=round(score_before, 4),
|
|
667
709
|
score_after=round(score_after, 4),
|
|
668
710
|
delta=delta,
|
|
711
|
+
score_basis=score_basis,
|
|
669
712
|
score_regressed=delta > 0.0,
|
|
670
713
|
confidence=confidence,
|
|
671
714
|
diff_ref=diff_ref,
|
|
@@ -86,11 +86,12 @@ def _build_error_payload(
|
|
|
86
86
|
*,
|
|
87
87
|
detail: str | None = None,
|
|
88
88
|
hint: str | None = None,
|
|
89
|
+
suggested_action_override: str | None = None,
|
|
89
90
|
) -> dict[str, object]:
|
|
90
91
|
"""Build a v2.0 machine-readable error payload with recovery info."""
|
|
91
92
|
info = ERROR_REGISTRY.get(error_code)
|
|
92
93
|
recoverable = category == "user"
|
|
93
|
-
suggested_action = info.action if info else hint
|
|
94
|
+
suggested_action = suggested_action_override or (info.action if info else hint)
|
|
94
95
|
return {
|
|
95
96
|
"error": True,
|
|
96
97
|
"schema_version": "2.0",
|
|
@@ -214,6 +215,7 @@ def safe_main() -> None:
|
|
|
214
215
|
exc.exit_code,
|
|
215
216
|
detail=exc.detail,
|
|
216
217
|
hint=exc.hint,
|
|
218
|
+
suggested_action_override=exc.suggested_action,
|
|
217
219
|
),
|
|
218
220
|
)
|
|
219
221
|
else:
|