Skip to content
This repository was archived by the owner on Mar 9, 2026. It is now read-only.

Commit a6aeda4

Browse files
roottoolclaude
andauthored
refactor(skills): trim boundary-validator SKILL.md to spec (#65)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 06820e6 commit a6aeda4

3 files changed

Lines changed: 23 additions & 1182 deletions

File tree

skills/boundary-validator/SKILL.md

Lines changed: 23 additions & 290 deletions
Original file line numberDiff line numberDiff line change
@@ -1,253 +1,46 @@
11
---
22
name: boundary-validator
33
description: 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

Comments
 (0)