Context
Existing fuzz tests cover starter-pack manifests, LLM intent classification, and export/import contracts. This issue expands adversarial input testing to more system boundaries — the places where user input enters the system and where the system must not break regardless of what it receives.
Candidate Surfaces for Property-Based / Fuzz Testing
Backend
API Request Bodies (adversarial JSON)
- Card creation: Random strings for title (0 to 100K chars), description (nulls, unicode, control chars, script tags), position (negative, float, MAX_INT)
- Board creation: Name with every unicode block, duplicate names, SQL injection attempts in name
- Capture text: Random binary data, null bytes, very long strings, nested JSON in text field
- Proposal operations JSON: Malformed operation types, missing fields, extra unknown fields, deeply nested objects
- Webhook URL: every RFC 3986 edge case, URL with authentication credentials, URL with fragments, data: URLs, javascript: URLs
Domain Entity Construction
- Property: for any valid construction parameters, the entity should be constructable and its invariants hold
- Property: for any invalid parameter combination, DomainException is thrown (never silently accepts bad data)
- Property: for any valid entity, calling Touch() changes UpdatedAt
JSON Serialization Round-Trip
- Property: for any board state (random cards, columns, labels), serialize → deserialize produces identical state
- Property: for any capture payload, SerializePayload → ParsePayload is identity
- Property: for any CaptureRequestContract.WithProvenance payload, the provenance fields are always recoverable
SQLite Query Boundary Values
- GUID format: verify queries work with uppercase, lowercase, and mixed-case GUIDs
- DateTime boundary: epoch, year 9999, DateTime.MinValue, DateTime.MaxValue
- String length: empty string vs null vs whitespace-only vs max-length
Frontend
Input Sanitization
- Card title input: paste 10K chars → verify truncation or rejection, no crash
- Search query: paste SQL injection / XSS payloads → verify sanitized in display
- Chat input: very long message → verify sent or truncated, no freeze
- Board name: HTML entities in name → displayed as text, not rendered as HTML
State Store Resilience
- Property: for any sequence of store actions (create, update, delete, refresh), the store ends in a consistent state
- Property: for any API error response, the store handles it without throwing an unhandled exception
Implementation Notes
Backend
- Use FsCheck or manual random generators for C# property tests
- Existing fuzz pattern in `Taskdeck.Application.Tests/Fuzz/` can be extended
- For API-level fuzzing: send random JSON bodies to endpoints, verify response is always valid `ApiErrorResponse` (never 500 with stack trace)
- Consider a "no 500s" meta-test: for any well-formed request with random content, the API never returns 500
Frontend
- Use fast-check for JavaScript property-based testing
- Focus on components that render user-provided content: card titles, descriptions, chat messages
Success Criteria
- No 500 Internal Server Error from any random input
- No unhandled exceptions in frontend from any random input
- No data corruption from any random input sequence
- All error responses have valid `ApiErrorResponse` shape
Considerations
Context
Existing fuzz tests cover starter-pack manifests, LLM intent classification, and export/import contracts. This issue expands adversarial input testing to more system boundaries — the places where user input enters the system and where the system must not break regardless of what it receives.
Candidate Surfaces for Property-Based / Fuzz Testing
Backend
API Request Bodies (adversarial JSON)
Domain Entity Construction
JSON Serialization Round-Trip
SQLite Query Boundary Values
Frontend
Input Sanitization
State Store Resilience
Implementation Notes
Backend
Frontend
Success Criteria
Considerations