parse-dont-validate
Skill23 starsChanged 32 days agoMITView on GitHub
Preserve invariants in types when changing domain models, input boundaries, or state transitions.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- selamy-labs/agent-skillstheir own version, first seen Nov 8, 2026
- auralshin/coding-skillstheir own version, first seen Aug 27, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- auralshin/coding-skills★ 0same name
- selamy-labs/agent-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository16 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- fsharp-async-compositionSkill
- fsharp-binary-compatibilitySkill
- fsharp-env-capabilitiesSkill
- fsharp-failure-pathsSkill
- fsharp-idiom-reviewSkill
- fsharp-iwsam-errorsSkill
- fsharp-library-api-designSkill
- fsharp-native-aotSkill
- fsharp-nullness-interopSkill
- fsharp-performance-typesSkill
- fsharp-serializationSkill
- fsharp-signature-filesSkill
- fsharp-verify-apiSkill
- optimize-fsharp-typecheck-graphSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 9 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 22
Use distinct types when exchanging two primitive values would cause an error.
- Very specific: line 24
Use constrained types for range or format guarantees.
- Distinctive: line 32
Keep domain values intact through domain operations.
- Distinctive: line 34
Check construction, update, deserialization, persistence-loading, and conversion paths.
- Distinctive: line 43
Keep runtime checks for permissions, concurrency, availability, and other changing external facts.
- Distinctive: line 49
Verify that invalid input produces the required failure.
- Distinctive: line 50
Verify that successful parsing produces the type required by consumers.
- Distinctive: line 51
Check that supported APIs cannot bypass construction.
- Distinctive: line 52
Check that updates preserve the invariant.
- Distinctive: line 53
Remove repeated checks only when the type guarantees the checked property.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Parse, Don't Validate
Parse raw input into domain values before effects depend on valid input. Make downstream functions consume those values instead of repeating checks on primitives.
Model the invariant
- Identify the invariant that the consumer requires.
- Choose a representation that preserves the invariant.
- Trace callers to the input boundary.
- Refine a value when a constraint applies only to one branch.
- Introduce a type only when it prevents a concrete error or expresses a domain distinction.
- Name each type for the guarantee that it establishes.
In F#, use records for values that must exist together. Use discriminated unions for alternatives or state-specific data.
Use distinct types when exchanging two primitive values would cause an error. Reuse suitable domain types.
Use constrained types for range or format guarantees. Enforce smart constructors through private representations or .fsi signatures.
Return Result<DomainValue, ParseError> when callers need failure details. Use option when absence gives sufficient information.
Represent a non-empty collection with a required head and a tail. Use units of measure for dimensions, not range constraints.
Preserve the guarantee
- Keep domain values intact through domain operations.
- Extract primitives only for serialization, display, or operations that require them.
- Check construction, update, deserialization, persistence-loading, and conversion paths.
- Make each operation preserve the invariant or return an explicit failure.
- Separate raw transport data from domain values when serializers bypass constructors.
- Preserve existing storage and wire contracts unless the user requests changes.
Reject invalid input according to the domain rules. Normalize, truncate, deduplicate, or substitute defaults only when the contract permits it.
Handle each state explicitly when a handler accepts all states. Consider accepting a state-specific type when an operation requires one state.
Keep runtime checks for permissions, concurrency, availability, and other changing external facts. A parsed value cannot permanently prove these facts.
A formatted email address does not prove ownership or deliverability.
Verify the result
- Verify that invalid input produces the required failure.
- Verify that successful parsing produces the type required by consumers.
- Check that supported APIs cannot bypass construction.
- Check that updates preserve the invariant.
- Remove repeated checks only when the type guarantees the checked property.
- Report remaining runtime checks and construction paths that bypass the guarantee.
Sources: Parse, Don't Validate and Designing with Types.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

