drift-analyzer 0.5.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.
- drift_analyzer-0.5.0/.git +1 -0
- drift_analyzer-0.5.0/.githooks/commit-msg +28 -0
- drift_analyzer-0.5.0/.githooks/pre-commit +25 -0
- drift_analyzer-0.5.0/.githooks/pre-push +68 -0
- drift_analyzer-0.5.0/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
- drift_analyzer-0.5.0/.github/ISSUE_TEMPLATE/config.yml +11 -0
- drift_analyzer-0.5.0/.github/ISSUE_TEMPLATE/false_positive.md +39 -0
- drift_analyzer-0.5.0/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- drift_analyzer-0.5.0/.github/PULL_REQUEST_TEMPLATE.md +35 -0
- drift_analyzer-0.5.0/.github/copilot-instructions.md +163 -0
- drift_analyzer-0.5.0/.github/instructions/drift-policy.instructions.md +57 -0
- drift_analyzer-0.5.0/.github/workflows/ci.yml +79 -0
- drift_analyzer-0.5.0/.github/workflows/docs.yml +48 -0
- drift_analyzer-0.5.0/.github/workflows/publish.yml +88 -0
- drift_analyzer-0.5.0/.github/workflows/validate-release.yml +33 -0
- drift_analyzer-0.5.0/.gitignore +27 -0
- drift_analyzer-0.5.0/.pre-commit-hooks.yaml +12 -0
- drift_analyzer-0.5.0/CHANGELOG.md +91 -0
- drift_analyzer-0.5.0/CODE_OF_CONDUCT.md +125 -0
- drift_analyzer-0.5.0/CONTRIBUTING.md +166 -0
- drift_analyzer-0.5.0/DEVELOPER.md +144 -0
- drift_analyzer-0.5.0/LICENSE +21 -0
- drift_analyzer-0.5.0/Makefile +68 -0
- drift_analyzer-0.5.0/OUTREACH.md +396 -0
- drift_analyzer-0.5.0/PKG-INFO +284 -0
- drift_analyzer-0.5.0/POLICY.md +238 -0
- drift_analyzer-0.5.0/README.md +224 -0
- drift_analyzer-0.5.0/SECURITY.md +45 -0
- drift_analyzer-0.5.0/STUDY.md +735 -0
- drift_analyzer-0.5.0/action.yml +101 -0
- drift_analyzer-0.5.0/docs/PRODUCT_STRATEGY.md +294 -0
- drift_analyzer-0.5.0/docs/adr/001-deterministic-analysis-pipeline.md +73 -0
- drift_analyzer-0.5.0/docs/adr/002-ast-fingerprinting-for-patterns.md +114 -0
- drift_analyzer-0.5.0/docs/adr/003-composite-scoring-model.md +97 -0
- drift_analyzer-0.5.0/docs/adr/004-subprocess-git-parsing.md +91 -0
- drift_analyzer-0.5.0/docs/language-roadmap.md +8 -0
- drift_analyzer-0.5.0/docs/language-support-matrix.md +9 -0
- drift_analyzer-0.5.0/docs/python-baseline.md +15 -0
- drift_analyzer-0.5.0/docs/python-rule-inventory.md +50 -0
- drift_analyzer-0.5.0/docs/tsjs-mvp-scope.md +18 -0
- drift_analyzer-0.5.0/docs-site/algorithms/deep-dive.md +64 -0
- drift_analyzer-0.5.0/docs-site/algorithms/scoring.md +50 -0
- drift_analyzer-0.5.0/docs-site/algorithms/signals.md +55 -0
- drift_analyzer-0.5.0/docs-site/benchmarking.md +69 -0
- drift_analyzer-0.5.0/docs-site/case-studies/django.md +26 -0
- drift_analyzer-0.5.0/docs-site/case-studies/fastapi.md +23 -0
- drift_analyzer-0.5.0/docs-site/case-studies/index.md +13 -0
- drift_analyzer-0.5.0/docs-site/case-studies/pydantic.md +19 -0
- drift_analyzer-0.5.0/docs-site/changelog.md +3 -0
- drift_analyzer-0.5.0/docs-site/contributing.md +26 -0
- drift_analyzer-0.5.0/docs-site/getting-started/configuration.md +68 -0
- drift_analyzer-0.5.0/docs-site/getting-started/finding-triage.md +126 -0
- drift_analyzer-0.5.0/docs-site/getting-started/installation.md +33 -0
- drift_analyzer-0.5.0/docs-site/getting-started/quickstart.md +52 -0
- drift_analyzer-0.5.0/docs-site/getting-started/team-rollout.md +94 -0
- drift_analyzer-0.5.0/docs-site/index.md +50 -0
- drift_analyzer-0.5.0/docs-site/product-strategy.md +56 -0
- drift_analyzer-0.5.0/docs-site/study.md +5 -0
- drift_analyzer-0.5.0/drift.example.yaml +72 -0
- drift_analyzer-0.5.0/examples/demo-project/README.md +20 -0
- drift_analyzer-0.5.0/examples/demo-project/api/__init__.py +0 -0
- drift_analyzer-0.5.0/examples/demo-project/api/routes.py +22 -0
- drift_analyzer-0.5.0/examples/demo-project/db/__init__.py +0 -0
- drift_analyzer-0.5.0/examples/demo-project/db/models.py +26 -0
- drift_analyzer-0.5.0/examples/demo-project/services/__init__.py +0 -0
- drift_analyzer-0.5.0/examples/demo-project/services/email_service.py +22 -0
- drift_analyzer-0.5.0/examples/demo-project/services/order_service.py +32 -0
- drift_analyzer-0.5.0/examples/demo-project/services/user_service.py +28 -0
- drift_analyzer-0.5.0/examples/demo-project/utils/__init__.py +0 -0
- drift_analyzer-0.5.0/examples/demo-project/utils/validators.py +43 -0
- drift_analyzer-0.5.0/examples/demo_fastapi.md +100 -0
- drift_analyzer-0.5.0/examples/drift-check.yml +33 -0
- drift_analyzer-0.5.0/mkdocs.yml +71 -0
- drift_analyzer-0.5.0/outreach/awesome_python_entry.md +24 -0
- drift_analyzer-0.5.0/outreach/awesome_static_analysis_entry.md +28 -0
- drift_analyzer-0.5.0/outreach/devto_outline.md +70 -0
- drift_analyzer-0.5.0/outreach/hn_post.md +37 -0
- drift_analyzer-0.5.0/outreach/reddit_experienced.md +44 -0
- drift_analyzer-0.5.0/outreach/reddit_python.md +55 -0
- drift_analyzer-0.5.0/outreach/twitter_thread.md +64 -0
- drift_analyzer-0.5.0/pyproject.toml +137 -0
- drift_analyzer-0.5.0/src/drift/__init__.py +18 -0
- drift_analyzer-0.5.0/src/drift/__main__.py +6 -0
- drift_analyzer-0.5.0/src/drift/analyzer.py +370 -0
- drift_analyzer-0.5.0/src/drift/analyzers/typescript/alias_resolver.py +129 -0
- drift_analyzer-0.5.0/src/drift/analyzers/typescript/barrel_resolver.py +131 -0
- drift_analyzer-0.5.0/src/drift/analyzers/typescript/import_graph.py +172 -0
- drift_analyzer-0.5.0/src/drift/analyzers/typescript/workspace_boundaries.py +116 -0
- drift_analyzer-0.5.0/src/drift/cache.py +209 -0
- drift_analyzer-0.5.0/src/drift/cli.py +80 -0
- drift_analyzer-0.5.0/src/drift/commands/__init__.py +16 -0
- drift_analyzer-0.5.0/src/drift/commands/analyze.py +142 -0
- drift_analyzer-0.5.0/src/drift/commands/badge.py +75 -0
- drift_analyzer-0.5.0/src/drift/commands/check.py +100 -0
- drift_analyzer-0.5.0/src/drift/commands/patterns.py +70 -0
- drift_analyzer-0.5.0/src/drift/commands/self_analyze.py +61 -0
- drift_analyzer-0.5.0/src/drift/commands/timeline.py +42 -0
- drift_analyzer-0.5.0/src/drift/commands/trend.py +125 -0
- drift_analyzer-0.5.0/src/drift/config.py +127 -0
- drift_analyzer-0.5.0/src/drift/embeddings.py +294 -0
- drift_analyzer-0.5.0/src/drift/ingestion/__init__.py +12 -0
- drift_analyzer-0.5.0/src/drift/ingestion/ast_parser.py +509 -0
- drift_analyzer-0.5.0/src/drift/ingestion/file_discovery.py +156 -0
- drift_analyzer-0.5.0/src/drift/ingestion/git_history.py +281 -0
- drift_analyzer-0.5.0/src/drift/ingestion/ts_parser.py +452 -0
- drift_analyzer-0.5.0/src/drift/models.py +240 -0
- drift_analyzer-0.5.0/src/drift/output/__init__.py +18 -0
- drift_analyzer-0.5.0/src/drift/output/json_output.py +147 -0
- drift_analyzer-0.5.0/src/drift/output/rich_output.py +489 -0
- drift_analyzer-0.5.0/src/drift/py.typed +0 -0
- drift_analyzer-0.5.0/src/drift/recommendations.py +268 -0
- drift_analyzer-0.5.0/src/drift/rules/tsjs/cross_package_import_ban.py +93 -0
- drift_analyzer-0.5.0/src/drift/scoring/__init__.py +17 -0
- drift_analyzer-0.5.0/src/drift/scoring/engine.py +269 -0
- drift_analyzer-0.5.0/src/drift/signals/__init__.py +21 -0
- drift_analyzer-0.5.0/src/drift/signals/architecture_violation.py +454 -0
- drift_analyzer-0.5.0/src/drift/signals/base.py +108 -0
- drift_analyzer-0.5.0/src/drift/signals/doc_impl_drift.py +492 -0
- drift_analyzer-0.5.0/src/drift/signals/explainability_deficit.py +198 -0
- drift_analyzer-0.5.0/src/drift/signals/mutant_duplicates.py +484 -0
- drift_analyzer-0.5.0/src/drift/signals/pattern_fragmentation.py +175 -0
- drift_analyzer-0.5.0/src/drift/signals/system_misalignment.py +217 -0
- drift_analyzer-0.5.0/src/drift/signals/temporal_volatility.py +171 -0
- drift_analyzer-0.5.0/src/drift/suppression.py +93 -0
- drift_analyzer-0.5.0/src/drift/timeline.py +293 -0
- drift_analyzer-0.5.0/tests/__init__.py +0 -0
- drift_analyzer-0.5.0/tests/conftest.py +149 -0
- drift_analyzer-0.5.0/tests/fixtures/__init__.py +0 -0
- drift_analyzer-0.5.0/tests/fixtures/ground_truth.py +1106 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_alias_resolution/src/app.ts +6 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_alias_resolution/src/core/logger.ts +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_alias_resolution/src/shared/config.ts +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_alias_resolution/tsconfig.json +9 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_barrel_resolution/src/app.ts +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_barrel_resolution/src/button.tsx +1 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_barrel_resolution/src/index.ts +2 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_graph_relative/app.ts +6 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_graph_relative/components/button.tsx +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_graph_relative/components/index.ts +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_graph_relative/lib/util.ts +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_rule_cross_package/negative/cross_package_import_ban.json +5 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_rule_cross_package/negative/package.json +7 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_rule_cross_package/negative/packages/app/src/main.ts +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_rule_cross_package/negative/packages/ui/src/button.ts +1 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_rule_cross_package/positive/cross_package_import_ban.json +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_rule_cross_package/positive/package.json +7 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_rule_cross_package/positive/packages/app/src/main.ts +3 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_rule_cross_package/positive/packages/ui/src/button.ts +1 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_workspace_boundaries/package.json +7 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_workspace_boundaries/packages/app/src/main.ts +1 -0
- drift_analyzer-0.5.0/tests/fixtures/tsjs_workspace_boundaries/packages/ui/src/button.tsx +1 -0
- drift_analyzer-0.5.0/tests/test_ablation.py +237 -0
- drift_analyzer-0.5.0/tests/test_architecture_violation.py +110 -0
- drift_analyzer-0.5.0/tests/test_ast_parser.py +112 -0
- drift_analyzer-0.5.0/tests/test_avs_enhanced.py +133 -0
- drift_analyzer-0.5.0/tests/test_avs_mutations.py +351 -0
- drift_analyzer-0.5.0/tests/test_badge_command.py +47 -0
- drift_analyzer-0.5.0/tests/test_cache_resilience.py +38 -0
- drift_analyzer-0.5.0/tests/test_ci_reality.py +296 -0
- drift_analyzer-0.5.0/tests/test_config.py +43 -0
- drift_analyzer-0.5.0/tests/test_dia_enhanced.py +254 -0
- drift_analyzer-0.5.0/tests/test_embeddings.py +106 -0
- drift_analyzer-0.5.0/tests/test_file_discovery.py +180 -0
- drift_analyzer-0.5.0/tests/test_fix_actionability.py +382 -0
- drift_analyzer-0.5.0/tests/test_git_history_edge_cases.py +228 -0
- drift_analyzer-0.5.0/tests/test_git_history_safety.py +94 -0
- drift_analyzer-0.5.0/tests/test_integration.py +168 -0
- drift_analyzer-0.5.0/tests/test_json_output.py +94 -0
- drift_analyzer-0.5.0/tests/test_mutant_duplicates_edge_cases.py +201 -0
- drift_analyzer-0.5.0/tests/test_output_golden.py +242 -0
- drift_analyzer-0.5.0/tests/test_pattern_fragmentation.py +147 -0
- drift_analyzer-0.5.0/tests/test_precision_recall.py +286 -0
- drift_analyzer-0.5.0/tests/test_recommendations.py +214 -0
- drift_analyzer-0.5.0/tests/test_recommendations_edge_cases.py +254 -0
- drift_analyzer-0.5.0/tests/test_scoring.py +218 -0
- drift_analyzer-0.5.0/tests/test_scoring_edge_cases.py +259 -0
- drift_analyzer-0.5.0/tests/test_self_command.py +31 -0
- drift_analyzer-0.5.0/tests/test_smoke_real_repos.py +316 -0
- drift_analyzer-0.5.0/tests/test_suppression.py +162 -0
- drift_analyzer-0.5.0/tests/test_timeline.py +158 -0
- drift_analyzer-0.5.0/tests/test_trend_chart.py +42 -0
- drift_analyzer-0.5.0/tests/test_tsjs_alias_resolution.py +18 -0
- drift_analyzer-0.5.0/tests/test_tsjs_barrel_resolution.py +20 -0
- drift_analyzer-0.5.0/tests/test_tsjs_import_graph_relative.py +28 -0
- drift_analyzer-0.5.0/tests/test_tsjs_rule_cross_package_import_ban.py +41 -0
- drift_analyzer-0.5.0/tests/test_tsjs_workspace_boundaries.py +44 -0
- drift_analyzer-0.5.0/tests/test_typescript_parser.py +161 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
gitdir: ../.git/modules/drift
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
# commit-msg hook — enforce Conventional Commits format
|
|
3
|
+
# Install with: git config core.hooksPath .githooks
|
|
4
|
+
#
|
|
5
|
+
# Allowed prefixes: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
|
|
6
|
+
# Format: type(scope): description OR type: description
|
|
7
|
+
|
|
8
|
+
commit_msg_file="$1"
|
|
9
|
+
commit_msg=$(head -1 "$commit_msg_file")
|
|
10
|
+
|
|
11
|
+
# Allow merge commits and fixup/squash commits
|
|
12
|
+
if echo "$commit_msg" | grep -qE "^(Merge|fixup!|squash!) "; then
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
pattern="^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .{1,}"
|
|
17
|
+
|
|
18
|
+
if ! echo "$commit_msg" | grep -qE "$pattern"; then
|
|
19
|
+
echo ">>> [commit-msg] ERROR: Commit message does not follow Conventional Commits."
|
|
20
|
+
echo ""
|
|
21
|
+
echo " Expected format: type(scope): description"
|
|
22
|
+
echo " Example: feat(scoring): add count dampening"
|
|
23
|
+
echo ""
|
|
24
|
+
echo " Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert"
|
|
25
|
+
echo ""
|
|
26
|
+
echo " Your message: $commit_msg"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
# pre-commit hook — block private paths + fast lint on staged files
|
|
3
|
+
# Install once with: git config core.hooksPath .githooks
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
blocked_pattern='^(tagesplanung/)'
|
|
7
|
+
|
|
8
|
+
staged_blocked=$(git diff --cached --name-only --diff-filter=ACMR | grep -E "$blocked_pattern" || true)
|
|
9
|
+
|
|
10
|
+
if [ -n "$staged_blocked" ]; then
|
|
11
|
+
echo ">>> [pre-commit] ERROR: Blocked paths detected in staged changes:"
|
|
12
|
+
echo "$staged_blocked"
|
|
13
|
+
echo ">>> [pre-commit] Remove these files from staging before commit."
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Fast lint on staged Python files (errors + import order only, <1s).
|
|
18
|
+
# Full lint + typecheck + tests run in pre-push.
|
|
19
|
+
staged_py=$(git diff --cached --name-only --diff-filter=ACMR -- '*.py' || true)
|
|
20
|
+
if [ -n "$staged_py" ]; then
|
|
21
|
+
if command -v ruff >/dev/null 2>&1; then
|
|
22
|
+
echo ">>> [pre-commit] Running ruff quick-check on staged files..."
|
|
23
|
+
echo "$staged_py" | xargs ruff check --select E,F,I --no-fix
|
|
24
|
+
fi
|
|
25
|
+
fi
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
# pre-push hook — mirrors CI checks (version-check + lint + typecheck + test + self-analysis)
|
|
3
|
+
# Install once with: git config core.hooksPath .githooks
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
# Block private/non-tool paths from being pushed.
|
|
7
|
+
blocked_pattern='^(tagesplanung/)'
|
|
8
|
+
|
|
9
|
+
reject_push_for_blocked_paths() {
|
|
10
|
+
local_ref="$1"
|
|
11
|
+
local_sha="$2"
|
|
12
|
+
remote_ref="$3"
|
|
13
|
+
remote_sha="$4"
|
|
14
|
+
|
|
15
|
+
# Deletion push (local ref removed) can be ignored here.
|
|
16
|
+
if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then
|
|
17
|
+
return 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then
|
|
21
|
+
commit_list=$(git rev-list "$local_sha" --not --all)
|
|
22
|
+
else
|
|
23
|
+
commit_list=$(git rev-list "$remote_sha..$local_sha")
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
for commit in $commit_list; do
|
|
27
|
+
blocked_hits=$(git diff-tree --no-commit-id --name-only --diff-filter=ACMR -r "$commit" | grep -E "$blocked_pattern" || true)
|
|
28
|
+
if [ -n "$blocked_hits" ]; then
|
|
29
|
+
echo ">>> [pre-push] ERROR: Blocked paths detected in commits for $local_ref -> $remote_ref"
|
|
30
|
+
echo "$blocked_hits"
|
|
31
|
+
echo ">>> [pre-push] Remove these files from the commit history before pushing."
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
done
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
while read local_ref local_sha remote_ref remote_sha; do
|
|
38
|
+
reject_push_for_blocked_paths "$local_ref" "$local_sha" "$remote_ref" "$remote_sha"
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
echo ">>> [pre-push] Starting local CI checks..."
|
|
42
|
+
|
|
43
|
+
# Unset git context variables that git injects when running hooks.
|
|
44
|
+
# Without this, tests that create git repos in tmp dirs inherit GIT_DIR
|
|
45
|
+
# from the parent repo and fail with exit 128 ("not a git repository").
|
|
46
|
+
unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_OBJECT_DIRECTORY GIT_COMMON_DIR
|
|
47
|
+
|
|
48
|
+
# 1. Version format (SemVer)
|
|
49
|
+
echo ">>> [1/5] Checking SemVer version..."
|
|
50
|
+
python scripts/check_version.py --check-semver
|
|
51
|
+
|
|
52
|
+
# 2. Lint
|
|
53
|
+
echo ">>> [2/5] Running ruff lint..."
|
|
54
|
+
ruff check src/ tests/
|
|
55
|
+
|
|
56
|
+
# 3. Type checking
|
|
57
|
+
echo ">>> [3/5] Running mypy..."
|
|
58
|
+
python -m mypy src/drift
|
|
59
|
+
|
|
60
|
+
# 4. Tests with coverage (exclude slow smoke tests that clone external repos)
|
|
61
|
+
echo ">>> [4/5] Running pytest + coverage (excl. smoke tests)..."
|
|
62
|
+
pytest -v --tb=short --cov --cov-report=term-missing --ignore=tests/test_smoke_real_repos.py
|
|
63
|
+
|
|
64
|
+
# 5. Self-analysis
|
|
65
|
+
echo ">>> [5/5] Running self-analysis..."
|
|
66
|
+
drift analyze --repo . --format json > /dev/null
|
|
67
|
+
|
|
68
|
+
echo ">>> [pre-push] All checks passed. Push continues."
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Bug Report"
|
|
3
|
+
about: "Something isn't working as expected"
|
|
4
|
+
title: "[Bug] "
|
|
5
|
+
labels: ["bug"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Describe the bug
|
|
10
|
+
|
|
11
|
+
A clear description of what the bug is.
|
|
12
|
+
|
|
13
|
+
## To reproduce
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Command you ran
|
|
17
|
+
drift analyze --repo /path/to/project
|
|
18
|
+
|
|
19
|
+
# Or: paste the relevant config
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Python version:** <!-- e.g. 3.12 -->
|
|
23
|
+
**drift-analyzer version:** <!-- drift --version -->
|
|
24
|
+
**OS:** <!-- e.g. Ubuntu 22.04, macOS 14, Windows 11 -->
|
|
25
|
+
|
|
26
|
+
## Expected behaviour
|
|
27
|
+
|
|
28
|
+
What you expected to happen.
|
|
29
|
+
|
|
30
|
+
## Actual behaviour
|
|
31
|
+
|
|
32
|
+
What actually happened. Include the full error output if applicable.
|
|
33
|
+
|
|
34
|
+
## Additional context
|
|
35
|
+
|
|
36
|
+
<!-- Stack trace, drift.yaml contents, anything else relevant -->
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Questions and usage help
|
|
4
|
+
url: https://github.com/sauremilk/drift/discussions
|
|
5
|
+
about: Please ask and answer general questions in Discussions.
|
|
6
|
+
- name: Documentation
|
|
7
|
+
url: https://sauremilk.github.io/drift/
|
|
8
|
+
about: Check the docs site for setup, configuration, and examples.
|
|
9
|
+
- name: Security report
|
|
10
|
+
url: https://github.com/sauremilk/drift/security/policy
|
|
11
|
+
about: Please report security vulnerabilities via the Security Policy page.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "False Positive / False Negative"
|
|
3
|
+
about: "Drift is flagging something incorrectly, or missing a real issue"
|
|
4
|
+
title: "[FP/FN] "
|
|
5
|
+
labels: ["signal-quality"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Signal affected
|
|
10
|
+
|
|
11
|
+
<!-- Which signal produced the false result? -->
|
|
12
|
+
|
|
13
|
+
- [ ] Pattern Fragmentation (PFS)
|
|
14
|
+
- [ ] Architecture Violations (AVS)
|
|
15
|
+
- [ ] Mutant Duplicates (MDS)
|
|
16
|
+
- [ ] Explainability Deficit (EDS)
|
|
17
|
+
- [ ] Temporal Volatility (TVS)
|
|
18
|
+
- [ ] System Misalignment (SMS)
|
|
19
|
+
|
|
20
|
+
## False positive or false negative?
|
|
21
|
+
|
|
22
|
+
- [ ] False positive — drift flagged something that isn't a real issue
|
|
23
|
+
- [ ] False negative — drift missed something that is a real issue
|
|
24
|
+
|
|
25
|
+
## Code example
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
# Paste the relevant code snippet here
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Why this is incorrect
|
|
32
|
+
|
|
33
|
+
Explain why drift's assessment is wrong in this case.
|
|
34
|
+
|
|
35
|
+
## drift.yaml config (if any)
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
|
|
39
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Feature Request"
|
|
3
|
+
about: "Suggest a new signal, output format, or improvement"
|
|
4
|
+
title: "[Feature] "
|
|
5
|
+
labels: ["enhancement"]
|
|
6
|
+
assignees: []
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem / motivation
|
|
10
|
+
|
|
11
|
+
What problem does this solve? What's the current limitation?
|
|
12
|
+
|
|
13
|
+
## Proposed solution
|
|
14
|
+
|
|
15
|
+
Describe the feature you'd like. Be as specific as possible.
|
|
16
|
+
|
|
17
|
+
## Alternatives considered
|
|
18
|
+
|
|
19
|
+
Any alternative approaches you've thought about?
|
|
20
|
+
|
|
21
|
+
## Would you like to contribute?
|
|
22
|
+
|
|
23
|
+
- [ ] Yes, I'd like to open a PR for this
|
|
24
|
+
- [ ] No, just requesting it
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What changed and why? -->
|
|
4
|
+
|
|
5
|
+
## Related issue
|
|
6
|
+
|
|
7
|
+
<!-- Use: Closes #123 / Fixes #123 / Related #123 -->
|
|
8
|
+
|
|
9
|
+
## Type of change
|
|
10
|
+
|
|
11
|
+
- [ ] Bug fix
|
|
12
|
+
- [ ] New feature
|
|
13
|
+
- [ ] Refactor
|
|
14
|
+
- [ ] Documentation
|
|
15
|
+
- [ ] Test-only change
|
|
16
|
+
- [ ] CI/Build change
|
|
17
|
+
|
|
18
|
+
## Validation
|
|
19
|
+
|
|
20
|
+
- [ ] `pytest` passes locally
|
|
21
|
+
- [ ] `ruff check src/ tests/` passes locally
|
|
22
|
+
- [ ] `mypy src/drift` passes locally
|
|
23
|
+
- [ ] `drift self` delta checked (target: <= +0.010)
|
|
24
|
+
- [ ] Added/updated tests for behavioral changes
|
|
25
|
+
|
|
26
|
+
## Checklist
|
|
27
|
+
|
|
28
|
+
- [ ] PR is focused on one concern
|
|
29
|
+
- [ ] Public docs updated (README/docs-site) if needed
|
|
30
|
+
- [ ] Changelog entry added if user-visible
|
|
31
|
+
- [ ] No unrelated files included
|
|
32
|
+
|
|
33
|
+
## Notes for reviewers
|
|
34
|
+
|
|
35
|
+
<!-- Anything that needs special attention during review -->
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Drift — Verbindliche Arbeitsgrundlage für alle Agenten
|
|
2
|
+
|
|
3
|
+
**Diese Datei ist für alle Copilot-Agenten, Coding-Agenten und KI-Assistenten im Drift-Workspace bindend.**
|
|
4
|
+
|
|
5
|
+
Die vollständige Policy befindet sich in:
|
|
6
|
+
`POLICY.md` (Workspace-Root)
|
|
7
|
+
|
|
8
|
+
Lies diese Datei **vor jeder Arbeit** vollständig, sofern sie nicht bereits im Kontext ist.
|
|
9
|
+
Die Policy ist ein Vertrag — keine Empfehlung, kein Vorschlag.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## PFLICHT-GATE: Zulässigkeitsprüfung vor jeder Aufgabe
|
|
14
|
+
|
|
15
|
+
**Vor jeder Antwort, die eine Änderung, ein Feature, eine Analyse oder eine Umsetzung enthält, MUSS der Agent dieses Gate sichtbar ausgeben:**
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
### Drift Policy Gate
|
|
19
|
+
- Aufgabe: [Kurzbeschreibung der Aufgabe in einem Satz]
|
|
20
|
+
- Zulassungskriterium erfüllt: [JA / NEIN] → [welches Kriterium: Unsicherheit / Signal / Glaubwürdigkeit / Handlungsfähigkeit / Trend / Einführbarkeit]
|
|
21
|
+
- Ausschlusskriterium ausgelöst: [JA / NEIN] → [falls JA: welches]
|
|
22
|
+
- Roadmap-Phase: [Phase 1 / 2 / 3 / 4] — blockiert durch höhere Phase: [JA / NEIN]
|
|
23
|
+
- Entscheidung: [ZULÄSSIG / ABBRUCH]
|
|
24
|
+
- Begründung: [ein Satz]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Bei Entscheidung ABBRUCH:** Keine weitere Umsetzung. Stattdessen: kurze Erklärung, welches Kriterium verletzt wird und was stattdessen priorisiert werden sollte.
|
|
28
|
+
|
|
29
|
+
**Das Gate darf nicht übersprungen werden.** Auch nicht bei kleinen Änderungen, Refactorings oder scheinbar offensichtlichen Aufgaben.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Nicht verhandelbare Grundregeln
|
|
34
|
+
|
|
35
|
+
### Was Drift ist
|
|
36
|
+
Drift ist ein statischer Analyzer zur Erkennung architektonischer Kohärenzprobleme.
|
|
37
|
+
Zweck: strukturelle Erosion erkennen, benennen, priorisieren, über Zeit vergleichbar machen.
|
|
38
|
+
|
|
39
|
+
### Was Drift nicht ist
|
|
40
|
+
- Drift ist kein Tool, das lediglich Probleme auflistet.
|
|
41
|
+
- Drift erzeugt keine dekorativen Ergebnisse.
|
|
42
|
+
- Drift priorisiert keine Ergebnisse ohne realen Zusammenhang mit struktureller Kohärenz.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Absolute Ausschlusskriterien für neue Arbeit
|
|
47
|
+
|
|
48
|
+
**Keine Aufgabe darf begonnen werden**, die ausschließlich folgendes erzeugt:
|
|
49
|
+
- mehr Ausgabe ohne besseren Erkenntniswert
|
|
50
|
+
- mehr Komplexität ohne klaren Nutzen
|
|
51
|
+
- mehr Oberfläche ohne bessere Analyse
|
|
52
|
+
- mehr Analyse ohne Validierung des Ergebnisses
|
|
53
|
+
- mehr technische Ausarbeitung ohne Beitrag zur Produktwirkung
|
|
54
|
+
- einen Nutzen, der nicht eindeutig benennbar ist
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Priorisierungsformel (Policy §6)
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
Priorität = (Unsicherheit × Schaden × Nutzbarkeit) / Aufwand
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Bei konkurrierenden Vorhaben gilt diese feste Reihenfolge:
|
|
65
|
+
1. Glaubwürdigkeit erhalten
|
|
66
|
+
2. Signalpräzision verbessern
|
|
67
|
+
3. Verständlichkeit der Befunde verbessern
|
|
68
|
+
4. False Positives / False Negatives reduzieren
|
|
69
|
+
5. Einführbarkeit verbessern
|
|
70
|
+
6. Trendanalyse verbessern
|
|
71
|
+
7. Zusätzliche Features, Formate, Komfortmerkmale
|
|
72
|
+
|
|
73
|
+
**Eine niedrigere Stufe verdrängt niemals eine höhere.**
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Qualitätsanforderungen an jeden Befund (Policy §13)
|
|
78
|
+
|
|
79
|
+
Jeder Befund muss besitzen:
|
|
80
|
+
- technische Nachvollziehbarkeit
|
|
81
|
+
- Reproduzierbarkeit
|
|
82
|
+
- eindeutige Zuordnung zu einer Ursache
|
|
83
|
+
- klare Benennung der betroffenen Stelle
|
|
84
|
+
- nachvollziehbare Begründung
|
|
85
|
+
- erkennbare nächste Maßnahme
|
|
86
|
+
|
|
87
|
+
Ein Befund ohne klare Begründung ist **unzulässig**.
|
|
88
|
+
Ein Befund ohne mögliche nächste Maßnahme ist **unvollständig**.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Zulassungskriterien für neue Arbeit (Policy §8)
|
|
93
|
+
|
|
94
|
+
Eine Aufgabe darf nur begonnen werden, wenn sie mindestens eines erfüllt:
|
|
95
|
+
- reduziert eine zentrale Unsicherheit
|
|
96
|
+
- verbessert die Signalqualität
|
|
97
|
+
- erhöht die Glaubwürdigkeit
|
|
98
|
+
- erhöht die Handlungsfähigkeit
|
|
99
|
+
- verbessert die Trendfähigkeit
|
|
100
|
+
- erleichtert die Einführbarkeit
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Roadmap-Phasen-Hierarchie (Policy §14)
|
|
105
|
+
|
|
106
|
+
**Phase 1 — Vertrauen** (Vorrang vor allem anderen):
|
|
107
|
+
Nachvollziehbarkeit → Reproduzierbarkeit → Fehlalarmreduktion → Erklärbarkeit
|
|
108
|
+
|
|
109
|
+
**Phase 2 — Relevanz** → **Phase 3 — Einführbarkeit** → **Phase 4 — Skalierung**
|
|
110
|
+
|
|
111
|
+
Phase 4 verdrängt niemals Phase 1.
|
|
112
|
+
Skalierungsmaßnahmen ohne gesichertes Vertrauen sind **nachrangig**.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Entscheidungsregel bei Unklarheit (Policy §16)
|
|
117
|
+
|
|
118
|
+
> Wähle die Option, die die größte Unsicherheit reduziert.
|
|
119
|
+
> Sind mehrere gleich gut: höchsten Erkenntniswert pro Aufwandseinheit.
|
|
120
|
+
> Ist keine Option hinreichend begründet: **keine Umsetzung**.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Schlussbestimmung
|
|
125
|
+
|
|
126
|
+
Diese Policy ist verbindlich (Policy §18).
|
|
127
|
+
Abweichungen sind nur zulässig wenn: dokumentiert, begründet, als Ausnahme gekennzeichnet.
|
|
128
|
+
Im Zweifel gilt: geringerer Interpretationsspielraum, höherer Erkenntniswert.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Schnellreferenz für Agenten
|
|
133
|
+
|
|
134
|
+
Vollständiger Developer Guide: **[DEVELOPER.md](../DEVELOPER.md)**
|
|
135
|
+
|
|
136
|
+
### Architektur (Datenfluss)
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
ingestion/ → signals/ → scoring/ → output/
|
|
140
|
+
AST + Git 7 Detektoren Score+Severity Rich/JSON/SARIF
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Wichtigste Kommandos
|
|
144
|
+
|
|
145
|
+
| Aufgabe | Befehl |
|
|
146
|
+
|---------|--------|
|
|
147
|
+
| Dev-Setup | `make install` |
|
|
148
|
+
| Alle Checks | `make check` |
|
|
149
|
+
| Nur Tests (schnell) | `make test-fast` |
|
|
150
|
+
| Lint + Autofix | `make lint-fix` |
|
|
151
|
+
| CI lokal replizieren | `make ci` |
|
|
152
|
+
| Selbstanalyse | `make self` |
|
|
153
|
+
|
|
154
|
+
### Verzeichnisstruktur
|
|
155
|
+
|
|
156
|
+
| Pfad | Inhalt |
|
|
157
|
+
|------|--------|
|
|
158
|
+
| `src/drift/signals/` | 7 Signale (PFS, AVS, MDS, EDS, TVS, SMS, DIA) |
|
|
159
|
+
| `src/drift/ingestion/` | AST-Parsing, Git-History, File-Discovery |
|
|
160
|
+
| `src/drift/scoring/` | Composite-Score, Module-Scores, Severity |
|
|
161
|
+
| `src/drift/output/` | Rich-Terminal, JSON, SARIF |
|
|
162
|
+
| `src/drift/commands/` | Click-CLI-Subcommands |
|
|
163
|
+
| `tests/` | 27+ Testdateien, conftest.py mit tmp_repo Fixture |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**"
|
|
3
|
+
description: "Drift Policy — Bindende Arbeitsregeln für alle Dateien. MUSS gelesen werden bevor Änderungen an Drift-Code, Analyselogik, Ergebnisformaten oder Features vorgenommen werden."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Drift — Policy (bindend für alle Dateioperationen)
|
|
7
|
+
|
|
8
|
+
Vollständige Policy: `POLICY.md` im Workspace-Root.
|
|
9
|
+
Kurzfassung der Kern-Verbote und Anforderungen:
|
|
10
|
+
|
|
11
|
+
## PFLICHT-GATE: Zulässigkeitsprüfung — immer zuerst ausführen und ausgeben
|
|
12
|
+
|
|
13
|
+
Vor jeder Umsetzung dieses Format sichtbar ausgeben:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
### Drift Policy Gate
|
|
17
|
+
- Aufgabe: [Kurzbeschreibung in einem Satz]
|
|
18
|
+
- Zulassungskriterium erfüllt: [JA / NEIN] → [Unsicherheit / Signal / Glaubwürdigkeit / Handlungsfähigkeit / Trend / Einführbarkeit]
|
|
19
|
+
- Ausschlusskriterium ausgelöst: [JA / NEIN] → [falls JA: welches]
|
|
20
|
+
- Roadmap-Phase: [1 / 2 / 3 / 4] — blockiert durch höhere Phase: [JA / NEIN]
|
|
21
|
+
- Entscheidung: [ZULÄSSIG / ABBRUCH]
|
|
22
|
+
- Begründung: [ein Satz]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Bei **ABBRUCH**: keine Umsetzung, stattdessen Erklärung + Gegenvorschlag.
|
|
26
|
+
Das Gate darf **niemals übersprungen** werden.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Vor jeder Änderung prüfen
|
|
31
|
+
|
|
32
|
+
**Ist die Aufgabe zulässig?** Sie muss mindestens eines erfüllen:
|
|
33
|
+
- reduziert eine zentrale Unsicherheit
|
|
34
|
+
- verbessert die Signalqualität oder Glaubwürdigkeit
|
|
35
|
+
- erhöht die Handlungsfähigkeit
|
|
36
|
+
- verbessert Trendfähigkeit oder Einführbarkeit
|
|
37
|
+
|
|
38
|
+
**Ist die Aufgabe unzulässig?** Sofort abbrechen, wenn sie ausschließlich erzeugt:
|
|
39
|
+
- mehr Ausgabe ohne Erkenntniswert
|
|
40
|
+
- mehr Komplexität ohne klaren Nutzen
|
|
41
|
+
- ein Feature, dessen Beitrag nicht klar benennbar ist
|
|
42
|
+
|
|
43
|
+
## Pflicht bei Code-Änderungen an Analyseergebnissen
|
|
44
|
+
|
|
45
|
+
Jedes Ergebnis/Befund benötigt zwingend:
|
|
46
|
+
1. technische Nachvollziehbarkeit
|
|
47
|
+
2. Reproduzierbarkeit
|
|
48
|
+
3. eindeutige Ursachenzuordnung
|
|
49
|
+
4. nachvollziehbare Begründung
|
|
50
|
+
5. erkennbare nächste Maßnahme
|
|
51
|
+
|
|
52
|
+
Fehlt eines dieser fünf Elemente → Änderung ist **unzulässig**.
|
|
53
|
+
|
|
54
|
+
## Prioritätsbindung
|
|
55
|
+
|
|
56
|
+
Reihenfolge ist nicht verhandelbar:
|
|
57
|
+
`Glaubwürdigkeit > Signalpräzision > Verständlichkeit > FP/FN-Reduktion > Einführbarkeit > Trend > Features`
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
version-check:
|
|
12
|
+
name: Version format check
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
|
|
22
|
+
- name: Validate pyproject.toml version is SemVer
|
|
23
|
+
# Ensures the version in pyproject.toml is always MAJOR.MINOR.PATCH –
|
|
24
|
+
# a merge to master with an invalid or missing version is blocked.
|
|
25
|
+
run: python scripts/check_version.py --check-semver
|
|
26
|
+
|
|
27
|
+
test:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
needs: version-check
|
|
30
|
+
strategy:
|
|
31
|
+
matrix:
|
|
32
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
with:
|
|
37
|
+
fetch-depth: 0 # Full history for git-based signals
|
|
38
|
+
|
|
39
|
+
- uses: actions/setup-python@v5
|
|
40
|
+
with:
|
|
41
|
+
python-version: ${{ matrix.python-version }}
|
|
42
|
+
|
|
43
|
+
- name: Install dependencies
|
|
44
|
+
run: pip install -e ".[dev]"
|
|
45
|
+
|
|
46
|
+
- name: Lint with ruff
|
|
47
|
+
run: ruff check src/ tests/
|
|
48
|
+
|
|
49
|
+
- name: Type-check with mypy
|
|
50
|
+
run: python -m mypy src/drift
|
|
51
|
+
|
|
52
|
+
- name: Run tests with coverage
|
|
53
|
+
run: pytest -v --tb=short --cov=drift --cov-report=xml --cov-report=term-missing -m "not slow"
|
|
54
|
+
|
|
55
|
+
- name: Upload coverage to Codecov
|
|
56
|
+
if: matrix.python-version == '3.12'
|
|
57
|
+
uses: codecov/codecov-action@v4
|
|
58
|
+
with:
|
|
59
|
+
files: coverage.xml
|
|
60
|
+
fail_ci_if_error: false
|
|
61
|
+
env:
|
|
62
|
+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
63
|
+
|
|
64
|
+
- name: Self-analysis
|
|
65
|
+
run: drift analyze --repo . --format json > /dev/null
|
|
66
|
+
|
|
67
|
+
- name: Drift self-check (score gate)
|
|
68
|
+
if: matrix.python-version == '3.12'
|
|
69
|
+
run: |
|
|
70
|
+
drift self --format json > drift_score.json
|
|
71
|
+
python -c "
|
|
72
|
+
import json, sys
|
|
73
|
+
data = json.load(open('drift_score.json'))
|
|
74
|
+
score = data['drift_score']
|
|
75
|
+
if score > 0.47:
|
|
76
|
+
print(f'FAIL: drift self score {score:.3f} exceeds threshold 0.47')
|
|
77
|
+
sys.exit(1)
|
|
78
|
+
print(f'OK: drift self score {score:.3f} (threshold 0.47)')
|
|
79
|
+
"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: Deploy Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
paths:
|
|
7
|
+
- "docs-site/**"
|
|
8
|
+
- "mkdocs.yml"
|
|
9
|
+
- ".github/workflows/docs.yml"
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
pages: write
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: pages
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
build:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- uses: actions/setup-python@v5
|
|
27
|
+
with:
|
|
28
|
+
python-version: "3.12"
|
|
29
|
+
|
|
30
|
+
- name: Install MkDocs
|
|
31
|
+
run: pip install mkdocs-material
|
|
32
|
+
|
|
33
|
+
- name: Build documentation
|
|
34
|
+
run: mkdocs build --strict
|
|
35
|
+
|
|
36
|
+
- uses: actions/upload-pages-artifact@v3
|
|
37
|
+
with:
|
|
38
|
+
path: site/
|
|
39
|
+
|
|
40
|
+
deploy:
|
|
41
|
+
needs: build
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
environment:
|
|
44
|
+
name: github-pages
|
|
45
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
46
|
+
steps:
|
|
47
|
+
- id: deployment
|
|
48
|
+
uses: actions/deploy-pages@v4
|