Ensure accessibility in UI components including semantic HTML, ARIA attributes, keyboard navigation, and WCAG 2.2 AA compliance.
日本語の概要は準備中です。原文の説明を表示しています。
Living catalogue of 7 known hazard entries (SE-01 through SE-07) specific to agent-studio: Windows backslash paths, prototype pollution, hook exit codes, async swallowing, ReDoS in glob-to-regex, DST arithmetic, array mutation during iteration. Each entry: symptom, root cause, fix, test assertion.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Living catalogue of confirmed hazard patterns in agent-studio. Each entry documents a real bug we've shipped. Invoke this skill during debugging and code review to check against known failure modes.
Symptom: Glob patterns match correctly in CI (Linux) but silently fail on developer machines (Windows).
Root cause: path.relative() returns backslash-separated paths on Windows (node_modules\foo), but glob patterns use forward slashes. [^/]* in regex won't block \.
Fix:
// ALWAYS normalize before regex matching
const rel = path.relative(root, filePath).replace(/\\/g, '/');
Test assertion:
assert(normalizePath('a\\b\\c') === 'a/b/c');
assert(!normalizePath('a\\b').includes('\\'));
Files affected: .claude/lib/utils/path-constants.cjs, any glob-based exclusion logic.
Symptom: Object.prototype gains unexpected properties after parsing malformed JSON from hook input or agent memory.
Root cause: JSON.parse('{"__proto__":{"isAdmin":true}}') silently mutates Object.prototype in older Node.js versions or when objects are created via Object.create(null) checks are missed.
Fix:
// Use safeParseJSON — strips __proto__, constructor, prototype keys
const { safeParseJSON } = require('.claude/lib/utils/safe-json.cjs');
const { success, data } = safeParseJSON(rawInput, {});
Test assertion:
const before = Object.getPrototypeOf({});
safeParseJSON('{"__proto__":{"evil":true}}', {});
assert(!{}.evil);
Files affected: Any hook that calls JSON.parse() on stdin input.
Symptom: Hook appears to "block" when it should allow, or silently "allows" when it should block.
Root cause: Hooks use exit codes 0 (allow) and 2 (block). Using process.exit(1) or process.exit(true) does not block — it produces unexpected behavior.
Fix:
// CORRECT
if (shouldBlock) process.exit(2); // Block tool execution
process.exit(0); // Allow tool execution
// WRONG
if (shouldBlock) process.exit(1); // Not a valid block code
process.exit(false); // Not valid
Test assertion:
// Mock hook execution and verify exit code
const result = execHook(input);
assert(result.exitCode === 0 || result.exitCode === 2);
Files affected: All hooks in .claude/hooks/.
Symptom: One failing async operation silently causes all results to be lost; agent believes all tasks succeeded.
Root cause: Promise.all([...]) rejects on the first failure and discards all other results. When wrapped in try/catch that returns [], the caller sees empty results with no error.
Fix:
// Use Promise.allSettled to get partial results
const results = await Promise.allSettled(tasks);
const succeeded = results.filter(r => r.status === 'fulfilled').map(r => r.value);
const failed = results.filter(r => r.status === 'rejected').map(r => r.reason);
return { succeeded, failed, partial: failed.length > 0 };
Test assertion:
const tasks = [resolvesWith('ok'), rejectsWith('error'), resolvesWith('ok2')];
const result = await safeAllSettled(tasks);
assert(result.succeeded.length === 2);
assert(result.failed.length === 1);
Symptom: Glob pattern matching hangs or takes exponential time on long path strings.
Root cause: Naive glob-to-regex conversion produces patterns with nested quantifiers like (.*)* or (.+)+ which backtrack exponentially on non-matching strings.
Fix:
// Use anchored, non-backtracking patterns
// BAD: (.*)* -> exponential backtracking
// GOOD: [^/]* -> linear, no backtracking
function globToRegex(glob) {
const escaped = glob.replace(/[.+^${}()|[\]\\]/g, '\\$&');
return escaped
.replace(/\*\*/g, '___DOUBLE___')
.replace(/\*/g, '[^/]*') // Single * -> no path separators
.replace(/___DOUBLE___/g, '.*'); // ** -> any path
}
Test assertion:
const regex = globToRegex('**/*.js');
const longString = 'a'.repeat(10000) + '.ts';
const start = Date.now();
regex.test(longString);
assert(Date.now() - start < 100); // Must complete in <100ms
Symptom: Date calculations are off by 1 hour for events that cross daylight saving time boundaries.
Root cause: Adding 24 60 60 * 1000ms to a timestamp does not always equal "tomorrow" — DST transitions can make a day 23 or 25 hours long.
Fix:
// WRONG: assumes 24h = 1 day
const tomorrow = new Date(date.getTime() + 86400000);
// CORRECT: use date arithmetic, not ms arithmetic
const tomorrow = new Date(date);
tomorrow.setDate(tomorrow.getDate() + 1);
Test assertion:
// Test across a known DST boundary (e.g., March DST change)
const dst = new Date('2026-03-08T01:00:00'); // Day before US spring forward
const nextDay = addDays(dst, 1);
assert(nextDay.getDate() === 9);
assert(nextDay.getHours() === 1); // Same time, next day
Symptom: Items are skipped or processed twice; behavior is non-deterministic.
Root cause: Mutating an array (push, splice, shift) while iterating with forEach or for...of causes the iterator to skip or re-visit elements.
Fix:
// WRONG: mutates during iteration
arr.forEach(item => {
if (condition) arr.push(newItem); // Skips items
});
// CORRECT: collect mutations, apply after
const toAdd = [];
arr.forEach(item => {
if (condition) toAdd.push(newItem);
});
arr.push(...toAdd);
// OR: work on a copy
[...arr].forEach(item => { ... });
Test assertion:
const arr = [1, 2, 3];
const result = safeForEach(arr, item => item * 2);
assert(result.length === 3); // Original not mutated, all items processed
Invoke at the START of any debugging session:
Skill({ skill: 'sharp-edges' });
Then match your symptom against SE-01 through SE-07. If your bug is new and reproducible, add it to this catalogue.
Pattern for new entries:
## SE-0N: [Short Title]
**Symptom:** [What you observe]
**Root cause:** [Why it happens]
**Fix:** [Code fix with before/after]
**Test assertion:** [Minimal test that would catch it]
**Files affected:** [Where in agent-studio this applies]
After invoking: if you find a new sharp edge, append it here via technical-writer agent.
Before starting:
Read .claude/context/memory/learnings.md
After completing:
.claude/context/memory/learnings.md.claude/context/memory/issues.md.claude/context/memory/decisions.mdASSUME INTERRUPTION: If it's not in memory, it didn't happen.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Ensure accessibility in UI components including semantic HTML, ARIA attributes, keyboard navigation, and WCAG 2.2 AA compliance.
日本語の概要は準備中です。原文の説明を表示しています。
Use when you want to improve response quality through meta-cognitive reasoning. Applies 15+ reasoning methods to reconsider and refine initial outputs.
日本語の概要は準備中です。原文の説明を表示しています。
N-round opposing-stance debates for trade-off analysis. Assigns pro/con roles to agents, runs structured debate rounds with quality scoring, and produces a moderator synthesis with confidence-rated recommendation. Generalizable to architecture, technology, security, and design decisions.
日本語の概要は準備中です。原文の説明を表示しています。
Force adversarial code review stance that eliminates confirmation bias — reviewer must find issues or re-analyze
日本語の概要は準備中です。原文の説明を表示しています。
Creates specialized AI agents on-demand when no existing agent matches a request. Use when the Router cannot find a suitable agent for a task. Enables self-evolution by generating persistent agents.
日本語の概要は準備中です。原文の説明を表示しています。
LLM-as-judge evaluation framework with 5-dimension rubric (accuracy, groundedness, coherence, completeness, helpfulness) for scoring AI-generated content quality with weighted composite scores and evidence citations
日本語の概要は準備中です。原文の説明を表示しています。