scamscript 0.6.1__tar.gz → 0.7.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.
- {scamscript-0.6.1 → scamscript-0.7.0}/CHANGELOG.md +21 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/PKG-INFO +29 -3
- {scamscript-0.6.1 → scamscript-0.7.0}/README.md +28 -2
- scamscript-0.7.0/corpus/real/real-commonwealth-bank-card-vishing.txt +1459 -0
- scamscript-0.7.0/corpus/real/real-credit-union-card-vishing.txt +47 -0
- scamscript-0.7.0/corpus/real/real-ftc-apple-support-robocall.txt +7 -0
- scamscript-0.7.0/corpus/real/real-ftc-interest-rate-robocall.txt +7 -0
- scamscript-0.7.0/corpus/real/real-ftc-irs-settlement-robocall.txt +7 -0
- scamscript-0.7.0/corpus/real/real-ftc-ssa-suspension-robocall.txt +7 -0
- scamscript-0.7.0/corpus/real/real-ftc-student-loan-robocall.txt +7 -0
- scamscript-0.7.0/corpus/real/real-ftc-utility-rebate-robocall.txt +7 -0
- scamscript-0.7.0/corpus/real/real-medicare-benefits-vishing.txt +519 -0
- scamscript-0.7.0/corpus/real/real-usps-invalid-zip-smishing.txt +6 -0
- scamscript-0.7.0/docs/real-corpus.md +37 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/pyproject.toml +1 -1
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/__init__.py +1 -1
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/analysis.py +14 -4
- scamscript-0.7.0/src/scamscript/brief.py +95 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/cli.py +77 -6
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/client.py +1 -1
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/config.py +2 -1
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/ingest.py +33 -13
- scamscript-0.7.0/src/scamscript/language.py +62 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/prompts.py +11 -5
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/taxonomy.py +12 -5
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/verify.py +24 -6
- scamscript-0.7.0/tests/test_brief.py +57 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_cli.py +20 -2
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_ingest.py +32 -0
- scamscript-0.7.0/tests/test_language.py +28 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_taxonomy.py +5 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_verify.py +32 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/.github/SECURITY.md +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/.github/pull_request_template.md +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/.github/workflows/ci.yml +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/.github/workflows/release.yml +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/.gitignore +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/CITATION.cff +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/CODE_OF_CONDUCT.md +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/CONTRIBUTING.md +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/LICENSE +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/docs/banner.svg +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/docs/calibration.md +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/docs/demo.gif +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/docs/sample-report.md +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/docs/social-preview.png +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/adversarial/fake_output_json.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/adversarial/fence_escape.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/adversarial/fixed_attack_type.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/adversarial/non_json_demand.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/adversarial/print_system_prompt.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/adversarial/role_switch.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/adversarial/score_override.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/crude_robocall.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/gov_impersonation_vishing.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/prompt_injection_script.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/romance_scam_sms.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/sophisticated_wire_fraud.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/examples/tech_support_scam.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/scripts/calibrate.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/scripts/injection_eval.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/__main__.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/dedupe.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/models.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/redact.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/render.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/report.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/src/scamscript/store.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/fixtures/reprints/copy-header.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/fixtures/reprints/copy-punctuation.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/fixtures/reprints/near-twin.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/fixtures/reprints/original.txt +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_analysis.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_client.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_dedupe.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_models.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_prompts.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_redact.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_render.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_report.py +0 -0
- {scamscript-0.6.1 → scamscript-0.7.0}/tests/test_store.py +0 -0
|
@@ -5,6 +5,27 @@ schema are the things that count as public API.
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
## 0.7.0 - 2026-11-02
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `brief` command: a one-page defence handout per type from a finished run.
|
|
13
|
+
- `--language` override and stopword language detection; the prompt asks for the script's own language.
|
|
14
|
+
- `corpus/real/` with ten published transcripts, provenance in every header, and `docs/real-corpus.md`.
|
|
15
|
+
- `--force` before overwriting an output file.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Apostrophes inside words (`target's`) were read as quote delimiters, producing false `missing`
|
|
20
|
+
verdicts. Long quotes are now checked clause by clause.
|
|
21
|
+
- A recursive walk followed a symlink loop; it now terminates.
|
|
22
|
+
- A file changing mid-read is reported instead of being half-analyzed.
|
|
23
|
+
- Utility-rebate robocalls classified as `refund`; utility is matched first.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Default `--max-tokens` 4096 → 6144, after two real calls hit the ceiling on the first attempt.
|
|
28
|
+
|
|
8
29
|
## 0.6.1 - 2026-11-02
|
|
9
30
|
|
|
10
31
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: scamscript
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Reverse-engineer scam scripts and vishing transcripts into structured counter-playbooks
|
|
5
5
|
Project-URL: Homepage, https://github.com/sjdsjadjajdjsa/scamscript
|
|
6
6
|
Project-URL: Repository, https://github.com/sjdsjadjajdjsa/scamscript
|
|
@@ -130,11 +130,12 @@ corpus is at [`docs/sample-report.md`](https://github.com/sjdsjadjajdjsa/scamscr
|
|
|
130
130
|
| `batch <dir>` | Same as above, ranked |
|
|
131
131
|
| `report --run-id` | Regenerate a report from a past run's log |
|
|
132
132
|
| `history` | List previous runs |
|
|
133
|
+
| `brief` | One-page defence handout from a finished run |
|
|
133
134
|
| `prune` | Delete old logs |
|
|
134
135
|
|
|
135
136
|
Useful flags: `--dry-run`, `--json`, `--redact`, `--top N`, `--recursive`, `--timeout`,
|
|
136
137
|
`--retries`, `--max-tokens`, `--concurrency`, `--max-cost`, `--dedupe/--no-dedupe`,
|
|
137
|
-
`--show-duplicates`, `--type`, `--no-color`. `--json` puts one object per script on stdout and all
|
|
138
|
+
`--show-duplicates`, `--type`, `--language`, `--force`, `--no-color`. `--json` puts one object per script on stdout and all
|
|
138
139
|
Rich output on stderr, so it pipes:
|
|
139
140
|
|
|
140
141
|
```bash
|
|
@@ -155,6 +156,17 @@ The cap reads `usage.cost` from the response, so it works only where the provide
|
|
|
155
156
|
says so when none is sent. Spend is printed and logged per run. In-flight requests can overshoot by
|
|
156
157
|
up to the concurrency, so keep headroom on a hard limit.
|
|
157
158
|
|
|
159
|
+
## Real corpus
|
|
160
|
+
|
|
161
|
+
`corpus/real/` holds ten published transcripts with source, date and verbatim status in every
|
|
162
|
+
header: a 40-minute bank impersonation call, a Medicare benefits pitch, six FTC robocalls, a
|
|
163
|
+
recalled credit-union call and a USPS smishing message. Provenance and the results of running them
|
|
164
|
+
are in [`docs/real-corpus.md`](https://github.com/sjdsjadjajdjsa/scamscript/blob/master/docs/real-corpus.md).
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
scamscript --redact batch corpus/real --concurrency 3 --max-cost 0.25 --output real.md
|
|
168
|
+
```
|
|
169
|
+
|
|
158
170
|
## Attack types
|
|
159
171
|
|
|
160
172
|
`attack_type` is free prose, which is useful to read and useless to group. Every result also carries a
|
|
@@ -166,6 +178,12 @@ per slug above the ranking, and `--type` filters to the ones you ask for:
|
|
|
166
178
|
scamscript batch corpus/ --type tech-support,refund --output report.md
|
|
167
179
|
```
|
|
168
180
|
|
|
181
|
+
Briefings group the same way. Build one from a finished run:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
scamscript brief --type tech-support --output briefing.md
|
|
185
|
+
```
|
|
186
|
+
|
|
169
187
|
The raw phrase is always kept next to the slug. An unrecognised description lands in `other` and the
|
|
170
188
|
CLI names any filter token it did not recognise.
|
|
171
189
|
|
|
@@ -220,6 +238,12 @@ Every request appends to a timestamped JSONL file under `~/.scamscript/logs/` (o
|
|
|
220
238
|
a run replays without spending tokens, and `prune --keep 200 --keep-days 30` keeps the store
|
|
221
239
|
bounded. Directories are `0700` and log files `0600`.
|
|
222
240
|
|
|
241
|
+
## Paths
|
|
242
|
+
|
|
243
|
+
`--file` and `--dir` resolve symlinks, a recursive walk survives a symlink loop, and a file that
|
|
244
|
+
changes while it is read is an error rather than a half-read prompt. Output files are not overwritten
|
|
245
|
+
unless `--force` is passed.
|
|
246
|
+
|
|
223
247
|
## Install and configure
|
|
224
248
|
|
|
225
249
|
Python 3.12+. `pip install scamscript` for use, `pip install -e ".[dev]"` from a clone for tests.
|
|
@@ -281,6 +305,7 @@ src/scamscript/
|
|
|
281
305
|
verify.py quote checking against the source
|
|
282
306
|
tests/ schema, retry, redaction, verification, client and CLI tests
|
|
283
307
|
examples/ six fictional transcripts, plus adversarial/ fixtures
|
|
308
|
+
corpus/real/ ten published transcripts with provenance
|
|
284
309
|
scripts/ calibration and injection harnesses
|
|
285
310
|
docs/ calibration record, sample report, banner, demo
|
|
286
311
|
```
|
|
@@ -293,7 +318,8 @@ docs/ calibration record, sample report, banner, demo
|
|
|
293
318
|
- Duplicate folding ignores formatting only; a single changed digit keeps a copy separate.
|
|
294
319
|
- Type slugs are keyword-matched, so an unusual description falls to `other` rather than inventing one.
|
|
295
320
|
- The cost cap depends on provider-reported usage and can overshoot by the in-flight count.
|
|
296
|
-
-
|
|
321
|
+
- The prompt asks the model to answer in the script's own language and `--language` overrides
|
|
322
|
+
detection, but the type keywords are English: a non-English script often falls to `other`.
|
|
297
323
|
- Quote checking compares text, not meaning. A legitimate paraphrase left in quotes is flagged;
|
|
298
324
|
an accurate paraphrase without quotes is skipped rather than judged.
|
|
299
325
|
|
|
@@ -94,11 +94,12 @@ corpus is at [`docs/sample-report.md`](https://github.com/sjdsjadjajdjsa/scamscr
|
|
|
94
94
|
| `batch <dir>` | Same as above, ranked |
|
|
95
95
|
| `report --run-id` | Regenerate a report from a past run's log |
|
|
96
96
|
| `history` | List previous runs |
|
|
97
|
+
| `brief` | One-page defence handout from a finished run |
|
|
97
98
|
| `prune` | Delete old logs |
|
|
98
99
|
|
|
99
100
|
Useful flags: `--dry-run`, `--json`, `--redact`, `--top N`, `--recursive`, `--timeout`,
|
|
100
101
|
`--retries`, `--max-tokens`, `--concurrency`, `--max-cost`, `--dedupe/--no-dedupe`,
|
|
101
|
-
`--show-duplicates`, `--type`, `--no-color`. `--json` puts one object per script on stdout and all
|
|
102
|
+
`--show-duplicates`, `--type`, `--language`, `--force`, `--no-color`. `--json` puts one object per script on stdout and all
|
|
102
103
|
Rich output on stderr, so it pipes:
|
|
103
104
|
|
|
104
105
|
```bash
|
|
@@ -119,6 +120,17 @@ The cap reads `usage.cost` from the response, so it works only where the provide
|
|
|
119
120
|
says so when none is sent. Spend is printed and logged per run. In-flight requests can overshoot by
|
|
120
121
|
up to the concurrency, so keep headroom on a hard limit.
|
|
121
122
|
|
|
123
|
+
## Real corpus
|
|
124
|
+
|
|
125
|
+
`corpus/real/` holds ten published transcripts with source, date and verbatim status in every
|
|
126
|
+
header: a 40-minute bank impersonation call, a Medicare benefits pitch, six FTC robocalls, a
|
|
127
|
+
recalled credit-union call and a USPS smishing message. Provenance and the results of running them
|
|
128
|
+
are in [`docs/real-corpus.md`](https://github.com/sjdsjadjajdjsa/scamscript/blob/master/docs/real-corpus.md).
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
scamscript --redact batch corpus/real --concurrency 3 --max-cost 0.25 --output real.md
|
|
132
|
+
```
|
|
133
|
+
|
|
122
134
|
## Attack types
|
|
123
135
|
|
|
124
136
|
`attack_type` is free prose, which is useful to read and useless to group. Every result also carries a
|
|
@@ -130,6 +142,12 @@ per slug above the ranking, and `--type` filters to the ones you ask for:
|
|
|
130
142
|
scamscript batch corpus/ --type tech-support,refund --output report.md
|
|
131
143
|
```
|
|
132
144
|
|
|
145
|
+
Briefings group the same way. Build one from a finished run:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
scamscript brief --type tech-support --output briefing.md
|
|
149
|
+
```
|
|
150
|
+
|
|
133
151
|
The raw phrase is always kept next to the slug. An unrecognised description lands in `other` and the
|
|
134
152
|
CLI names any filter token it did not recognise.
|
|
135
153
|
|
|
@@ -184,6 +202,12 @@ Every request appends to a timestamped JSONL file under `~/.scamscript/logs/` (o
|
|
|
184
202
|
a run replays without spending tokens, and `prune --keep 200 --keep-days 30` keeps the store
|
|
185
203
|
bounded. Directories are `0700` and log files `0600`.
|
|
186
204
|
|
|
205
|
+
## Paths
|
|
206
|
+
|
|
207
|
+
`--file` and `--dir` resolve symlinks, a recursive walk survives a symlink loop, and a file that
|
|
208
|
+
changes while it is read is an error rather than a half-read prompt. Output files are not overwritten
|
|
209
|
+
unless `--force` is passed.
|
|
210
|
+
|
|
187
211
|
## Install and configure
|
|
188
212
|
|
|
189
213
|
Python 3.12+. `pip install scamscript` for use, `pip install -e ".[dev]"` from a clone for tests.
|
|
@@ -245,6 +269,7 @@ src/scamscript/
|
|
|
245
269
|
verify.py quote checking against the source
|
|
246
270
|
tests/ schema, retry, redaction, verification, client and CLI tests
|
|
247
271
|
examples/ six fictional transcripts, plus adversarial/ fixtures
|
|
272
|
+
corpus/real/ ten published transcripts with provenance
|
|
248
273
|
scripts/ calibration and injection harnesses
|
|
249
274
|
docs/ calibration record, sample report, banner, demo
|
|
250
275
|
```
|
|
@@ -257,7 +282,8 @@ docs/ calibration record, sample report, banner, demo
|
|
|
257
282
|
- Duplicate folding ignores formatting only; a single changed digit keeps a copy separate.
|
|
258
283
|
- Type slugs are keyword-matched, so an unusual description falls to `other` rather than inventing one.
|
|
259
284
|
- The cost cap depends on provider-reported usage and can overshoot by the in-flight count.
|
|
260
|
-
-
|
|
285
|
+
- The prompt asks the model to answer in the script's own language and `--language` overrides
|
|
286
|
+
detection, but the type keywords are English: a non-English script often falls to `other`.
|
|
261
287
|
- Quote checking compares text, not meaning. A legitimate paraphrase left in quotes is flagged;
|
|
262
288
|
an accurate paraphrase without quotes is skipped rather than judged.
|
|
263
289
|
|