11---
22name : boundary-validator
33description : Validates code changes against safe-formdata's boundary-focused design principles. Detects violations of "keys are opaque", "no silent behavior", "no inference", and "explicit issue reporting". Use when reviewing PRs, implementing features, or checking adherence to design rules.
4- license : MIT
5- compatibility : Designed for Claude Code (or similar products)
6- metadata :
7- author : safe-formdata-project
8- version : " 1.0"
9- source : Extracted from AGENTS.md
10- allowed-tools : Read Grep
114---
125
136# Boundary Validator
147
15- This skill validates code changes against safe-formdata's ** boundary-focused design principles ** .
8+ ## Review Process
169
17- ## When to use this skill
18-
19- Use this skill when:
20-
21- - Creating or reviewing Pull Requests
22- - Implementing new features for safe-formdata
23- - Refactoring existing code
24- - Performing code reviews
25- - Checking adherence to design rules before committing
26-
27- ** Trigger keywords** : code review, PR review, check boundary, validate design, implement, refactor
28-
29- ## What this skill does
30-
31- This skill automatically detects violations of safe-formdata's four core design rules:
32-
33- 1 . ** Keys are opaque strings** - No interpretation of key naming conventions
34- 2 . ** No silent behavior** - No implicit merging or overwriting
35- 3 . ** No inference, no convenience** - No structural inference or type coercion
36- 4 . ** Explicit issue reporting** - Never throw for input-derived errors
37-
38- ## How to use this skill
39-
40- ### Automatic Activation
41-
42- In Claude Code, this skill activates automatically when:
43-
44- - You create a Pull Request
45- - You request a code review
46- - You mention "boundary rules" or "design principles"
47-
48- ### Manual Activation
49-
50- You can explicitly invoke this skill by saying:
51-
52- ```
53- Review this code against boundary-validator rules
54- ```
55-
56- ### Review Process
57-
58- The skill will do the following.
59-
60- 1 . ** Read the changed files** using the Read and Grep tools
61- 2 . ** Check for violations** against the four design rules
62- 3 . ** Report findings** with specific line references and explanations
63- 4 . ** Suggest fixes** aligned with boundary principles
10+ 1 . Read the changed files using the Read and Grep tools
11+ 2 . Check for violations against the four design rules
12+ 3 . Report findings with specific line references and explanations
13+ 4 . Suggest fixes aligned with boundary principles
6414
6515## Validation Criteria
6616
67- ### 1. Keys are opaque strings
68-
69- ** Rule** : Do not interpret key naming conventions.
70-
71- ** Violations to detect** :
72-
73- ``` typescript
74- // ❌ BAD: Parsing bracket notation
75- if (key .endsWith (" []" )) {
76- // array inference logic
77- }
78-
79- // ❌ BAD: Parsing dot notation
80- if (key .includes (" ." )) {
81- // nested object inference
82- }
83-
84- // ❌ BAD: Interpreting key structure
85- const [parent, child] = key .split (" ." );
86- ```
87-
88- ** Correct approach** :
17+ For violation patterns and examples, see [ design-rules.md] ( references/design-rules.md ) .
8918
90- ``` typescript
91- // ✅ GOOD: Treat keys as opaque strings
92- const data = Object .create (null );
93- data [key ] = value ; // No interpretation
94- ```
19+ ### 1. Keys are opaque strings
9520
96- ** Reference ** : See [ design-rules.md ] ( references/design-rules.md#1-keys-are-opaque-strings ) for details .
21+ Do not interpret key naming conventions ( ` [] ` , ` . ` , ` _ ` , etc.). Store keys as-is .
9722
9823### 2. No silent behavior
9924
100- ** Rule** : Do not merge duplicate keys, overwrite values, or apply first-wins/last-wins semantics.
101-
102- ** Violations to detect** :
103-
104- ``` typescript
105- // ❌ BAD: Merging duplicate keys
106- Object .assign (result , newData );
107-
108- // ❌ BAD: Overwriting values
109- data [key ] = value ; // if key exists, this overwrites
110-
111- // ❌ BAD: First-wins logic
112- if (! data [key ]) {
113- data [key ] = value ;
114- }
115-
116- // ❌ BAD: Last-wins logic
117- data [key ] = value ; // always overwrites
118- ```
119-
120- ** Correct approach** :
121-
122- ``` typescript
123- // ✅ GOOD: Report duplicate keys as issues
124- if (seen .has (key )) {
125- issues .push ({
126- code: " duplicate_key" ,
127- key ,
128- });
129- // Do NOT continue processing
130- }
131- ```
132-
133- ** Reference** : See [ design-rules.md] ( references/design-rules.md#2-no-silent-behavior ) for details.
25+ Do not merge duplicate keys, overwrite values, or apply first-wins/last-wins semantics. Report duplicates as ` duplicate_key ` issues.
13426
13527### 3. No inference, no convenience
13628
137- ** Rule** : Do not infer arrays or objects, coerce types, validate values, or add configuration options.
138-
139- ** Violations to detect** :
140-
141- ``` typescript
142- // ❌ BAD: Array inference
143- if (key .endsWith (" []" )) {
144- result [key ] = [];
145- }
146-
147- // ❌ BAD: Type coercion
148- const numValue = Number (value );
149-
150- // ❌ BAD: Value validation
151- if (! isValidEmail (value )) {
152- throw new Error (" Invalid email" );
153- }
154-
155- // ❌ BAD: Configuration options
156- function parse(formData , options = {}) {
157- if (options .allowDuplicates ) {
158- /* ... */
159- }
160- }
161- ```
162-
163- ** Correct approach** :
164-
165- ``` typescript
166- // ✅ GOOD: No inference, no validation
167- const data = Object .create (null );
168- data [key ] = value ; // Store as-is (string or File)
169- ```
170-
171- ** Reference** : See [ design-rules.md] ( references/design-rules.md#3-no-inference-no-convenience ) for details.
29+ Do not infer arrays or objects, coerce types, validate values, or add configuration options.
17230
17331### 4. Explicit issue reporting
17432
175- ** Rule** : Never throw for input-derived errors. Always return a ParseResult with issues.
176-
177- ** Violations to detect** :
178-
179- ``` typescript
180- // ❌ BAD: Throwing exceptions
181- if (invalidKey ) {
182- throw new Error (' Invalid key' );
183- }
184-
185- // ❌ BAD: Partial success
186- return {
187- data: partialData , // Some keys processed
188- issues: [... ] // Some keys failed
189- };
190- ```
191-
192- ** Correct approach** :
193-
194- ``` typescript
195- // ✅ GOOD: Return null data when issues exist
196- if (issues .length > 0 ) {
197- return {
198- data: null ,
199- issues ,
200- };
201- }
202-
203- return {
204- data ,
205- issues: [],
206- };
207- ```
208-
209- ** Reference** : See [ design-rules.md] ( references/design-rules.md#4-explicit-issue-reporting ) for details.
33+ Never throw for input-derived errors. Return ` { data: null, issues } ` when any issue exists.
21034
21135## Additional Checks
21236
213- ### Security Rules
214-
215- ** Prototype safety** :
216-
217- ``` typescript
218- // ✅ GOOD: Reject forbidden keys
219- const FORBIDDEN_KEYS = [" __proto__" , " constructor" , " prototype" ];
220- if (FORBIDDEN_KEYS .includes (key )) {
221- issues .push ({
222- code: " forbidden_key" ,
223- key ,
224- });
225- }
226-
227- // ✅ GOOD: Use prototype-less objects
228- const data = Object .create (null ); // Not {}
229- ```
230-
231- ** Reference** : See [ security-rules.md] ( references/security-rules.md ) for details.
232-
233- ### API Contract
234-
235- ** IssueCode stability**
236-
237- - No new IssueCode values without major version bump
238- - Existing codes: ` invalid_key ` , ` forbidden_key ` , ` duplicate_key `
239-
240- ** ParseResult type**
241-
242- - Must be a discriminated union
243- - ` data !== null ` for type narrowing
244- - No ` .ok ` property
37+ ** Security** : Reject ` __proto__ ` , ` constructor ` , ` prototype ` as ` forbidden_key ` . Use ` Object.create(null) ` for data. See [ security-rules.md] ( references/security-rules.md ) .
24538
246- ** Reference ** : See [ api-contract.md] ( references/api-contract.md ) for details .
39+ ** API contract ** : No new ` IssueCode ` values without major version bump. ` ParseResult ` must be a discriminated union; use ` data !== null ` for type narrowing. No ` .ok ` property. See [ api-contract.md] ( references/api-contract.md ) .
24740
24841## Review Output Format
24942
250- When violations are found, report them in this format:
43+ When violations are found, report findings in this format:
25144
25245``` markdown
25346## Boundary Validation Results
@@ -266,85 +59,25 @@ result[key.slice(0, -2)] = [];
26659\`\`\`
26760** Suggestion** : Remove array inference. Treat ` key ` as opaque string.
26861
269- #### src/parser.ts:78
270-
271- ** Rule** : No silent behavior
272- ** Issue** : Duplicate keys are overwritten (last-wins)
273- ** Code** :
274- \`\`\` typescript
275- data[ key] = value; // Overwrites existing key
276- \`\`\`
277- ** Suggestion** : Check for duplicates and report as ` duplicate_key ` issue.
278-
27962### ✅ Design Principles Followed
28063
28164- ✅ Uses ` Object.create(null) ` for data container
28265- ✅ Reports forbidden keys (` __proto__ ` , ` constructor ` , ` prototype ` )
28366- ✅ Returns ParseResult with ` data: null ` when issues exist
28467```
28568
286- ## File References
69+ ## Scope
28770
288- For detailed rules and patterns, see:
71+ Validates ** implementation code** (e.g., ` src/parse.ts ` ). Does not flag:
72+
73+ - Tests, documentation, or configuration files
74+ - Performance optimizations (unless they compromise correctness)
75+ - Code style preferences (use linter)
76+ - Out-of-scope feature requests (design discussions, not violations)
77+
78+ ## File References
28979
29080- [ design-rules.md] ( references/design-rules.md ) - Complete design rules from AGENTS.md
29181- [ security-rules.md] ( references/security-rules.md ) - Security implementation requirements
29282- [ api-contract.md] ( references/api-contract.md ) - API stability constraints
29383- [ validation-patterns.md] ( references/validation-patterns.md ) - Concrete violation patterns
294-
295- ## Examples
296-
297- See the ` examples/ ` directory for:
298-
299- - [ good-code.md] ( examples/good-code.md ) - ✅ Correct implementations
300- - [ bad-code.md] ( examples/bad-code.md ) - ❌ Common violations
301-
302- ## Important Notes
303-
304- ### Scope
305-
306- This skill validates ** implementation code** (e.g., ` src/parse.ts ` ), not:
307-
308- - Tests (though test logic should also follow principles)
309- - Documentation
310- - Configuration files
311-
312- ### Non-Goals
313-
314- Do ** not** flag these as violations:
315-
316- - Performance optimizations (unless they compromise correctness)
317- - Code style preferences (use linter for that)
318- - Feature requests that are out of scope (those are design discussions, not violations)
319-
320- ### Philosophy
321-
322- The boundary-focused approach prioritizes:
323-
324- 1 . ** Correctness** over convenience
325- 2 . ** Explicitness** over inference
326- 3 . ** Stability** over features
327-
328- When in doubt, consult [ AGENTS.md] ( ../../AGENTS.md ) section "Review rule of thumb":
329-
330- > If a change makes the parser smarter, more convenient, or more opinionated, it likely violates the boundary.
331-
332- ## Limitations
333-
334- - ** Context required** : This skill needs to read source code files
335- - ** Human judgment** : Final decision on edge cases remains with humans
336- - ** False positives** : Some patterns may be flagged incorrectly - use judgment
337-
338- ## Versioning
339-
340- This skill follows AGENTS.md. When AGENTS.md is updated:
341-
342- 1 . Update the corresponding reference files in ` references/ `
343- 2 . Increment the ` metadata.version ` in this frontmatter
344- 3 . Test with actual code reviews
345-
346- ---
347-
348- ** Current version** : 1.0
349- ** Source** : Extracted from [ AGENTS.md] ( ../../AGENTS.md )
350- ** License** : MIT (see [ LICENSE.txt] ( LICENSE.txt ) )
0 commit comments