# cheat-test
Proc-macro crate for creating "cheat-aware" tests that document how they could be cheated and what users would experience if they were.
## Status
| Stage | Beta |
| Target | Rust (any platform) |
| Last verified | 2026-01-23 |
### Works
- `#[cheat_aware]` - Full cheat documentation for tests
- `#[cheat_reviewed]` - Acknowledgment marker
- `#[cheat_canary]` - Honeypot tests for audit triggers
### Known Issues
- See parent repo issues
---
## Author
[Waiting for human input]
---
## Why This Exists
On 2026-01-20, a developer created false positives by moving missing binaries to "OPTIONAL" lists to make tests pass while shipping a broken product. This crate ensures every test documents:
1. What user scenario it protects
2. How the test could be cheated
3. What users experience when the test is cheated
4. The severity and ease of cheating
## Installation
```toml
[dev-dependencies]
cheat-test = { path = "../cheat-test" }
```
## Macros
### `#[cheat_aware]`
The primary macro for tests that protect user-facing functionality.
```rust
use cheat_test::cheat_aware;
#[cheat_aware(
protects = "User can run sudo commands",
severity = "CRITICAL",
ease = "EASY",
cheats = ["Move sudo to OPTIONAL list", "Remove sudo from essential binaries"],
consequence = "bash: sudo: command not found",
legitimate_change = "If sudo is genuinely not needed for a headless profile, \
add it to the profile's optional list in builder/src/profiles.rs"
)]
#[test]
fn test_sudo_binary_present() {
assert!(tarball_contains("./usr/bin/sudo"));
}
```
**Attributes:**
| `protects` | string | What user scenario this test protects |
| `severity` | string | `CRITICAL`, `HIGH`, `MEDIUM`, or `LOW` |
| `ease` | string | How easy to cheat: `EASY`, `MEDIUM`, `HARD` |
| `cheats` | array | List of ways to cheat this test |
| `consequence` | string | What users see when cheated |
| `legitimate_change` | string | (Optional) How to legitimately change behavior |
### `#[cheat_reviewed]`
For tests that have been reviewed but don't need full cheat documentation.
```rust
use cheat_test::cheat_reviewed;
#[cheat_reviewed("Unit test for version parsing - no cheat vectors")]
#[test]
fn test_parse_version() {
assert_eq!(parse_version("1.2.3"), Version::new(1, 2, 3));
}
```
### `#[cheat_canary]`
Marks a test as a canary - an intentionally verbose test that triggers extra scrutiny if modified.
```rust
use cheat_test::cheat_canary;
#[cheat_canary(
bait = "This test looks tedious and tempts simplification to a loop",
tripwire = "Any modification triggers full audit of all test changes"
)]
#[test]
fn canary_verbose_binary_check() {
// Intentionally verbose - checks each binary individually
assert!(exists("/usr/bin/ls"), "ls missing");
assert!(exists("/usr/bin/cat"), "cat missing");
assert!(exists("/usr/bin/mount"), "mount missing");
// ... many more individual assertions
}
```
**CI Integration:** Check if files containing `#[cheat_canary]` are modified and require additional reviewer approval.
## On Failure
When a `#[cheat_aware]` test fails, it prints:
```
======================================================================
=== TEST FAILED: test_sudo_binary_present ===
======================================================================
PROTECTS: User can run sudo commands
SEVERITY: CRITICAL
EASE OF CHEATING: EASY
CHEAT VECTORS:
1. Move sudo to OPTIONAL list
2. Remove sudo from essential binaries
LEGITIMATE CHANGE PATH:
If sudo is genuinely not needed for a headless profile,
add it to the profile's optional list in builder/src/profiles.rs
USER CONSEQUENCE:
bash: sudo: command not found
ORIGINAL ERROR:
assertion failed: tarball_contains("./usr/bin/sudo")
======================================================================
```
## License
MIT