## 概要 既存のスタンス/インストラクションに埋め込まれているフロントエンド・バックエンド等の専門知識をknowledgeファイルとして抽出し、抽出元に適切に付与する。 --- ## タスク ### 1. 専門知識の抽出(優先度: 高) 既存のスタンス・インストラクションファイルをレビューし、以下の専門知識を特定・抽出: - **フロントエンド知識**(React、CSS、UI/UXなど) - **バックエンド知識**(API設計、DB、サーバーサイドなど) - **その他の専門知識**(発見したもの) 抽出した知識をknowledgeファイルとして作成する。 ### 2. 抽出元への付与(優先度: 高) 抽出した知識を、元々その知識を使用していたスタンス/インストラクションに付与設定する。 - 抽出元 = 付与先 --- ## 確認方法 - 抽出後、元のスタンス/インストラクションから専門知識が分離されていること - 抽出元にknowledgeが正しく付与設定されていること
428 lines
14 KiB
Markdown
428 lines
14 KiB
Markdown
# Architecture Knowledge
|
|
|
|
## Structure & Design
|
|
|
|
**File Organization:**
|
|
|
|
| Criteria | Judgment |
|
|
|----------|----------|
|
|
| Single file > 200 lines | Consider splitting |
|
|
| Single file > 300 lines | REJECT |
|
|
| Single file with multiple responsibilities | REJECT |
|
|
| Unrelated code coexisting | REJECT |
|
|
|
|
**Module Structure:**
|
|
|
|
- High cohesion: Related functionality grouped together
|
|
- Low coupling: Minimal inter-module dependencies
|
|
- No circular dependencies
|
|
- Appropriate directory hierarchy
|
|
|
|
**Function Design:**
|
|
|
|
- One responsibility per function
|
|
- Consider splitting functions over 30 lines
|
|
- Side effects clearly defined
|
|
|
|
**Layer Design:**
|
|
|
|
- Dependency direction: Upper layers -> Lower layers (reverse prohibited)
|
|
- Controller -> Service -> Repository flow maintained
|
|
- 1 interface = 1 responsibility (no giant Service classes)
|
|
|
|
**Directory Structure:**
|
|
|
|
Structure pattern selection:
|
|
|
|
| Pattern | Use Case | Example |
|
|
|---------|----------|---------|
|
|
| Layered | Small scale, CRUD-centric | `controllers/`, `services/`, `repositories/` |
|
|
| Vertical Slice | Medium-large scale, high feature independence | `features/auth/`, `features/order/` |
|
|
| Hybrid | Common foundation + feature modules | `core/` + `features/` |
|
|
|
|
Vertical Slice Architecture (organizing code by feature):
|
|
|
|
```
|
|
src/
|
|
├── features/
|
|
│ ├── auth/
|
|
│ │ ├── LoginCommand.ts
|
|
│ │ ├── LoginHandler.ts
|
|
│ │ ├── AuthRepository.ts
|
|
│ │ └── auth.test.ts
|
|
│ └── order/
|
|
│ ├── CreateOrderCommand.ts
|
|
│ ├── CreateOrderHandler.ts
|
|
│ └── ...
|
|
└── shared/ # Shared across features
|
|
├── database/
|
|
└── middleware/
|
|
```
|
|
|
|
Vertical Slice criteria:
|
|
|
|
| Criteria | Judgment |
|
|
|----------|----------|
|
|
| Single feature spans 3+ layers | Consider slicing |
|
|
| Minimal inter-feature dependencies | Recommend slicing |
|
|
| Over 50% shared processing | Keep layered |
|
|
| Team organized by features | Slicing required |
|
|
|
|
Prohibited patterns:
|
|
|
|
| Pattern | Problem |
|
|
|---------|---------|
|
|
| Bloated `utils/` | Becomes graveyard of unclear responsibilities |
|
|
| Lazy placement in `common/` | Dependencies become unclear |
|
|
| Excessive nesting (4+ levels) | Navigation difficulty |
|
|
| Mixed features and layers | `features/services/` prohibited |
|
|
|
|
**Separation of Concerns:**
|
|
|
|
- Read and write responsibilities separated
|
|
- Data fetching at root (View/Controller), passed to children
|
|
- Error handling centralized (no try-catch scattered everywhere)
|
|
- Business logic not leaking into Controller/View
|
|
|
|
## Code Quality Detection
|
|
|
|
**Explanatory Comment (What/How) Detection Criteria:**
|
|
|
|
Detect comments that simply restate code behavior in natural language.
|
|
|
|
| Judgment | Criteria |
|
|
|----------|----------|
|
|
| REJECT | Restates code behavior in natural language |
|
|
| REJECT | Repeats what is already obvious from function/variable names |
|
|
| REJECT | JSDoc that only paraphrases the function name without adding information |
|
|
| OK | Explains why a particular implementation was chosen |
|
|
| OK | Explains the reason behind seemingly unusual behavior |
|
|
| Best | No comment needed — the code itself communicates intent |
|
|
|
|
```typescript
|
|
// REJECT - Restates code (What)
|
|
// If interrupted, abort immediately
|
|
if (status === 'interrupted') {
|
|
return ABORT_STEP;
|
|
}
|
|
|
|
// REJECT - Restates the loop
|
|
// Check transitions in order
|
|
for (const transition of step.transitions) {
|
|
|
|
// REJECT - Repeats the function name
|
|
/** Check if status matches transition condition. */
|
|
export function matchesCondition(status: Status, condition: TransitionCondition): boolean {
|
|
|
|
// OK - Design decision (Why)
|
|
// User interruption takes priority over piece-defined transitions
|
|
if (status === 'interrupted') {
|
|
return ABORT_STEP;
|
|
}
|
|
|
|
// OK - Reason behind seemingly odd behavior
|
|
// stay can cause loops, but is only used when explicitly specified by the user
|
|
return step.name;
|
|
```
|
|
|
|
**Direct State Mutation Detection Criteria:**
|
|
|
|
Detect direct mutation of arrays or objects.
|
|
|
|
```typescript
|
|
// REJECT - Direct array mutation
|
|
const steps: Step[] = getSteps();
|
|
steps.push(newStep); // Mutates original array
|
|
steps.splice(index, 1); // Mutates original array
|
|
steps[0].status = 'done'; // Nested object also mutated directly
|
|
|
|
// OK - Immutable operations
|
|
const withNew = [...steps, newStep];
|
|
const without = steps.filter((_, i) => i !== index);
|
|
const updated = steps.map((s, i) =>
|
|
i === 0 ? { ...s, status: 'done' } : s
|
|
);
|
|
|
|
// REJECT - Direct object mutation
|
|
function updateConfig(config: Config) {
|
|
config.logLevel = 'debug'; // Mutates argument directly
|
|
config.steps.push(newStep); // Nested mutation too
|
|
return config;
|
|
}
|
|
|
|
// OK - Returns new object
|
|
function updateConfig(config: Config): Config {
|
|
return {
|
|
...config,
|
|
logLevel: 'debug',
|
|
steps: [...config.steps, newStep],
|
|
};
|
|
}
|
|
```
|
|
|
|
## Security (Basic Checks)
|
|
|
|
- Injection prevention (SQL, Command, XSS)
|
|
- User input validation
|
|
- Hardcoded sensitive information
|
|
|
|
## Testability
|
|
|
|
- Dependency injection enabled
|
|
- Mockable design
|
|
- Tests are written
|
|
|
|
## Anti-Pattern Detection
|
|
|
|
REJECT when these patterns are found:
|
|
|
|
| Anti-Pattern | Problem |
|
|
|--------------|---------|
|
|
| God Class/Component | Single class with too many responsibilities |
|
|
| Feature Envy | Frequently accessing other modules' data |
|
|
| Shotgun Surgery | Single change ripples across multiple files |
|
|
| Over-generalization | Variants and extension points not currently needed |
|
|
| Hidden Dependencies | Child components implicitly calling APIs etc. |
|
|
| Non-idiomatic | Custom implementation ignoring language/FW conventions |
|
|
|
|
## Abstraction Level Evaluation
|
|
|
|
**Conditional Branch Proliferation Detection:**
|
|
|
|
| Pattern | Judgment |
|
|
|---------|----------|
|
|
| Same if-else pattern in 3+ places | Abstract with polymorphism → REJECT |
|
|
| switch/case with 5+ branches | Consider Strategy/Map pattern |
|
|
| Flag arguments changing behavior | Split into separate functions → REJECT |
|
|
| Type-based branching (instanceof/typeof) | Replace with polymorphism → REJECT |
|
|
| Nested conditionals (3+ levels) | Early return or extract → REJECT |
|
|
|
|
**Abstraction Level Mismatch Detection:**
|
|
|
|
| Pattern | Problem | Fix |
|
|
|---------|---------|-----|
|
|
| Low-level details in high-level processing | Hard to read | Extract details to functions |
|
|
| Mixed abstraction levels in one function | Cognitive load | Align to same granularity |
|
|
| DB operations mixed with business logic | Responsibility violation | Separate to Repository layer |
|
|
| Config values mixed with processing logic | Hard to change | Externalize configuration |
|
|
|
|
**Good Abstraction Examples:**
|
|
|
|
```typescript
|
|
// Proliferating conditionals
|
|
function process(type: string) {
|
|
if (type === 'A') { /* process A */ }
|
|
else if (type === 'B') { /* process B */ }
|
|
else if (type === 'C') { /* process C */ }
|
|
// ...continues
|
|
}
|
|
|
|
// Abstract with Map pattern
|
|
const processors: Record<string, () => void> = {
|
|
A: processA,
|
|
B: processB,
|
|
C: processC,
|
|
};
|
|
function process(type: string) {
|
|
processors[type]?.();
|
|
}
|
|
```
|
|
|
|
```typescript
|
|
// Mixed abstraction levels
|
|
function createUser(data: UserData) {
|
|
// High level: business logic
|
|
validateUser(data);
|
|
// Low level: DB operation details
|
|
const conn = await pool.getConnection();
|
|
await conn.query('INSERT INTO users...');
|
|
conn.release();
|
|
}
|
|
|
|
// Aligned abstraction levels
|
|
function createUser(data: UserData) {
|
|
validateUser(data);
|
|
await userRepository.save(data); // Details hidden
|
|
}
|
|
```
|
|
|
|
## Workaround Detection
|
|
|
|
Don't overlook compromises made to "just make it work."
|
|
|
|
| Pattern | Example |
|
|
|---------|---------|
|
|
| Unnecessary package additions | Mystery libraries added just to make things work |
|
|
| Test deletion/skipping | `@Disabled`, `.skip()`, commented out |
|
|
| Empty implementations/stubs | `return null`, `// TODO: implement`, `pass` |
|
|
| Mock data in production | Hardcoded dummy data |
|
|
| Swallowed errors | Empty `catch {}`, `rescue nil` |
|
|
| Magic numbers | Unexplained `if (status == 3)` |
|
|
|
|
## Strict TODO Comment Prohibition
|
|
|
|
"We'll do it later" never gets done. What's not done now is never done.
|
|
|
|
TODO comments are immediate REJECT.
|
|
|
|
```kotlin
|
|
// REJECT - Future-looking TODO
|
|
// TODO: Add authorization check by facility ID
|
|
fun deleteCustomHoliday(@PathVariable id: String) {
|
|
deleteCustomHolidayInputPort.execute(input)
|
|
}
|
|
|
|
// APPROVE - Implement now
|
|
fun deleteCustomHoliday(@PathVariable id: String) {
|
|
val currentUserFacilityId = getCurrentUserFacilityId()
|
|
val holiday = findHolidayById(id)
|
|
require(holiday.facilityId == currentUserFacilityId) {
|
|
"Cannot delete holiday from another facility"
|
|
}
|
|
deleteCustomHolidayInputPort.execute(input)
|
|
}
|
|
```
|
|
|
|
Only acceptable TODO cases:
|
|
|
|
| Condition | Example | Judgment |
|
|
|-----------|---------|----------|
|
|
| External dependency prevents implementation + Issued | `// TODO(#123): Implement after API key obtained` | Acceptable |
|
|
| Technical constraint prevents + Issued | `// TODO(#456): Waiting for library bug fix` | Acceptable |
|
|
| "Future implementation", "add later" | `// TODO: Add validation` | REJECT |
|
|
| "No time for now" | `// TODO: Refactor` | REJECT |
|
|
|
|
Correct handling:
|
|
- Needed now → Implement now
|
|
- Not needed now → Delete the code
|
|
- External blocker → Create issue and include ticket number in comment
|
|
|
|
## DRY Violation Detection
|
|
|
|
Detect duplicate code.
|
|
|
|
| Pattern | Judgment |
|
|
|---------|----------|
|
|
| Same logic in 3+ places | Immediate REJECT - Extract to function/method |
|
|
| Same validation in 2+ places | Immediate REJECT - Extract to validator function |
|
|
| Similar components 3+ | Immediate REJECT - Create shared component |
|
|
| Copy-paste derived code | Immediate REJECT - Parameterize or abstract |
|
|
|
|
AHA principle (Avoid Hasty Abstractions) balance:
|
|
- 2 duplications → Wait and see
|
|
- 3 duplications → Extract immediately
|
|
- Different domain duplications → Don't abstract (e.g., customer validation vs admin validation are different)
|
|
|
|
## Spec Compliance Verification
|
|
|
|
Verify that changes comply with the project's documented specifications.
|
|
|
|
Verification targets:
|
|
|
|
| Target | What to Check |
|
|
|--------|---------------|
|
|
| CLAUDE.md / README.md | Conforms to schema definitions, design principles, constraints |
|
|
| Type definitions / Zod schemas | New fields reflected in schemas |
|
|
| YAML/JSON config files | Follows documented format |
|
|
|
|
Specific checks:
|
|
|
|
1. When config files (YAML, etc.) are modified or added:
|
|
- Cross-reference with schema definitions in CLAUDE.md, etc.
|
|
- No ignored or invalid fields present
|
|
- No required fields missing
|
|
|
|
2. When type definitions or interfaces are modified:
|
|
- Documentation schema descriptions are updated
|
|
- Existing config files are compatible with new schema
|
|
|
|
REJECT when these patterns are found:
|
|
|
|
| Pattern | Problem |
|
|
|---------|---------|
|
|
| Fields not in the spec | Ignored or unexpected behavior |
|
|
| Invalid values per spec | Runtime error or silently ignored |
|
|
| Violation of documented constraints | Against design intent |
|
|
|
|
## Call Chain Verification
|
|
|
|
When new parameters/fields are added, verify not just the changed file but also callers.
|
|
|
|
Verification steps:
|
|
1. When finding new optional parameters or interface fields, `Grep` all callers
|
|
2. Check if all callers pass the new parameter
|
|
3. If fallback value (`?? default`) exists, verify if fallback is used as intended
|
|
|
|
Danger patterns:
|
|
|
|
| Pattern | Problem | Detection |
|
|
|---------|---------|-----------|
|
|
| `options.xxx ?? fallback` where all callers omit `xxx` | Feature implemented but always falls back | grep callers |
|
|
| Tests set values directly with mocks | Don't go through actual call chain | Check test construction |
|
|
| `executeXxx()` doesn't receive `options` it uses internally | No route to pass value from above | Check function signature |
|
|
|
|
```typescript
|
|
// Missing wiring: No route to receive projectCwd
|
|
export async function executePiece(config, cwd, task) {
|
|
const engine = new PieceEngine(config, cwd, task); // No options
|
|
}
|
|
|
|
// Wired: Can pass projectCwd
|
|
export async function executePiece(config, cwd, task, options?) {
|
|
const engine = new PieceEngine(config, cwd, task, options);
|
|
}
|
|
```
|
|
|
|
Logically dead code due to caller constraints:
|
|
|
|
Call chain verification applies not only to "missing wiring" but also to the reverse — unnecessary guards for conditions that callers already guarantee.
|
|
|
|
| Pattern | Problem | Detection |
|
|
|---------|---------|-----------|
|
|
| TTY check when all callers require TTY | Unreachable branch remains | grep all callers' preconditions |
|
|
| Null guard when callers already check null | Redundant defense | Trace caller constraints |
|
|
| Runtime type check when TypeScript types constrain | Not trusting type safety | Check TypeScript type constraints |
|
|
|
|
Verification steps:
|
|
1. When finding defensive branches (TTY check, null guard, etc.), grep all callers
|
|
2. If all callers already guarantee the condition, guard is unnecessary → REJECT
|
|
3. If some callers don't guarantee it, keep the guard
|
|
|
|
## Quality Attributes
|
|
|
|
| Attribute | Review Point |
|
|
|-----------|--------------|
|
|
| Scalability | Design handles increased load |
|
|
| Maintainability | Easy to modify and fix |
|
|
| Observability | Logging and monitoring enabled |
|
|
|
|
## Big Picture
|
|
|
|
Don't get lost in minor "clean code" nitpicks.
|
|
|
|
Verify:
|
|
- How will this code evolve in the future
|
|
- Is scaling considered
|
|
- Is technical debt being created
|
|
- Does it align with business requirements
|
|
- Is naming consistent with the domain
|
|
|
|
## Change Scope Assessment
|
|
|
|
Check change scope and include in report (non-blocking).
|
|
|
|
| Scope Size | Lines Changed | Action |
|
|
|------------|---------------|--------|
|
|
| Small | ~200 lines | Review as-is |
|
|
| Medium | 200-500 lines | Review as-is |
|
|
| Large | 500+ lines | Continue review. Suggest splitting if possible |
|
|
|
|
Note: Some tasks require large changes. Don't REJECT based on line count alone.
|
|
|
|
Verify:
|
|
- Changes are logically cohesive (no unrelated changes mixed in)
|
|
- Coder's scope declaration matches actual changes
|
|
|
|
Include as suggestions (non-blocking):
|
|
- If splittable, present splitting proposal
|