Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
16ca8ac
Merge pull request #126 from ReversecLabs/main
ThomasCross Sep 10, 2026
0ef5888
Merge pull request #128 from ReversecLabs/main
ThomasCross Sep 10, 2026
9a3ff06
Merge pull request #130 from ReversecLabs/main
ThomasCross Sep 10, 2026
be83e29
docs: update Contribution Rules to CONTRIBUTING.md
ThomasCross Sep 10, 2026
5404ca0
Merge pull request #132 from ThomasCross/tjc-contributions-docs
ThomasCross Sep 10, 2026
05198d3
feat: simplify attack logging with nested attempt_history
kyuz0 Sep 10, 2026
2e0cb49
fix: put result IDs and success before input and response
kyuz0 Sep 10, 2026
c14ff2a
fix: preserve original text as attack result objective
kyuz0 Sep 10, 2026
425373c
fix: shorten output filenames with readable labels and hashes
kyuz0 Sep 10, 2026
877f9af
fix: harden judge verdicts and add model evaluations
kyuz0 Sep 10, 2026
482ec2f
fix: refactor _attack_result to use dictionary literal for row creation
ThomasCross Sep 11, 2026
a77ab18
Merge pull request #135 from ThomasCross/tjc-fix-donato-lint
ThomasCross Sep 11, 2026
f511180
fix: repair malformed LLM attack responses with bounded retries
kyuz0 Sep 11, 2026
85b1207
fix: give judge retries rejected assessments and validation errors
kyuz0 Sep 11, 2026
8ceb7a6
fix: tolerate verified evidence excerpts and negative-grade summaries
kyuz0 Sep 11, 2026
44d8b4c
Handle reasoning prefixes and reinforce judge grading requests
kyuz0 Sep 11, 2026
bd5db3f
change: update conversation attempt history in the webui
ThomasCross Sep 11, 2026
7ba4edd
fix: remove unnecessary blank line in _conversation_message_count fun…
ThomasCross Sep 11, 2026
d43a460
feat: Implement Spikee Filter Language (SFL) for result extraction
ThomasCross Sep 11, 2026
387b7dd
fix: update spikee_extract_cli tests to use SFL
ThomasCross Sep 11, 2026
3732662
fix: append resumed tests to the original results file
kyuz0 Sep 11, 2026
8827d34
fix: remove attacker token caps and accept literal JSON control chara…
kyuz0 Sep 11, 2026
e93f286
fix: remove judge evidence requirements and quote validation
kyuz0 Sep 11, 2026
87bcb94
docs: record live OpenRouter judge accuracy
kyuz0 Sep 11, 2026
596f937
fix: warn only when structured response repairs are exhausted
kyuz0 Sep 11, 2026
056dc95
Merge pull request #136 from ThomasCross/tjc-webui-conversations-qol
ThomasCross Sep 11, 2026
2388a02
Merge pull request #137 from ThomasCross/tjc-spikee-filter-language
ThomasCross Sep 11, 2026
ae36f96
Merge pull request #134 from kyuz0/fix/llm-judge-evaluation
ThomasCross Sep 11, 2026
dca48bd
Merge pull request #138 from ReversecLabs/main
ThomasCross Sep 11, 2026
c227ffe
Release 0.9.2
github-actions[bot] Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,46 @@
# Changelog

All notable changes to this project will be documented in this file.
## [0.9.2] - 2026-09-11

### Features

- Implement Spikee Filter Language (SFL) for result extraction
- simplify attack logging with nested attempt_history
- add opt-in dynamic attack history
- webui fetch and convert script
- webui edit seeds and datasets
- enhance session management for webui executions and persist state
- implement manual job handling and UI for dataset testing

### Fixes

- warn only when structured response repairs are exhausted
- remove judge evidence requirements and quote validation
- remove attacker token caps and accept literal JSON control characters
- append resumed tests to the original results file
- update spikee_extract_cli tests to use SFL
- remove unnecessary blank line in _conversation_message_count function
- tolerate verified evidence excerpts and negative-grade summaries
- give judge retries rejected assessments and validation errors
- repair malformed LLM attack responses with bounded retries
- refactor _attack_result to use dictionary literal for row creation
- harden judge verdicts and add model evaluations
- shorten output filenames with readable labels and hashes
- preserve original text as attack result objective
- put result IDs and success before input and response
- remove redundant skip PyPI publication step from release workflow
- add SKIP_PYPI environment variable to control PyPI publication in release workflow
- refine conditions for lint and functional test jobs in workflow
- pin ruff version to 0.16.6 in release and test workflows
- declare tokenizer dependency for random suffix attack
- debug plugin option key and error handling in OpusTranslator (#122)
- add future annotations import to crescendo.py to fix test bug

### Changes

- update conversation attempt history in the webui

## [0.9.1] - 2026-07-13

### Features
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
</p>
</div>

_Version: 0.9.2-dev_
_Version: 0.9.2_


Developed by Reversec Labs, `spikee` is a toolkit for assessing the resilience of LLMs, guardrails, and applications against prompt injection and jailbreaking. Spikee's strength is its modular design, which allows for easy customization of every part of the testing process.
Expand Down Expand Up @@ -375,7 +375,7 @@ Further information on analyzing results can be found in the **[Spikee Results](

Contributions are welcome. Please feel free to submit bug fixes, new modules (Targets, Plugins, Attacks, Judges), or dataset seeds via GitHub pull requests.

See [Contribution Rules](./CONTRIBUTION_RULES.md) for guidelines on contributing to the project.
See [Contribution Rules](./CONTRIBUTING.md) for guidelines on contributing to the project.

# Questions or Feedback?

Expand Down
16 changes: 7 additions & 9 deletions docs/01_cheatsheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ spikee test --dataset my_dataset.jsonl --target my_target

| **Resume Arguments** | Description | Docs |
| -------------------- | ----------------------------------------------------------------------------- | -------- |
| `--resume-file` | Path to a results JSONL file to resume from. Only works with a single dataset | [Link](./05_testing.md#resume) |
| `--resume-file` | Append to an existing results JSONL file. Only works with a single dataset | [Link](./05_testing.md#resume) |
| `--auto-resume` | Silently pick the latest matching results file if present | [Link](./05_testing.md#resume) |
| `--no-auto-resume` | Create new results file, do not attempt to resume | [Link](./05_testing.md#resume) |

Expand All @@ -134,7 +134,7 @@ spikee results analyze --results-file results.jsonl
(NB, Result file/folder args can be used multiple times to specify multiple datasets, but at least one is **required**)

### `rejudge`
Rejudges a results file - [Link](./09_judges.md#2-perform-rejudging)
Rejudges a results file - [Link](./09_judges.md#re-judging)

```bash
spikee results rejudge --results-file results.jsonl
Expand All @@ -149,18 +149,17 @@ spikee results rejudge --results-file results.jsonl
(NB, Result file/folder args can be used multiple times to specify multiple datasets, but at least one is **required**)

### `extract`
Searches for result entries by category or search term and extracts them to another JSONL file - [Link](./11_results.md#the-extract-command)
Searches for result entries with an SFL query and extracts them to another JSONL file - [Link](./11_results.md#the-extract-command)

```bash
spikee results extract --results-file results.jsonl --category "success"
spikee results extract --result-file results.jsonl --query "success = true"
```

| Argument | Description |
| ------------------- | ------------------------------------------------------ |
| `--results-file` | Path to a results JSONL file |
| `--results-folder` | Path to a folder containing multiple results JSONL files |
| `--category` | Extracts prompts by category: success (default), failure, error, guardrail, no-guardrail, custom |
| `--custom-search` | Custom search string to filter prompts when --category=custom. Formats: 'search_string', 'field:search_string' or '!search_string' to invert match |
| `--result-file` | Path to a results JSONL file |
| `--result-folder` | Path to a folder containing multiple results JSONL files |
| `--query` | Required Spikee Filter Language (SFL) query |
| `--tag` | Include a tag at the end of the results filename |

(NB, Result file/folder args can be used multiple times to specify multiple datasets, but at least one is **required**)
Expand All @@ -187,4 +186,3 @@ spikee webui --host 0.0.0.0 -p 8081
# Persist job history across restarts
spikee webui --database jobs.db
```

13 changes: 13 additions & 0 deletions docs/02_builtin.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,16 @@ spikee test --dataset datasets/dataset-name.jsonl \
--attack-only

```

### Malformed attacker JSON

Structured LLM attacks send malformed replies back to the same model with the parser/field-validation error and ask for a complete corrected response. Local parsing accepts code fences, explicit reasoning prefixes ending in `</think>`, or prose around an object. Literal control characters inside quoted strings, such as newlines and tabs, are preserved as text. Missing commas, closing quotes or braces still require repair; the parser does not invent missing values.

- **Call limits:** Crescendo allows 3 calls total per generation; Echo Chamber uses `stage-attempts`; GOAT generation uses `LLM_AGENT_RETRY`. Other structured calls allow 2 total (initial + one repair). Existing refusal fallbacks remain separate.
- **Output length:** LLM Jailbreaker, its multilingual and poetry variants, and RAG Poisoner leave the output-token limit to the provider/model, as do Crescendo and GOAT. Generation and repair use the same provider settings.
- **JSONL:** prompt decomposition repairs each batch once. If both replies are malformed, it keeps the batch with the most valid lines and retains its existing top-up/original-prompt fallback.
- **Diagnostics:** successful repairs are silent. Only exhausted format failures log attack/stage, parser error, model, requested token cap, finish reason and token usage. Provider metadata may be unavailable. Repair calls consume attacker inference, not target-attempt budget.

Example: `finish_reason: "length"` indicates a provider-reported length limit; `requested_max_tokens: null` means Spikee set no explicit cap. A missing finish reason does not establish truncation. Provider errors are not treated as JSON failures by the repair helper.

Existing workspace copies of `goat.py` need the updated template and matching Spikee package. Other custom workspace overrides are unchanged.
2 changes: 1 addition & 1 deletion docs/03_llm_providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Use `spikee list providers` to get a list of providers and known supported model
| Local (Ollama) | `ollama` | *None* | `OLLAMA_URL` | |
| Local (LLaMA CPP Server) | `llamacpp` | *None* | `LLAMACPP_URL` | |
| Custom | `custom` | *None* | `CUSTOM_API_URL`<br/>`CUSTOM_API_KEY` | *Custom OpenAI-Based API* |
| Offline | `offline` | `offline` | *None* | [See Judges section](./09_judges.md#1-scan-using-offline-judge) |
| Offline | `offline` | `offline` | *None* | [See Judges section](./09_judges.md#re-judging) |


## Configuring Models in Spikee Components
Expand Down
6 changes: 5 additions & 1 deletion docs/04_dataset_generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

The `spikee generate` command offers several flags to control precisely how test cases are constructed. Understanding these options is key to creating datasets that accurately simulate specific attack vectors and test potential defenses.

Generated dataset filenames keep short, safe seed names and tags unchanged. Long
names or names containing special characters use a readable prefix plus a
12-character hash, while retaining the output format and timestamp. This keeps
filenames under 180 characters without changing dataset contents.

Jump to Links:
- [Dataset Construction](#dataset-construction)
- [Multi-Turn Dataset Types](#multi-turn-datasets)
Expand Down Expand Up @@ -221,4 +226,3 @@ spikee generate --seed-folder datasets/seeds-cybersec-2026-01 \
--jailbreak-filter dan \
--instruction-filter data-exfil-curl
```

31 changes: 23 additions & 8 deletions docs/05_testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ spikee test

These args can be used multiple times to specify multiple datasets, which `spikee test` will assess sequentially against the target. However, at least one of `--dataset` or `--dataset-folder` is **required** to run a test.

Result filenames use compact labels: target options that need cleaning or shortening
become up to 24 readable characters plus a 12-character hash of the full options.
Long dataset names and tags are also shortened, keeping generated filenames under
180 characters. The original options are still passed to the target unchanged.
Automatic resume recognizes both compact names and existing result filenames.

```bash
spikee test
--dataset ./dataset/cybersec-2026-01.jsonl \
Expand Down Expand Up @@ -103,8 +109,10 @@ spikee test
```

### Resume
Resuming appends new results to the selected file, including with `--auto-resume` or the interactive picker. Completed entries are skipped; repeated resumes do not create additional results files. An unfinished entry is retried from the start, with any older incomplete history rows replaced. Use `--no-auto-resume` to start a fresh file.

By default, Spikee will analyse the workspace results folder to identify an previously executed test files with a matching name pattern. It will then display an interactive prompt to start a new test or to continue a previous test. The following flags can be used to control this behavior:
- `--resume-file` - specify a path to a results JSONL file to resume from. Only works with a single dataset.
- `--resume-file` - append to an existing results JSONL file. Only works with a single dataset. A missing or malformed file raises an error.
- `--auto-resume` - silently pick the latest matching results file if present
- `--no-auto-resume` - create new results file, do not attempt to resume

Expand All @@ -131,17 +139,24 @@ spikee test
--no-auto-resume

```
## Retain every dynamic attack attempt
## Attack history and conversation logs

Dynamic attacks write one result per dataset entry, with ID `<id>-attack`, the successful or final failed input/response, and the overall `attempts` count. Supporting single-turn attacks, including `best_of_n`, `llm_jailbreaker`, and `llm_multi_language_jailbreaker`, also include an `attempt_history` list containing the intermediate inputs, responses, and their recorded verdicts. History is enabled by default; no CLI option or viewer checkbox is required.

By default, dynamic attacks keep one representative result per dataset entry: the successful attempt, or the final failed attempt. To retain intermediate attempts from supporting attacks:
To omit this optional history, set `SPIKEE_ATTACK_HISTORY=false` in the environment or workspace `.env`:

```bash
spikee test --dataset datasets/my-dataset.jsonl --target my_target \
--attack best_of_n --attack-iterations 20 --attack-return-all-attempts
SPIKEE_ATTACK_HISTORY=false spikee test \
--dataset datasets/my-dataset.jsonl --target my_target \
--attack best_of_n --attack-iterations 20
```

The flag also works with `--attack-only` and repeated invocations using `--attempts`. In the web UI, select **Retain all attack attempts**. Neither choice changes attack stopping conditions or adds target/judge calls. Full histories take more memory and result-file space, especially with conversation snapshots. Older custom attacks without history support remain callable; Spikee warns and saves their representative result.
`false`, `0`, `no`, and `off` disable recording (case-insensitive). The setting changes memory and result-file usage, without changing target calls, judge calls, stopping conditions, the representative result, or attempt counts. Custom and legacy modules may omit history; Spikee continues to accept their existing return tuple and does not reconstruct discarded candidates.

**Crescendo, GOAT, Echo Chamber, and `multi_turn` keep their existing `conversation` logs.** They do not use `SPIKEE_ATTACK_HISTORY` or duplicate their turns in `attempt_history`. The graph-based attacks retain recorded turns and backtracking branches in one row; inspect the conversation in the viewer before concluding that earlier exchanges were lost. Existing error paths can omit some details.

With repeated invocations using `--attempts`, provided candidate histories are combined in the one attack result. Each nested item receives a 1-based `invocation` number. The top-level input, response, and conversation remain from the successful or final invocation. Only its conversation graph survives; candidate history does not change conversation logging.

Twenty attack attempts contribute 20 to total attempts in either mode. Standard attempts are counted separately. Expanded result IDs are unique and remain associated with their source dataset entry. See [Dynamic Attacks](08_dynamic_attacks.md#retaining-all-attempts) and [Results Analysis](11_results.md).
Twenty dynamic iterations still contribute 20 to total attempts; a separate standard attempt adds its own count. Nested history items and conversation nodes are evidence, not additional dataset entries or counts. See [Dynamic Attacks](08_dynamic_attacks.md#attempt-history) and [Results Analysis](11_results.md#attack-history-and-conversation-results).

Resume keeps completed entries in their existing format. To collect history for entries previously completed in representative mode, start a fresh run with `--no-auto-resume`. An incomplete traced group is rerun as a whole; transport retries are not separate retained candidates.
Resume preserves completed results as saved. Start a fresh run with `--no-auto-resume` to collect history for previously completed entries that lack it. History is held in memory until the attack returns; it is not a checkpoint for resuming within an attack.
Loading
Loading