lurebench 0.9.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.
- lurebench-0.9.1/.editorconfig +18 -0
- lurebench-0.9.1/.env.example +18 -0
- lurebench-0.9.1/.github/DISCUSSION_TEMPLATE/q-a.yml +34 -0
- lurebench-0.9.1/.github/ISSUE_TEMPLATE/benchmark_submission.yml +63 -0
- lurebench-0.9.1/.github/ISSUE_TEMPLATE/bug_report.yml +38 -0
- lurebench-0.9.1/.github/ISSUE_TEMPLATE/config.yml +8 -0
- lurebench-0.9.1/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- lurebench-0.9.1/.github/dependabot.yml +25 -0
- lurebench-0.9.1/.github/workflows/ci.yml +36 -0
- lurebench-0.9.1/.github/workflows/codeql.yml +37 -0
- lurebench-0.9.1/.github/workflows/release.yml +72 -0
- lurebench-0.9.1/.github/workflows/scorecard.yml +38 -0
- lurebench-0.9.1/.gitignore +29 -0
- lurebench-0.9.1/.pre-commit-config.yaml +18 -0
- lurebench-0.9.1/.zenodo.json +35 -0
- lurebench-0.9.1/CHANGELOG.md +383 -0
- lurebench-0.9.1/CITATION.cff +31 -0
- lurebench-0.9.1/CODE_OF_CONDUCT.md +117 -0
- lurebench-0.9.1/CONTRIBUTING.md +46 -0
- lurebench-0.9.1/DATA.md +48 -0
- lurebench-0.9.1/LICENSE +202 -0
- lurebench-0.9.1/PKG-INFO +300 -0
- lurebench-0.9.1/README.md +243 -0
- lurebench-0.9.1/SECURITY.md +85 -0
- lurebench-0.9.1/data/samples/lures.jsonl +18 -0
- lurebench-0.9.1/docs/DATASHEET.md +101 -0
- lurebench-0.9.1/docs/RELEASING.md +33 -0
- lurebench-0.9.1/docs/RISK_CONTROL.md +136 -0
- lurebench-0.9.1/docs/SHARD_SPEC.md +107 -0
- lurebench-0.9.1/docs/VALIDITY.md +119 -0
- lurebench-0.9.1/docs/adaptive_robustness.md +19 -0
- lurebench-0.9.1/docs/adding-a-detector.md +68 -0
- lurebench-0.9.1/docs/adversarial-robustness.md +129 -0
- lurebench-0.9.1/docs/assets/brand-hero.svg +44 -0
- lurebench-0.9.1/docs/assets/carousel/lurebench-carousel.pdf +0 -0
- lurebench-0.9.1/docs/assets/carousel/slide1.png +0 -0
- lurebench-0.9.1/docs/assets/carousel/slide2.png +0 -0
- lurebench-0.9.1/docs/assets/carousel/slide3.png +0 -0
- lurebench-0.9.1/docs/assets/carousel/slide4.png +0 -0
- lurebench-0.9.1/docs/assets/carousel/slide5.png +0 -0
- lurebench-0.9.1/docs/assets/carousel/slide6.png +0 -0
- lurebench-0.9.1/docs/assets/carousel/slide7.png +0 -0
- lurebench-0.9.1/docs/assets/detection.png +0 -0
- lurebench-0.9.1/docs/assets/detection.svg +40 -0
- lurebench-0.9.1/docs/assets/llm-multilingual.svg +2203 -0
- lurebench-0.9.1/docs/assets/llm-robustness.svg +1798 -0
- lurebench-0.9.1/docs/assets/lurebench-atlas.gif +0 -0
- lurebench-0.9.1/docs/assets/lurebench-atlas.png +0 -0
- lurebench-0.9.1/docs/assets/multilingual.svg +70 -0
- lurebench-0.9.1/docs/assets/provenance.png +0 -0
- lurebench-0.9.1/docs/assets/provenance.svg +37 -0
- lurebench-0.9.1/docs/assets/robustness.svg +40 -0
- lurebench-0.9.1/docs/cross_generator_findings.md +67 -0
- lurebench-0.9.1/docs/leaderboard.md +33 -0
- lurebench-0.9.1/docs/llm-detector.md +100 -0
- lurebench-0.9.1/docs/multilingual.md +118 -0
- lurebench-0.9.1/docs/multilingual_llm.md +20 -0
- lurebench-0.9.1/docs/provenance_llm.md +20 -0
- lurebench-0.9.1/docs/provenance_results.md +75 -0
- lurebench-0.9.1/docs/shard_manifests/core.json +45 -0
- lurebench-0.9.1/docs/shard_manifests/phishtext.json +24 -0
- lurebench-0.9.1/docs/sources.md +52 -0
- lurebench-0.9.1/docs/taxonomy.md +106 -0
- lurebench-0.9.1/lurebench/__init__.py +45 -0
- lurebench-0.9.1/lurebench/attacks/__init__.py +37 -0
- lurebench-0.9.1/lurebench/attacks/base.py +28 -0
- lurebench-0.9.1/lurebench/attacks/llm.py +172 -0
- lurebench-0.9.1/lurebench/attacks/perturb.py +100 -0
- lurebench-0.9.1/lurebench/audit.py +116 -0
- lurebench-0.9.1/lurebench/calibration.py +422 -0
- lurebench-0.9.1/lurebench/cli.py +676 -0
- lurebench-0.9.1/lurebench/corpus.py +148 -0
- lurebench-0.9.1/lurebench/crossgen.py +119 -0
- lurebench-0.9.1/lurebench/data.py +37 -0
- lurebench-0.9.1/lurebench/detectors/__init__.py +59 -0
- lurebench-0.9.1/lurebench/detectors/base.py +34 -0
- lurebench-0.9.1/lurebench/detectors/binoculars.py +43 -0
- lurebench-0.9.1/lurebench/detectors/cache.py +118 -0
- lurebench-0.9.1/lurebench/detectors/heuristic.py +73 -0
- lurebench-0.9.1/lurebench/detectors/llama_guard.py +52 -0
- lurebench-0.9.1/lurebench/detectors/llm.py +165 -0
- lurebench-0.9.1/lurebench/detectors/moderation.py +45 -0
- lurebench-0.9.1/lurebench/detectors/tfidf.py +116 -0
- lurebench-0.9.1/lurebench/diskcache.py +105 -0
- lurebench-0.9.1/lurebench/generate/__init__.py +99 -0
- lurebench-0.9.1/lurebench/generate/anthropic_generator.py +62 -0
- lurebench-0.9.1/lurebench/generate/base.py +242 -0
- lurebench-0.9.1/lurebench/generate/completion_cache.py +72 -0
- lurebench-0.9.1/lurebench/generate/openai_compat.py +267 -0
- lurebench-0.9.1/lurebench/generate/pipeline.py +140 -0
- lurebench-0.9.1/lurebench/generate/template.py +66 -0
- lurebench-0.9.1/lurebench/harness.py +135 -0
- lurebench-0.9.1/lurebench/hub.py +104 -0
- lurebench-0.9.1/lurebench/ingest/__init__.py +39 -0
- lurebench-0.9.1/lurebench/ingest/base.py +101 -0
- lurebench-0.9.1/lurebench/ingest/ephishgen.py +52 -0
- lurebench-0.9.1/lurebench/ingest/generic.py +107 -0
- lurebench-0.9.1/lurebench/leaderboard.py +233 -0
- lurebench-0.9.1/lurebench/manifest.py +92 -0
- lurebench-0.9.1/lurebench/metrics.py +162 -0
- lurebench-0.9.1/lurebench/multilingual.py +152 -0
- lurebench-0.9.1/lurebench/robustness.py +98 -0
- lurebench-0.9.1/lurebench/schema.py +107 -0
- lurebench-0.9.1/lurebench/splits.py +36 -0
- lurebench-0.9.1/lurebench/stix.py +189 -0
- lurebench-0.9.1/lurebench/taxonomy.py +227 -0
- lurebench-0.9.1/paper.bib +57 -0
- lurebench-0.9.1/paper.md +115 -0
- lurebench-0.9.1/pyproject.toml +75 -0
- lurebench-0.9.1/scripts/adaptive_robustness.py +313 -0
- lurebench-0.9.1/scripts/build_multilingual_pilot.py +115 -0
- lurebench-0.9.1/scripts/build_paired_provenance.py +72 -0
- lurebench-0.9.1/scripts/build_phishtext_shard.py +95 -0
- lurebench-0.9.1/scripts/eval_cross_generator.py +59 -0
- lurebench-0.9.1/scripts/eval_paired_provenance.py +93 -0
- lurebench-0.9.1/scripts/fix_duplicate_ids.py +150 -0
- lurebench-0.9.1/scripts/llm_experiments.py +296 -0
- lurebench-0.9.1/scripts/make_carousel.py +261 -0
- lurebench-0.9.1/scripts/make_charts.py +144 -0
- lurebench-0.9.1/scripts/make_denominator_video.py +266 -0
- lurebench-0.9.1/scripts/make_llm_comparison_chart.py +94 -0
- lurebench-0.9.1/scripts/make_llm_robustness_chart.py +88 -0
- lurebench-0.9.1/scripts/make_llm_video.py +210 -0
- lurebench-0.9.1/scripts/make_multilingual_chart.py +116 -0
- lurebench-0.9.1/scripts/make_multilingual_video.py +186 -0
- lurebench-0.9.1/scripts/make_story_video.py +298 -0
- lurebench-0.9.1/scripts/make_story_video_dark.py +279 -0
- lurebench-0.9.1/scripts/pilot_paired_provenance.py +83 -0
- lurebench-0.9.1/scripts/score_llm_multilingual.py +102 -0
- lurebench-0.9.1/scripts/score_llm_robustness.py +138 -0
- lurebench-0.9.1/scripts/verify_release.py +61 -0
- lurebench-0.9.1/spec/decision-policy-v2.schema.json +72 -0
- lurebench-0.9.1/tests/test_adaptive_attack.py +135 -0
- lurebench-0.9.1/tests/test_attacks.py +64 -0
- lurebench-0.9.1/tests/test_audit.py +31 -0
- lurebench-0.9.1/tests/test_calibration.py +184 -0
- lurebench-0.9.1/tests/test_completion_cache.py +68 -0
- lurebench-0.9.1/tests/test_corpus.py +140 -0
- lurebench-0.9.1/tests/test_crossgen.py +68 -0
- lurebench-0.9.1/tests/test_detector_cache.py +135 -0
- lurebench-0.9.1/tests/test_generate.py +263 -0
- lurebench-0.9.1/tests/test_harness.py +88 -0
- lurebench-0.9.1/tests/test_ingest.py +92 -0
- lurebench-0.9.1/tests/test_leaderboard.py +176 -0
- lurebench-0.9.1/tests/test_llm_detector.py +197 -0
- lurebench-0.9.1/tests/test_metrics.py +54 -0
- lurebench-0.9.1/tests/test_multilingual.py +123 -0
- lurebench-0.9.1/tests/test_record_ids.py +133 -0
- lurebench-0.9.1/tests/test_robustness.py +84 -0
- lurebench-0.9.1/tests/test_splits.py +29 -0
- lurebench-0.9.1/tests/test_stix.py +125 -0
- lurebench-0.9.1/tests/test_taxonomy.py +47 -0
- lurebench-0.9.1/tests/test_tfidf.py +52 -0
- lurebench-0.9.1/uv.lock +2863 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
insert_final_newline = true
|
|
7
|
+
trim_trailing_whitespace = true
|
|
8
|
+
indent_style = space
|
|
9
|
+
|
|
10
|
+
[*.py]
|
|
11
|
+
indent_size = 4
|
|
12
|
+
max_line_length = 100
|
|
13
|
+
|
|
14
|
+
[*.{yml,yaml,json,toml,cff}]
|
|
15
|
+
indent_size = 2
|
|
16
|
+
|
|
17
|
+
[*.md]
|
|
18
|
+
trim_trailing_whitespace = false
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# LureBench provider keys — copy to `.env` and fill in. `.env` is gitignored.
|
|
2
|
+
# Only fill the providers you have keys for; the rest can stay blank.
|
|
3
|
+
# Load into a shell with: set -a; source .env; set +a
|
|
4
|
+
|
|
5
|
+
# DeepSeek — https://platform.deepseek.com
|
|
6
|
+
DEEPSEEK_API_KEY=
|
|
7
|
+
|
|
8
|
+
# Qwen (Alibaba DashScope) — https://dashscope.console.aliyun.com
|
|
9
|
+
DASHSCOPE_API_KEY=
|
|
10
|
+
|
|
11
|
+
# GLM (Zhipu / Z.ai) — https://open.bigmodel.cn or https://z.ai
|
|
12
|
+
ZHIPUAI_API_KEY=
|
|
13
|
+
|
|
14
|
+
# Kimi (Moonshot) — https://platform.moonshot.ai
|
|
15
|
+
MOONSHOT_API_KEY=
|
|
16
|
+
|
|
17
|
+
# Mistral — https://console.mistral.ai
|
|
18
|
+
MISTRAL_API_KEY=
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
title: "[Question] "
|
|
2
|
+
body:
|
|
3
|
+
- type: dropdown
|
|
4
|
+
id: area
|
|
5
|
+
attributes:
|
|
6
|
+
label: Area
|
|
7
|
+
options:
|
|
8
|
+
- Installation or CLI
|
|
9
|
+
- Dataset or licensing
|
|
10
|
+
- Evaluation methodology
|
|
11
|
+
- Adding a detector
|
|
12
|
+
- Reproducing a published result
|
|
13
|
+
- Other
|
|
14
|
+
validations:
|
|
15
|
+
required: true
|
|
16
|
+
- type: input
|
|
17
|
+
id: version
|
|
18
|
+
attributes:
|
|
19
|
+
label: Version or commit
|
|
20
|
+
placeholder: v0.9.1 or a commit SHA
|
|
21
|
+
validations:
|
|
22
|
+
required: true
|
|
23
|
+
- type: textarea
|
|
24
|
+
id: question
|
|
25
|
+
attributes:
|
|
26
|
+
label: Question
|
|
27
|
+
description: Include the outcome you need and enough context to reproduce the situation.
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
- type: textarea
|
|
31
|
+
id: attempted
|
|
32
|
+
attributes:
|
|
33
|
+
label: What have you tried?
|
|
34
|
+
description: Redact provider keys, personal data, and live malicious infrastructure.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Benchmark submission
|
|
2
|
+
description: Propose a detector or published result for reproducible evaluation.
|
|
3
|
+
title: "[Benchmark]: "
|
|
4
|
+
labels: [benchmark-submission]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for contributing a result. Do not include live credentials, working
|
|
10
|
+
malicious links, private messages, or data you are not allowed to share.
|
|
11
|
+
- type: input
|
|
12
|
+
id: detector
|
|
13
|
+
attributes:
|
|
14
|
+
label: Detector and version
|
|
15
|
+
placeholder: example-detector 1.2.0
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: dropdown
|
|
19
|
+
id: task
|
|
20
|
+
attributes:
|
|
21
|
+
label: Evaluation task
|
|
22
|
+
options:
|
|
23
|
+
- Fraud detection
|
|
24
|
+
- AI-authorship provenance
|
|
25
|
+
- Adversarial robustness
|
|
26
|
+
- Multilingual generalization
|
|
27
|
+
- Calibration or risk control
|
|
28
|
+
- Other
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
- type: textarea
|
|
32
|
+
id: reproduction
|
|
33
|
+
attributes:
|
|
34
|
+
label: Reproduction command or code
|
|
35
|
+
description: Include the exact dataset version, split, detector configuration, and command.
|
|
36
|
+
render: shell
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
- type: textarea
|
|
40
|
+
id: results
|
|
41
|
+
attributes:
|
|
42
|
+
label: Results and uncertainty
|
|
43
|
+
description: Report denominators and confidence intervals or replicate variation where available.
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
- type: input
|
|
47
|
+
id: implementation
|
|
48
|
+
attributes:
|
|
49
|
+
label: Public implementation or paper
|
|
50
|
+
placeholder: https://...
|
|
51
|
+
validations:
|
|
52
|
+
required: true
|
|
53
|
+
- type: checkboxes
|
|
54
|
+
id: integrity
|
|
55
|
+
attributes:
|
|
56
|
+
label: Submission checks
|
|
57
|
+
options:
|
|
58
|
+
- label: I evaluated on the documented frozen split and did not tune on the test labels.
|
|
59
|
+
required: true
|
|
60
|
+
- label: I have disclosed provider/model versions, abstentions, failures, and paid API use.
|
|
61
|
+
required: true
|
|
62
|
+
- label: The submission contains no secrets, personal data, or actionable fraud infrastructure.
|
|
63
|
+
required: true
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something behaves differently from what the docs say
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
For a **security vulnerability**, do not file here. See
|
|
9
|
+
[SECURITY.md](../blob/main/SECURITY.md) and email the maintainer.
|
|
10
|
+
- type: textarea
|
|
11
|
+
id: what
|
|
12
|
+
attributes:
|
|
13
|
+
label: What happened
|
|
14
|
+
description: What you expected, and what you got instead.
|
|
15
|
+
validations:
|
|
16
|
+
required: true
|
|
17
|
+
- type: textarea
|
|
18
|
+
id: repro
|
|
19
|
+
attributes:
|
|
20
|
+
label: How to reproduce
|
|
21
|
+
description: The exact command or code. A failing snippet beats a description.
|
|
22
|
+
render: shell
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: input
|
|
26
|
+
id: version
|
|
27
|
+
attributes:
|
|
28
|
+
label: Version or commit
|
|
29
|
+
placeholder: "0.9.1, or a commit SHA"
|
|
30
|
+
validations:
|
|
31
|
+
required: true
|
|
32
|
+
- type: input
|
|
33
|
+
id: python
|
|
34
|
+
attributes:
|
|
35
|
+
label: Python version and OS
|
|
36
|
+
placeholder: "3.11 on macOS 14"
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: true
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability
|
|
4
|
+
url: https://github.com/immu4989/lurebench/security/advisories/new
|
|
5
|
+
about: Report privately through GitHub. Please do not open a public issue.
|
|
6
|
+
- name: Question or idea
|
|
7
|
+
url: https://github.com/immu4989/lurebench/discussions
|
|
8
|
+
about: Open a discussion for usage questions and proposals.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## What this changes
|
|
2
|
+
|
|
3
|
+
<!-- One or two sentences. What is different after this PR? -->
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
<!-- The problem being solved. Link an issue if there is one. -->
|
|
8
|
+
|
|
9
|
+
## How it was verified
|
|
10
|
+
|
|
11
|
+
<!-- Commands you ran, tests you added, numbers you observed. If this changes a
|
|
12
|
+
published result, say which one and by how much. -->
|
|
13
|
+
|
|
14
|
+
## Checklist
|
|
15
|
+
|
|
16
|
+
- [ ] `pytest` passes
|
|
17
|
+
- [ ] `ruff check` passes
|
|
18
|
+
- [ ] New behaviour has a test
|
|
19
|
+
- [ ] Docs updated if behaviour or results changed
|
|
20
|
+
- [ ] Any fraud samples are defanged (no real URLs, contacts, payment rails, or PII)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: pip
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: monthly
|
|
7
|
+
open-pull-requests-limit: 5
|
|
8
|
+
groups:
|
|
9
|
+
python-dependencies:
|
|
10
|
+
patterns: ["*"]
|
|
11
|
+
# The bundled classifier is serialized with scikit-learn 1.6.1. Minor/major
|
|
12
|
+
# deserializer upgrades require an explicit model-compatibility validation.
|
|
13
|
+
# Dependabot security updates are unaffected by version-update ignores.
|
|
14
|
+
ignore:
|
|
15
|
+
- dependency-name: scikit-learn
|
|
16
|
+
update-types:
|
|
17
|
+
- version-update:semver-minor
|
|
18
|
+
- version-update:semver-major
|
|
19
|
+
- package-ecosystem: github-actions
|
|
20
|
+
directory: "/"
|
|
21
|
+
schedule:
|
|
22
|
+
interval: monthly
|
|
23
|
+
groups:
|
|
24
|
+
github-actions:
|
|
25
|
+
patterns: ["*"]
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
python-version: ["3.10", "3.12", "3.13"]
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
20
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
- uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
|
|
24
|
+
with:
|
|
25
|
+
version: "0.12.3"
|
|
26
|
+
enable-cache: true
|
|
27
|
+
cache-dependency-glob: uv.lock
|
|
28
|
+
- name: Install
|
|
29
|
+
run: uv sync --frozen --python "${{ matrix.python-version }}" --extra dev --extra train
|
|
30
|
+
- name: Lint
|
|
31
|
+
run: uv run --frozen ruff check lurebench tests scripts
|
|
32
|
+
- name: Tests
|
|
33
|
+
run: uv run --frozen pytest -q
|
|
34
|
+
- name: Build distributions
|
|
35
|
+
if: matrix.python-version == '3.12'
|
|
36
|
+
run: uv build
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: "17 4 * * 2"
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
analyze:
|
|
16
|
+
name: Analyze (python)
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
permissions:
|
|
19
|
+
actions: read
|
|
20
|
+
contents: read
|
|
21
|
+
packages: read
|
|
22
|
+
security-events: write
|
|
23
|
+
steps:
|
|
24
|
+
- name: Checkout source
|
|
25
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
|
+
with:
|
|
27
|
+
persist-credentials: false
|
|
28
|
+
- name: Initialize CodeQL
|
|
29
|
+
uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
|
|
30
|
+
with:
|
|
31
|
+
languages: python
|
|
32
|
+
build-mode: none
|
|
33
|
+
queries: security-extended
|
|
34
|
+
- name: Analyze
|
|
35
|
+
uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
|
|
36
|
+
with:
|
|
37
|
+
category: /language:python
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Release artifacts
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
name: Build and attest Python distributions
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
id-token: write
|
|
17
|
+
attestations: write
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout release source
|
|
20
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
- name: Set up uv
|
|
29
|
+
uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
|
|
30
|
+
with:
|
|
31
|
+
version: "0.12.3"
|
|
32
|
+
- name: Verify protected release source and metadata
|
|
33
|
+
run: |
|
|
34
|
+
git merge-base --is-ancestor "$GITHUB_SHA" origin/main
|
|
35
|
+
python scripts/verify_release.py "$GITHUB_REF_NAME"
|
|
36
|
+
- name: Build and verify distributions
|
|
37
|
+
run: |
|
|
38
|
+
uv build
|
|
39
|
+
uvx --from twine==7.0.0 twine check dist/*
|
|
40
|
+
- name: Attest distributions
|
|
41
|
+
uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
|
|
42
|
+
with:
|
|
43
|
+
subject-path: dist/*
|
|
44
|
+
- name: Store distributions
|
|
45
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
46
|
+
with:
|
|
47
|
+
name: python-package-distributions
|
|
48
|
+
path: dist/
|
|
49
|
+
if-no-files-found: error
|
|
50
|
+
- name: Attach distributions to the GitHub release
|
|
51
|
+
env:
|
|
52
|
+
GH_TOKEN: ${{ github.token }}
|
|
53
|
+
run: gh release upload "$GITHUB_REF_NAME" dist/* --clobber
|
|
54
|
+
|
|
55
|
+
publish-pypi:
|
|
56
|
+
name: Publish to PyPI with OIDC
|
|
57
|
+
if: ${{ vars.PYPI_PUBLISH == 'true' }}
|
|
58
|
+
needs: build
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
environment:
|
|
61
|
+
name: pypi
|
|
62
|
+
url: https://pypi.org/p/lurebench
|
|
63
|
+
permissions:
|
|
64
|
+
id-token: write
|
|
65
|
+
steps:
|
|
66
|
+
- name: Download distributions
|
|
67
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
68
|
+
with:
|
|
69
|
+
name: python-package-distributions
|
|
70
|
+
path: dist/
|
|
71
|
+
- name: Publish distributions
|
|
72
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: OpenSSF Scorecard
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: "31 5 * * 6"
|
|
8
|
+
|
|
9
|
+
permissions: read-all
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
analysis:
|
|
13
|
+
name: Scorecard analysis
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
security-events: write
|
|
17
|
+
id-token: write
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout source
|
|
20
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
21
|
+
with:
|
|
22
|
+
persist-credentials: false
|
|
23
|
+
- name: Run Scorecard
|
|
24
|
+
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
|
|
25
|
+
with:
|
|
26
|
+
results_file: results.sarif
|
|
27
|
+
results_format: sarif
|
|
28
|
+
publish_results: true
|
|
29
|
+
- name: Upload SARIF artifact
|
|
30
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
31
|
+
with:
|
|
32
|
+
name: scorecard-sarif
|
|
33
|
+
path: results.sarif
|
|
34
|
+
retention-days: 5
|
|
35
|
+
- name: Upload to code scanning
|
|
36
|
+
uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
|
|
37
|
+
with:
|
|
38
|
+
sarif_file: results.sarif
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*.egg-info/
|
|
4
|
+
.eggs/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
env/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.ruff_cache/
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
.DS_Store
|
|
14
|
+
*.log
|
|
15
|
+
# Secrets — API keys never get committed.
|
|
16
|
+
.env
|
|
17
|
+
.env.*
|
|
18
|
+
!.env.example
|
|
19
|
+
*.key
|
|
20
|
+
secrets/
|
|
21
|
+
# Generated staging (review-pending lures), trained model artifacts, and large data.
|
|
22
|
+
staging/
|
|
23
|
+
models/
|
|
24
|
+
data/full/
|
|
25
|
+
data/restricted/
|
|
26
|
+
*.parquet
|
|
27
|
+
|
|
28
|
+
# Cached detector scores from scripts/llm_experiments.py (regenerable, large)
|
|
29
|
+
.cache/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
exclude: '\.md$'
|
|
7
|
+
- id: end-of-file-fixer
|
|
8
|
+
- id: check-yaml
|
|
9
|
+
- id: check-toml
|
|
10
|
+
- id: check-added-large-files
|
|
11
|
+
args: ["--maxkb=2048"]
|
|
12
|
+
- id: check-merge-conflict
|
|
13
|
+
- id: detect-private-key
|
|
14
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
15
|
+
rev: v0.15.20
|
|
16
|
+
hooks:
|
|
17
|
+
- id: ruff
|
|
18
|
+
args: [--fix]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "LureBench: A Benchmark and Evaluation Harness for Detecting AI-Generated Fraud Lures",
|
|
3
|
+
"description": "<p>LureBench is a Python benchmark and evaluation harness for detecting AI-generated fraud lures across phishing, business email compromise, romance and pig-butchering typologies. It ships a distribution-matched corpus in nine languages, detector baselines from keyword rules through a trained classifier to LLM-as-classifier judges, and an adversarial layer of character-level and LLM-driven evasion attacks. Detectors are scored on two tasks: <em>fraud</em> (is this a lure?) and <em>provenance</em> (did a machine write it?).</p><p>The project documents several measurement results, including a corpus confound that makes AI-vs-human fraud detection look trivially easy until the classes are distribution-matched, a defang artifact that inflates apparent multilingual recall, and a robustness ordering that inverts depending on whether the attack changes spelling or meaning.</p><p>Everything runs without model downloads or API keys; provider keys are needed only to generate new lures or to run LLM-backed detectors and attacks.</p>",
|
|
4
|
+
"upload_type": "software",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"access_right": "open",
|
|
7
|
+
"creators": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Ahamed, Imran",
|
|
10
|
+
"orcid": "0009-0002-7717-7480"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"fraud detection",
|
|
15
|
+
"phishing",
|
|
16
|
+
"business email compromise",
|
|
17
|
+
"machine-generated text detection",
|
|
18
|
+
"adversarial robustness",
|
|
19
|
+
"large language models",
|
|
20
|
+
"AI security",
|
|
21
|
+
"benchmark"
|
|
22
|
+
],
|
|
23
|
+
"related_identifiers": [
|
|
24
|
+
{
|
|
25
|
+
"identifier": "https://github.com/immu4989/lurebench",
|
|
26
|
+
"relation": "isSupplementTo",
|
|
27
|
+
"scheme": "url"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"identifier": "https://github.com/immu4989/lurescope",
|
|
31
|
+
"relation": "isSourceOf",
|
|
32
|
+
"scheme": "url"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|