chore(brain): ASTRA 성장 자산 동기화 — 기능 인벤토리·growth(약점프로필/학습큐)·일화기억·장기기억·회의록 원문

This commit is contained in:
2026-06-12 16:37:41 +09:00
parent a97fc7be07
commit 89fb05a28a
781 changed files with 138546 additions and 47 deletions
@@ -0,0 +1,144 @@
---
id: wiki-2026-0508-acid-transactions
title: ACID Transactions
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [ACID, Database Transactions, Atomicity Consistency Isolation Durability]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [database, transactions, consistency, postgres]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: sql
framework: postgres-17
---
# ACID Transactions
## 매 한 줄
> **"Atomicity / Consistency / Isolation / Durability — 매 transaction 의 four guarantees."** Härder & Reuter (1983) 가 정식화한 properties. 매 RDBMS (Postgres, Oracle, MySQL InnoDB) 의 default 보장이며, 2026 distributed era 에도 매 NewSQL (CockroachDB, Spanner, TiDB, Neon) 가 매 ACID across nodes 를 표방. 매 단일 transaction 이 매 multi-statement 의 all-or-nothing + isolated + persisted 를 보장.
## 매 핵심
### 매 4 properties
- **Atomicity**: 매 all statements commit or all rollback. 매 partial state 없음.
- **Consistency**: 매 transaction 종료 시 매 모든 invariant (FK, check, unique) 가 valid.
- **Isolation**: 매 concurrent transactions 가 매 serially executed 처럼 보임. 매 isolation level 로 trade-off.
- **Durability**: 매 commit 후 매 crash / power loss 에도 매 data 가 살아남음 (WAL → fsync).
### 매 Isolation levels (SQL standard + Postgres)
- **Read Uncommitted**: 매 dirty read 허용 (Postgres 는 사실상 RC 로 mapping).
- **Read Committed** (Postgres default): 매 dirty read X, 매 non-repeatable read O.
- **Repeatable Read** (Postgres = snapshot isolation): 매 phantom read 거의 없음, 매 serialization anomaly O.
- **Serializable** (Postgres = SSI): 매 strictest, 매 overhead 큼.
### 매 응용
1. 매 financial / inventory 의 multi-row update.
2. 매 idempotent worker — 매 transaction + unique key.
3. 매 saga compensation 의 단위.
## 💻 패턴
### 1) Postgres BEGIN/COMMIT
```sql
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- 매 atomic + durable
```
### 2) SAVEPOINT 로 partial rollback
```sql
BEGIN;
INSERT INTO orders(id, total) VALUES (1, 50);
SAVEPOINT before_items;
INSERT INTO items(order_id, sku) VALUES (1, 'BAD-SKU'); -- FK 위반
ROLLBACK TO SAVEPOINT before_items;
INSERT INTO items(order_id, sku) VALUES (1, 'OK');
COMMIT;
```
### 3) Isolation level 명시 (Python + asyncpg)
```python
async with conn.transaction(isolation="serializable"):
row = await conn.fetchrow("SELECT balance FROM accounts WHERE id=$1", 1)
await conn.execute("UPDATE accounts SET balance=$1 WHERE id=$2", row["balance"]-100, 1)
# 매 SSI — 매 serialization_failure 시 retry 필요
```
### 4) Optimistic concurrency (version column)
```sql
UPDATE doc SET body = $1, version = version + 1
WHERE id = $2 AND version = $3;
-- 매 affected_rows = 0 → conflict, 매 retry / 사용자 alert
```
### 5) SELECT FOR UPDATE (pessimistic lock)
```sql
BEGIN;
SELECT * FROM accounts WHERE id = 1 FOR UPDATE; -- 매 row lock
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
COMMIT;
```
### 6) Outbox pattern (transaction + async publish)
```sql
BEGIN;
INSERT INTO orders(id, ...) VALUES (...);
INSERT INTO outbox(event_type, payload) VALUES ('OrderCreated', $1);
COMMIT;
-- 매 separate worker 가 outbox 를 읽고 매 broker 로 publish
```
### 7) Retry on serialization failure (Python)
```python
from psycopg.errors import SerializationFailure
for _ in range(5):
try:
with conn.transaction(): do_work()
break
except SerializationFailure:
time.sleep(random.uniform(0, 0.05))
```
## 매 결정 기준
| 상황 | Isolation level |
|---|---|
| 매 read-heavy dashboard | Read Committed |
| 매 report 의 consistent snapshot | Repeatable Read |
| 매 money / counter / unique reservation | Serializable |
| 매 high-conflict hot row | Pessimistic FOR UPDATE |
| 매 low-conflict OLTP | Optimistic version |
**기본값**: Postgres Read Committed + 매 critical path 만 매 Serializable / FOR UPDATE.
## 🔗 Graph
- 변형: [[BASE]] · [[Snapshot Isolation]]
- 응용: [[Idempotency]]
- Adjacent: [[CAP Theorem]]
## 🤖 LLM 활용
**언제**: 매 codegen 의 SQL transaction boundary 검증, 매 isolation level mismatch 점검.
**언제 X**: 매 eventually-consistent NoSQL (DynamoDB single-region) — 매 BASE 모델로 reasoning.
## ❌ 안티패턴
- **App-side "transaction"**: 매 read-modify-write 가 매 BEGIN/COMMIT 밖. 매 race condition.
- **Long transaction**: 매 minutes 단위 hold → 매 lock contention + bloat.
- **Wrong isolation**: 매 default RC 에서 매 lost update 발생, 매 detect 못 함.
- **Ignoring serialization failure**: 매 SSI 에서 매 retry 안 함 → 매 user-facing error.
- **Transaction across services**: 매 distributed XA 시도 → 매 saga 로 대체.
## 🧪 검증 / 중복
- Verified (Postgres 17 docs, Härder & Reuter 1983, Bailis "Highly Available Transactions" 2014).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — ACID + Postgres isolation levels + 7 patterns |
@@ -0,0 +1,184 @@
---
id: wiki-2026-0508-adr-architecture-decision-record
title: ADR (Architecture Decision Records)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [ADR, Architecture Decision Record, Decision Log, Lightweight ADR]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [architecture, documentation, decisions, governance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: markdown
framework: madr
---
# ADR (Architecture Decision Records)
## 매 한 줄
> **"매 architecturally significant decision 을 매 immutable, dated, numbered markdown 파일로 기록하는 lightweight practice."** Michael Nygard 의 2011 blog post 가 origin, 매 이후 MADR / Y-statement 등 variants 가 표준화. 2026 현재 매 GitOps + LLM agent 시대에 매 ADR 은 매 single source of truth — 매 *왜 이 design 인가* 의 history 를 매 codebase 안에 매 living document 로 유지.
## 매 핵심
### 매 5 essential fields (Nygard original)
- **Title**: 매 short, declarative — `0007: Use Postgres for OLTP`.
- **Status**: `proposed | accepted | deprecated | superseded by NNNN`.
- **Context**: 매 forces — 매 problem, 매 constraint, 매 stakeholder.
- **Decision**: 매 actually chosen approach (one paragraph).
- **Consequences**: 매 positive + negative + neutral. 매 honest trade-offs.
### 매 MADR (Markdown ADR) extras
- Decision drivers, considered options, pros/cons of each.
- 매 numbered (`adr/0001-record-architecture-decisions.md`).
- 매 PR 에 포함 — 매 code change 와 매 same review.
### 매 응용
1. 매 framework / DB / cloud provider 선택.
2. 매 API style (REST vs gRPC vs GraphQL).
3. 매 auth, observability, deploy strategy.
4. 매 LLM model / provider 선택.
## 💻 패턴
### 1) Nygard ADR template
```markdown
# 0007. Use Postgres for OLTP
Date: 2026-05-10
Status: Accepted
## Context
We need an OLTP store with strong ACID, JSON support, and managed offerings
across AWS/GCP/Azure. Team size 12. Expected QPS 5k.
## Decision
Adopt Postgres 17 (RDS / Aurora / Cloud SQL / Neon).
## Consequences
+ Mature ecosystem, ACID, JSONB, pgvector.
- Vertical scaling ceiling — needs Citus / sharding past ~30TB.
~ Team will invest in `psql` / pgbouncer expertise.
```
### 2) MADR full template
```markdown
# Use Postgres for OLTP
* Status: Accepted
* Deciders: @alice, @bob, @carol
* Date: 2026-05-10
## Context and Problem Statement
...
## Decision Drivers
* ACID, managed offering, ecosystem
* Cost ceiling at 5k QPS
* Vector search (pgvector)
## Considered Options
* Postgres
* MySQL
* CockroachDB
* DynamoDB
## Decision Outcome
Chosen option: "Postgres", because it dominates on drivers (1) and (3),
and matches (2) within budget.
### Positive Consequences
* JSONB, pgvector, mature tooling
### Negative Consequences
* Sharding burden later
```
### 3) Y-statement (one-liner ADR)
```text
In the context of <use case>,
facing <concern>,
we decided for <option>
to achieve <quality>,
accepting <downside>.
```
### 4) adr-tools (CLI)
```bash
brew install adr-tools
adr init doc/adr
adr new "Use Postgres for OLTP"
adr new -s 7 "Use CockroachDB instead of Postgres" # 매 supersede
adr generate toc > doc/adr/README.md
```
### 5) GitHub PR-based workflow
```bash
git checkout -b adr/0007-postgres
$EDITOR doc/adr/0007-use-postgres-for-oltp.md
git commit -m "ADR-0007: Use Postgres for OLTP"
gh pr create --label adr --reviewer @platform-team
```
### 6) Status transitions
```markdown
# 0007. Use Postgres
Status: Superseded by [0019](0019-use-cockroachdb.md)
```
### 7) LLM-assisted drafting (2026)
```text
You are an ADR scribe. Given a Slack discussion transcript,
output a MADR-format ADR with:
- Decision drivers extracted from the discussion
- All options mentioned with pros/cons
- Status: Proposed
Do not invent options not discussed.
```
### 8) Linking from code
```ts
// See ADR-0007 for why Postgres + pgvector instead of pinecone
import { Pool } from 'pg';
```
## 매 결정 기준
| 상황 | ADR 작성 여부 |
|---|---|
| 매 reversible (1 file 내 결정) | 작성 X |
| 매 cross-team / cross-service impact | 작성 |
| 매 vendor / framework 선택 | 작성 |
| 매 reverse 시 매 1주 이상 cost | 작성 |
| 매 trivial styling | 작성 X (lint config 로) |
**기본값**: 매 "되돌리는 데 1주 이상 걸리면 ADR". 매 Nygard 5-field minimum, 매 큰 결정만 MADR.
## 🔗 Graph
- 부모: [[Architecture Documentation]]
- 응용: [[ATAM]] · [[RFC Process]] · [[C4 Model]]
- Adjacent: [[GitOps]]
## 🤖 LLM 활용
**언제**: 매 design discussion 의 transcript → ADR draft 자동 생성, 매 ADR audit (status 누락 등).
**언제 X**: 매 LLM 이 매 invent 한 driver/option 을 매 사실로 commit X. 매 human verifier 필요.
## ❌ 안티패턴
- **Wiki-only ADR**: 매 codebase 밖 → 매 stale. 매 repo 안에 두고 매 PR 로 review.
- **Mutable ADR**: 매 기존 ADR 을 edit. 매 새 ADR 로 supersede.
- **Decision-only**: 매 Context / Consequences 누락 → 매 6개월 후 매 누구도 이유 모름.
- **Too coarse**: 매 "Use Microservices" — 매 specific 으로 (어떤 service, 매 boundary 어떻게).
- **Too fine**: 매 매 PR 마다 ADR — 매 noise.
## 🧪 검증 / 중복
- Verified (Nygard 2011 blog, MADR spec adr.github.io, Thoughtworks Tech Radar).
- 신뢰도 A.
- 매 [[ADR_(Architecture_Decision_Records)|ADR_(Architecture_Decision_Record)]] 가 매 redirect 로 본 문서를 가리킴.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Nygard + MADR templates + adr-tools workflow |
@@ -0,0 +1,218 @@
---
id: wiki-2026-0508-architectural-constraint-enforce
title: Architectural Constraint Enforcement
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [archunit, dependency-cruiser, fitness-functions]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, fitness-functions, archunit, constraints]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: java
framework: archunit
---
# Architectural Constraint Enforcement
## 매 한 줄
> **"매 architecture 의 자동으로 enforce 한다"**. 매 ArchUnit (2018, Java/Kotlin), Dependency-Cruiser (JS/TS), NetArchTest (.NET), Konsist (Kotlin) 의 fitness function 의 CI 통합. 매 *Building Evolutionary Architectures* (Ford, Parsons, Kua, 2017; 2nd ed 2023) 의 paradigm.
## 매 핵심
### 매 enforced rules (typical)
- **Layer dependency**: 매 controller → service → repository — 매 reverse 의 X.
- **Package isolation**: `domain` 의 framework import 의 X.
- **Naming**: 매 `*Service` class 의 `service` package 의 only.
- **Cyclic dependency**: 매 always X.
- **API surface**: 매 `internal/*` 의 external module 의 import 의 X.
### 매 fitness function categories (Ford)
- **Atomic vs Holistic**: single attribute / system-wide.
- **Triggered vs Continual**: CI gate / runtime probe.
- **Static vs Dynamic**: code analysis / runtime metric.
- **Automated vs Manual**: prefer automated.
### 매 응용
1. CI gate — 매 PR 의 violation 의 block.
2. Refactor safety — 매 large refactor 의 invariant 의 hold.
3. Onboarding — 매 implicit rule 의 explicit code 의 됨.
## 💻 패턴
### ArchUnit — layer enforcement (Java)
```java
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule;
@AnalyzeClasses(packages = "com.acme.banking")
class LayerArchTest {
@ArchTest
static final ArchRule controllers_only_call_services =
classes().that().resideInAPackage("..controller..")
.should().onlyDependOnClassesThat()
.resideInAnyPackage("..controller..", "..service..", "java..", "org.springframework..");
@ArchTest
static final ArchRule no_cycles =
slices().matching("..banking.(*)..").should().beFreeOfCycles();
@ArchTest
static final ArchRule services_named_correctly =
classes().that().resideInAPackage("..service..")
.and().areNotInterfaces()
.should().haveSimpleNameEndingWith("Service");
}
```
### Dependency-Cruiser (TypeScript)
```js
// .dependency-cruiser.cjs
module.exports = {
forbidden: [
{
name: 'no-circular',
severity: 'error',
from: {},
to: { circular: true }
},
{
name: 'domain-pure',
severity: 'error',
from: { path: '^src/domain' },
to: { path: '^(src/infra|node_modules/express)' }
},
{
name: 'no-test-in-prod',
severity: 'error',
from: { pathNot: '\\.test\\.ts$' },
to: { path: '\\.test\\.ts$' }
}
],
options: { tsConfig: { fileName: 'tsconfig.json' } }
};
```
```bash
npx depcruise src --config .dependency-cruiser.cjs
npx depcruise src --output-type dot | dot -T svg > deps.svg
```
### NetArchTest (.NET 8)
```csharp
using NetArchTest.Rules;
using Xunit;
public class ArchitectureTests {
[Fact]
public void Domain_ShouldNotDependOnInfrastructure() {
var result = Types.InAssembly(typeof(Domain.Marker).Assembly)
.That().ResideInNamespace("Acme.Domain")
.ShouldNot().HaveDependencyOn("Acme.Infrastructure")
.GetResult();
Assert.True(result.IsSuccessful, string.Join(",", result.FailingTypeNames ?? []));
}
}
```
### Konsist (Kotlin)
```kotlin
import com.lemonappdev.konsist.api.Konsist
import com.lemonappdev.konsist.api.verify.assertTrue
class CleanArchitectureTest {
@Test
fun `domain layer does not depend on data layer`() {
Konsist.scopeFromProduction()
.files
.filter { it.packagee?.fullyQualifiedName?.contains("domain") == true }
.assertTrue { file ->
file.imports.none { it.name.contains(".data.") }
}
}
}
```
### Go — go-arch-lint
```yaml
# .go-arch-lint.yml
version: 3
workdir: internal
components:
domain: { in: domain/** }
app: { in: app/** }
infra: { in: infra/** }
deps:
domain: {}
app: { mayDependOn: [domain] }
infra: { mayDependOn: [domain, app] }
```
### Python — import-linter
```ini
# .importlinter
[importlinter]
root_package = acme
[importlinter:contract:layers]
name = Layered architecture
type = layers
layers =
acme.api
acme.service
acme.domain
```
### CI integration (GitHub Actions)
```yaml
- name: Architecture tests
run: |
./gradlew archTest
npx depcruise src --config .dependency-cruiser.cjs
lint-imports
```
## 매 결정 기준
| Stack | Tool |
|---|---|
| Java/Kotlin | ArchUnit, Konsist |
| JS/TS | Dependency-Cruiser, eslint-plugin-boundaries |
| .NET | NetArchTest |
| Go | go-arch-lint |
| Python | import-linter |
| Polyglot | Sonargraph, Structure101 (commercial) |
**기본값**: 매 ArchUnit (JVM) / Dependency-Cruiser (Node) — 매 OSS + CI-first.
## 🔗 Graph
- 부모: [[Software Architecture]] · [[Fitness Functions]]
- 변형: [[Static-Analysis]]
- 응용: [[CI-CD]] · [[Architecture_Refactor]]
- Adjacent: [[Architecture Erosion (아키텍처 침식)]] · [[Modular-Monolith]]
## 🤖 LLM 활용
**언제**: 매 plain English rule → ArchUnit/depcruise config 의 translation, 매 violation message 의 fix suggestion.
**언제 X**: 매 architecture 의 design 의 LLM-only delegation — 매 human ownership 의 필수.
## ❌ 안티패턴
- **Test exists, never runs**: 매 CI 의 not wired — 매 dead rule.
- **Over-broad rule**: 매 100% violations 의 noise — 매 graduated rollback (allowlist).
- **Rule without rationale**: 매 ADR-less rule — 매 future deletion 의 blocker.
- **Ignore-list explosion**: 매 exception 의 100+ — 매 architecture 의 already eroded 의 sign.
## 🧪 검증 / 중복
- Verified (Ford et al., *Building Evolutionary Architectures* 2nd ed; ArchUnit user guide).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — fitness functions + ArchUnit/depcruise/NetArchTest patterns |
@@ -0,0 +1,197 @@
---
id: wiki-2026-0508-architecture-description-아키텍처-명세
title: Architecture Description (아키텍처 명세)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Architecture Description, 아키텍처 명세, AD, Software Architecture Document, SAD]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, documentation, c4, 4plus1-view, iso-42010]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: markdown
framework: Structurizr / C4 / arc42
---
# Architecture Description (아키텍처 명세)
## 매 한 줄
> **"매 architecture description 은 system 의 multiple stakeholder concern 을 multiple view 로 documenting"**. ISO/IEC/IEEE 42010 standard 기반 — 매 stakeholder, concern, viewpoint, view, model 의 conceptual chain. 매 modern practice 는 4+1 (Kruchten) → C4 (Brown) → arc42 (Starke) → DAR (Decision Records) 의 layered combination.
## 매 핵심
### 매 ISO/IEC/IEEE 42010 framework
- **Stakeholder**: dev, ops, security, PM, customer — 매 다른 concern.
- **Concern**: performance, security, deployability, cost, regulatory.
- **Viewpoint**: concern 의 lens (e.g., "security viewpoint", "deployment viewpoint").
- **View**: viewpoint 적용 결과의 specific artifact.
- **Model**: view 안의 box-and-line / sequence / state diagram.
### 매 4+1 view (Kruchten 1995, still relevant)
- **Logical view**: domain model, class, package — dev concern.
- **Process view**: runtime behavior, threading, concurrency — perf concern.
- **Development view**: module, layer, build — dev productivity.
- **Physical view**: deployment topology — ops concern.
- **+1 Scenario**: use cases tying 4 views together.
### 매 C4 model (Simon Brown, modern default)
1. **Context (L1)**: system + external actor/system — non-technical stakeholder 용.
2. **Container (L2)**: deployable unit (web app, API, DB) — tech overview.
3. **Component (L3)**: container 내부 module — dev 용.
4. **Code (L4, optional)**: class diagram — auto-gen, rarely manual.
## 💻 패턴
### Structurizr DSL (modern C4 standard, 2026)
```dsl
workspace "BankingApp" {
model {
customer = person "Customer" "A bank customer"
bankingSystem = softwareSystem "Internet Banking" {
webApp = container "Web App" "React SPA" "TypeScript/React"
api = container "API" "REST backend" "Kotlin/Spring"
db = container "Database" "Customer + tx data" "PostgreSQL 16"
webApp -> api "Calls" "HTTPS/JSON"
api -> db "Reads/writes" "JDBC"
}
customer -> webApp "Uses" "HTTPS"
}
views {
systemContext bankingSystem { include * autoLayout }
container bankingSystem { include * autoLayout }
theme default
}
}
```
### arc42 template skeleton (Markdown, 12 sections)
```markdown
# 1. Introduction & Goals
## 1.1 Requirements Overview
## 1.2 Quality Goals (top 3-5)
## 1.3 Stakeholders
# 2. Architecture Constraints
# 3. Context & Scope (C4 L1 here)
# 4. Solution Strategy
# 5. Building Block View (C4 L2/L3)
# 6. Runtime View (sequence / activity)
# 7. Deployment View
# 8. Crosscutting Concepts (security, logging, i18n)
# 9. Architecture Decisions (link to ADRs)
# 10. Quality Requirements (scenarios)
# 11. Risks & Technical Debt
# 12. Glossary
```
### ADR (Architecture Decision Record, Michael Nygard format)
```markdown
# ADR-0042: Use PostgreSQL over MongoDB for tx store
## Status
Accepted (2026-04-15) — supersedes ADR-0021.
## Context
Transactional integrity 의 critical. Document flexibility 의 secondary.
PostgreSQL 16 의 JSONB columns 의 hybrid 의 enable.
## Decision
PostgreSQL 16 with JSONB for flexible attributes.
## Consequences
+ ACID guarantees, mature tooling, strong ecosystem.
- Schema migrations more rigid than Mongo.
- Team needs PG expertise (training budget allocated).
```
### Mermaid C4 diagram (lightweight, GitHub-native)
```mermaid
C4Context
title System Context — Banking
Person(customer, "Customer")
System(banking, "Banking System", "Online banking")
System_Ext(email, "Email System", "SMTP")
Rel(customer, banking, "Uses", "HTTPS")
Rel(banking, email, "Sends notifications", "SMTP")
```
### Architecture-as-code: PlantUML C4 macro
```plantuml
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(user, "User")
System_Boundary(c1, "App") {
Container(spa, "SPA", "React 19")
Container(api, "API", "Kotlin/Ktor")
ContainerDb(db, "DB", "PostgreSQL 16")
}
Rel(user, spa, "Uses", "HTTPS")
Rel(spa, api, "JSON/REST")
Rel(api, db, "JDBC")
@enduml
```
### Quality scenario (ATAM-style, embeddable in AD)
```yaml
scenario: "API survives 10x traffic spike"
source: External users
stimulus: Sudden 10x request burst
artifact: API container
environment: Production, normal ops
response: Auto-scale, no errors >0.1%
response_measure:
- p99 latency < 800ms
- error_rate < 0.1%
- autoscale_lag < 60s
```
### Living docs — auto-extract from code (jQAssistant + Structurizr)
```bash
# Generate Structurizr workspace from code annotations
./gradlew structurizrExport
structurizr-cli push -workspace workspace.dsl \
-id $WORKSPACE_ID -key $API_KEY -secret $API_SECRET
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Greenfield, small-mid team | C4 + arc42 + ADR |
| Enterprise, regulatory | ISO 42010 strict + 4+1 |
| OSS project | Mermaid C4 in README |
| Microservices, many teams | Structurizr DSL + ADR per service |
| Legacy reverse-engineered | Auto-gen (jQAssistant) + manual context |
**기본값**: C4 (Structurizr DSL) + arc42 sections + ADR — 매 modern combination.
## 🔗 Graph
- 부모: [[Software Architecture]]
- 변형: [[C4 Model]] · [[arc42]]
- 응용: [[Architecture_Diagramming_Standards]] · [[Architecture Review (아키텍처 및 설계 리뷰)]]
## 🤖 LLM 활용
**언제**: bootstrap arc42 template from a codebase scan, generate C4 Container diagrams from package structure, draft ADR Context/Consequences from PR descriptions.
**언제 X**: do not let an LLM author quality scenarios without measurable response criteria — vague AI-generated "should be fast" fails ATAM review.
## ❌ 안티패턴
- **Diagram-only AD**: pictures without prose context — stakeholder cannot infer intent.
- **One-view-fits-all**: single deployment diagram trying to satisfy security, perf, dev concerns simultaneously.
- **Stale Visio**: AD frozen on day 1, drifts from implementation within 6 months.
- **Pseudo-UML**: ad-hoc boxes labeled "UML" with no notation discipline.
- **Decision-less AD**: structures documented without WHY — readers cannot evaluate tradeoffs.
## 🧪 검증 / 중복
- Verified (ISO/IEC/IEEE 42010:2022, Kruchten 1995, Brown C4 spec, Starke arc42 v8.2).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full AD spec with C4/4+1/arc42/ADR patterns |
@@ -0,0 +1,198 @@
---
id: wiki-2026-0508-architecture-refactor
title: Architecture Refactor
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [strangler-fig, big-bang-rewrite, modernization]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, refactor, strangler-fig, modernization]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: polyglot
framework: strangler-fig
---
# Architecture Refactor
## 매 한 줄
> **"매 incremental 의 always wins"**. 매 architecture refactor 의 default approach 의 Martin Fowler 의 Strangler Fig (2004) — 매 old system 의 around 의 new system 의 gradual 의 grow. 매 big-bang rewrite 의 historically failure rate >70% (Ousterhout, Brooks). 매 2026 의 typical pattern: 매 monolith → modular monolith → selective service extraction.
## 매 핵심
### 매 refactor strategies
- **Strangler Fig**: 매 facade 의 routing — 매 traffic 의 incrementally 의 new system 의 redirect.
- **Branch by Abstraction**: 매 abstraction layer 의 introduce — 매 dual 의 implementation — 매 old 의 remove.
- **Parallel Run**: 매 old + new 의 동시 실행 — 매 output 의 compare.
- **Big Bang Rewrite**: 매 last resort — 매 only 매 system 의 small + scope 의 frozen 의 가능.
### 매 refactor 의 prerequisite
- **Test coverage**: 매 characterization tests (Feathers) 의 minimum.
- **Observability**: 매 metrics + traces 의 before/after diff.
- **Feature flag**: 매 reversibility 의 prerequisite.
- **ADR**: 매 decision rationale 의 documented.
### 매 응용
1. Monolith → modular monolith — 매 module boundary 의 enforce (ArchUnit).
2. Service extraction — 매 bounded context 의 따라.
3. Database split — 매 most expensive — 매 last 의 do.
4. Framework upgrade — 매 incremental migration.
## 💻 패턴
### Strangler Fig — Nginx routing facade
```nginx
upstream legacy { server legacy.internal:8080; }
upstream new { server new.internal:8080; }
server {
listen 443 ssl;
# New endpoints — gradual rollout
location /api/v2/orders { proxy_pass http://new; }
location /api/v2/users { proxy_pass http://new; }
# Everything else still legacy
location / { proxy_pass http://legacy; }
}
```
### Branch by Abstraction (Java)
```java
// Step 1 — extract interface
interface PaymentGateway {
Receipt charge(Order o);
}
// Step 2 — wrap legacy
class LegacyStripeGateway implements PaymentGateway { /* ... */ }
// Step 3 — new impl behind flag
class AdyenGateway implements PaymentGateway { /* ... */ }
// Step 4 — feature-flag pick
class GatewayFactory {
PaymentGateway pick(String tenant) {
return flags.isOn("adyen", tenant)
? new AdyenGateway()
: new LegacyStripeGateway();
}
}
// Step 5 — once 100% rollout, delete LegacyStripeGateway
```
### Parallel Run (shadow traffic)
```ts
async function chargeShadow(order: Order): Promise<Receipt> {
const [primary, shadow] = await Promise.allSettled([
legacy.charge(order),
newImpl.charge(order) // never persists, just observes
]);
if (shadow.status === 'fulfilled' && primary.status === 'fulfilled') {
diff.record('charge', primary.value, shadow.value);
}
return primary.status === 'fulfilled' ? primary.value : Promise.reject(primary.reason);
}
```
### Database Strangling — dual write + read switch
```python
# Phase 1: dual write
def save_order(o: Order):
legacy_db.insert(o)
try:
new_db.insert(o)
except Exception as e:
log.warn("shadow write failed", e=e)
# Phase 2: dual read + diff
def get_order(id: str):
a = legacy_db.get(id)
b = new_db.get(id)
if a != b: metrics.increment("order.read.diverge")
return a # legacy still source of truth
# Phase 3: flip read source
def get_order(id: str):
return new_db.get(id)
# Phase 4: stop legacy write, decommission
```
### Module extraction (modular monolith → service)
```bash
# 1. Codify module boundary first (ArchUnit)
# 2. Replace direct calls with in-process interface
# 3. Add feature flag: in-process vs HTTP/gRPC
# 4. Deploy as separate process behind flag
# 5. Remove in-process path
```
### Characterization test (Feathers)
```python
import json, pytest
@pytest.mark.parametrize("fixture", load_fixtures("legacy_outputs/*.json"))
def test_legacy_behavior_preserved(fixture):
inputs = fixture["input"]
expected = fixture["legacy_output"]
actual = new_impl.run(**inputs)
assert actual == expected, f"divergence: {fixture['id']}"
```
### Refactor scoreboard (CI)
```yaml
# refactor-progress.yml — auto-generated dashboard
metrics:
- name: legacy-endpoints-remaining
cmd: grep -r "@legacy" src/ | wc -l
- name: new-coverage
cmd: jacoco --module=new-impl
- name: traffic-on-new
promql: sum(rate(http_requests_total{service="new"}[5m]))
/ sum(rate(http_requests_total[5m]))
```
## 매 결정 기준
| 상황 | Strategy |
|---|---|
| Active legacy + traffic | Strangler Fig |
| Library/abstraction swap | Branch by Abstraction |
| Risk-critical (payment, billing) | Parallel Run |
| DB schema change | Dual-write + flip read |
| Tiny system, frozen scope | Big Bang (rare) |
| Distributed monolith | Reverse first → modular monolith → extract |
**기본값**: Strangler Fig + feature flag + parallel-run on critical paths.
## 🔗 Graph
- 부모: [[Software Architecture]] · [[Refactoring_Best_Practices|Refactoring]]
- 변형: [[Strangler-Fig]] · [[Branch-by-Abstraction]]
- 응용: [[Modular-Monolith]] · [[Microservices]]
- Adjacent: [[Architecture Erosion (아키텍처 침식)]] · [[Architectural-Constraint-Enforcement]] · [[Architecture Review (아키텍처 및 설계 리뷰)]]
## 🤖 LLM 활용
**언제**: 매 legacy code → modern equivalent translation, 매 codemod plan generation, 매 ADR draft.
**언제 X**: 매 production cutover decision — 매 human + traffic data 의 필수.
## ❌ 안티패턴
- **Big bang rewrite**: 매 70%+ failure rate — 매 last resort.
- **Refactor without tests**: 매 silent regression 의 guarantee.
- **No flag, no rollback**: 매 forward-only deploy — 매 incident magnification.
- **Premature service extraction**: 매 distributed monolith 의 worst-of-both.
- **Stop midway**: 매 두 system 의 forever maintain — 매 cost 의 doubled.
## 🧪 검증 / 중복
- Verified (Fowler — *StranglerFigApplication*; Feathers — *Working Effectively with Legacy Code*; Newman — *Monolith to Microservices*).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Strangler Fig + Branch-by-Abstraction + parallel-run patterns |
@@ -0,0 +1,224 @@
---
id: wiki-2026-0508-aspect-oriented-programming-aop
title: Aspect Oriented Programming (AOP)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [AOP, Aspect Programming, Cross-cutting Concerns]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, paradigm, spring, decorator]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Java / TypeScript / Python
framework: Spring AOP / AspectJ / NestJS
---
# Aspect-Oriented Programming (AOP)
## 매 한 줄
> **"매 cross-cutting concern을 separate aspect로 modularize."**. 1997년 Gregor Kiczales (Xerox PARC) 의 AspectJ 가 시초. 2026 현재 Spring AOP 6.x, NestJS interceptor, Python decorator 가 주류 — logging/transaction/security 같이 매 객체 가로지르는 logic을 매 한 곳에 모음.
## 매 핵심
### 매 용어
- **Aspect**: 매 cross-cutting concern 의 modular 단위 (e.g. `LoggingAspect`).
- **Join Point**: 매 program execution 의 한 지점 (method call, field access).
- **Pointcut**: 매 join point 의 selection expression.
- **Advice**: 매 pointcut 매칭 시 실행할 code (`@Before`, `@After`, `@Around`).
- **Weaving**: 매 aspect 와 base code 결합 — compile-time / load-time / runtime.
### 매 cross-cutting concerns
- Logging / tracing
- Transaction management
- Security / authorization
- Caching
- Performance monitoring
- Error handling / retry
- Audit trail
### 매 응용
1. Spring `@Transactional` — DB transaction 자동 commit/rollback.
2. NestJS `@UseInterceptors` — request/response transform.
3. Python `@functools.lru_cache` — pure caching aspect.
4. OpenTelemetry auto-instrumentation — runtime byte-code weaving.
## 💻 패턴
### Spring AOP — @Around aspect
```java
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logExecutionTime(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
try {
Object result = pjp.proceed();
long elapsed = System.currentTimeMillis() - start;
log.info("{} took {} ms", pjp.getSignature(), elapsed);
return result;
} catch (Throwable t) {
log.error("{} threw {}", pjp.getSignature(), t.getMessage());
throw t;
}
}
}
```
### Spring — @Transactional declarative TX
```java
@Service
public class OrderService {
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
public Order placeOrder(OrderRequest req) {
Order order = orderRepo.save(new Order(req));
inventoryRepo.decrement(req.getItems());
// Any RuntimeException → automatic rollback via AOP proxy
return order;
}
}
```
### NestJS — Interceptor (AOP-style)
```typescript
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable, tap } from 'rxjs';
@Injectable()
export class TimingInterceptor implements NestInterceptor {
intercept(ctx: ExecutionContext, next: CallHandler): Observable<unknown> {
const start = Date.now();
return next.handle().pipe(
tap(() => console.log(`${ctx.getHandler().name} took ${Date.now() - start}ms`)),
);
}
}
@Controller('orders')
@UseInterceptors(TimingInterceptor)
export class OrdersController { /* ... */ }
```
### Python — Decorator as aspect
```python
import functools, time, logging
def timed(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
try:
return func(*args, **kwargs)
finally:
elapsed = time.perf_counter() - start
logging.info(f"{func.__name__} took {elapsed*1000:.1f}ms")
return wrapper
@timed
def expensive_calc(n: int) -> int:
return sum(i * i for i in range(n))
```
### Python — Class-based retry aspect
```python
def retry(times: int = 3, on: tuple = (Exception,)):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
last = None
for attempt in range(times):
try:
return func(*args, **kwargs)
except on as e:
last = e
time.sleep(2 ** attempt)
raise last
return wrapper
return decorator
@retry(times=5, on=(httpx.HTTPError,))
def fetch_remote(url: str) -> dict:
return httpx.get(url).json()
```
### AspectJ pointcut DSL
```java
@Pointcut("execution(public * com.example.repo.*.find*(..))")
public void anyFinder() {}
@Pointcut("@annotation(com.example.Audited)")
public void auditedMethod() {}
@Before("anyFinder() && auditedMethod()")
public void audit(JoinPoint jp) {
auditService.log(jp.getSignature().toShortString(), Instant.now());
}
```
### TypeScript — method decorator
```typescript
function Cached(ttlMs: number): MethodDecorator {
const cache = new Map<string, { value: unknown; exp: number }>();
return (_t, _k, desc: PropertyDescriptor) => {
const original = desc.value;
desc.value = function (...args: unknown[]) {
const key = JSON.stringify(args);
const entry = cache.get(key);
if (entry && entry.exp > Date.now()) return entry.value;
const value = original.apply(this, args);
cache.set(key, { value, exp: Date.now() + ttlMs });
return value;
};
};
}
class Pricing {
@Cached(60_000)
fetchRate(currency: string) { /* ... */ }
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Java enterprise, declarative TX | Spring AOP (proxy-based) |
| 매 method 매칭 + field access weaving | AspectJ (compile/load-time) |
| Node.js HTTP layer | NestJS Interceptor / Guard |
| Python script / function-level | Decorator |
| Cross-language tracing | OpenTelemetry auto-instrumentation |
**기본값**: framework-native (Spring AOP / NestJS interceptor / decorator). 매 raw AspectJ 는 매 매우 specific 한 경우만.
## 🔗 Graph
- 부모: [[Object-Oriented-Programming]] · [[Software-Architecture]]
- 변형: [[Middleware]]
- 응용: [[Spring-Framework]] · [[NestJS]] · [[OpenTelemetry]]
- Adjacent: [[Dependency_Injection_(DI)|Dependency-Injection]] · [[Cross-Cutting-Concerns]]
## 🤖 LLM 활용
**언제**: cross-cutting concern (logging/TX/security/caching) 이 매 여러 service 에 반복, declarative style 선호, framework 가 AOP 지원.
**언제 X**: 매 한두 곳만 쓰는 logic (직접 호출이 명확), 매 magic 회피 culture, 매 debug 어려움 감수 못할 때.
## ❌ 안티패턴
- **Aspect 안 business logic**: 매 aspect 는 매 cross-cutting 만 — 매 domain rule 넣지 X.
- **너무 broad pointcut**: `execution(* *.*(..))` — 매 unintended weaving.
- **Self-invocation 의 proxy bypass**: 매 같은 class 안 method call 은 매 proxy 통과 안 함 (Spring).
- **Order 의존**: 매 multiple aspect 매 ordering 명시 X 면 매 비결정적.
- **Aspect explosion**: 매 100+ aspect → 매 control flow 추적 불가.
## 🧪 검증 / 중복
- Verified (Spring Framework 6.x docs, AspectJ programming guide, NestJS docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — AOP full content with Spring/NestJS/Python patterns |
@@ -0,0 +1,186 @@
---
id: wiki-2026-0508-branded-types
title: Branded Types
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Branded Types, Nominal Types, Opaque Types, Tagged Types]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [typescript, type-system, nominal-typing, domain-modeling]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: typescript-5.x,zod,effect-ts
---
# Branded Types
## 매 한 줄
> **"매 structural type 의 nominal 의 emulate — 매 `string` 두 개 의 distinguish 의 enforce"**. TypeScript 의 structural typing 의 long-standing pain (UserId vs OrderId · Email vs string) 의 solve, 2026 의 Effect-TS Brand · Zod brand · Type-Fest Tagged 의 ergonomic API 의 mainstream.
## 매 핵심
### 매 problem
- TS structural: 매 `string` 의 모든 `string` 의 assignable.
- `function sendEmail(userId: string, email: string)` — 매 swap 의 type check pass.
- 매 nominal hint 의 require — but TS 의 native 의 no.
### 매 mechanism
- Intersection 의 phantom property: `string & { __brand: "UserId" }`.
- 매 runtime 의 plain string — 매 zero cost.
- Constructor function 의 cast — 매 single point 의 validate.
### 매 응용
1. Domain ID (UserId · OrderId · ProductId).
2. Validated string (Email · URL · UUID · NonEmptyString).
3. Numeric unit (Meters · Seconds · USD · Cents).
4. Sanitized input (HtmlSafeString · SqlEscapedString).
## 💻 패턴
### Vanilla TS brand
```typescript
type Brand<T, B> = T & { readonly __brand: B };
type UserId = Brand<string, "UserId">;
type OrderId = Brand<string, "OrderId">;
const UserId = (s: string): UserId => s as UserId;
const OrderId = (s: string): OrderId => s as OrderId;
function getUser(id: UserId) { /* ... */ }
const u = UserId("u-123");
const o = OrderId("o-456");
getUser(u); // OK
getUser(o); // ❌ Type error — 매 nominal 의 distinguish
getUser("u-123"); // ❌ raw string 의 reject
```
### Branded with smart constructor (validate + brand)
```typescript
type Email = Brand<string, "Email">;
function Email(s: string): Email {
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(s)) {
throw new Error(`invalid email: ${s}`);
}
return s as Email;
}
// safer Result variant
function tryEmail(s: string): { ok: true; value: Email } | { ok: false; error: string } {
return /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(s)
? { ok: true, value: s as Email }
: { ok: false, error: "invalid email" };
}
```
### Zod brand (runtime + type)
```typescript
import { z } from "zod";
const UserIdSchema = z.string().uuid().brand<"UserId">();
type UserId = z.infer<typeof UserIdSchema>;
const id = UserIdSchema.parse("550e8400-e29b-41d4-a716-446655440000");
// id is branded UserId — 매 raw uuid string 의 reject elsewhere
```
### Effect-TS Brand
```typescript
import { Brand } from "effect";
type USD = number & Brand.Brand<"USD">;
const USD = Brand.refined<USD>(
(n) => Number.isInteger(n) && n >= 0,
(n) => Brand.error(`expected positive integer cents, got ${n}`),
);
const price = USD(1999); // OK
const bad = USD(-5); // BrandErrors
```
### Numeric units (compile-time dimensional)
```typescript
type Meters = Brand<number, "Meters">;
type Seconds = Brand<number, "Seconds">;
type MPS = Brand<number, "MetersPerSecond">;
const m = (n: number) => n as Meters;
const s = (n: number) => n as Seconds;
function speed(d: Meters, t: Seconds): MPS {
return (d / t) as MPS;
}
speed(m(100), s(9.58)); // OK
speed(s(9.58), m(100)); // ❌ swapped
```
### Type-Fest Tagged (lighter syntax)
```typescript
import type { Tagged } from "type-fest";
type Email = Tagged<string, "Email">;
type UserId = Tagged<string, "UserId">;
```
### Phantom param (alternate encoding)
```typescript
declare const brand: unique symbol;
type Brand<T, K> = T & { readonly [brand]: K };
```
### Runtime parsing layer (input boundary)
```typescript
// API boundary — single point of validation
function handleRequest(raw: { userId: string; email: string }) {
const userId = UserId(raw.userId); // brand at boundary
const email = Email(raw.email); // validate + brand
return processOrder(userId, email); // internal: branded everywhere
}
```
## 매 결정 기준
| 상황 | Encoding |
|---|---|
| Lightweight ID 의 distinguish | Vanilla `__brand` |
| Runtime validation + brand | Zod brand · Effect Brand |
| Functional pipeline · refinement | Effect-TS Brand |
| Library ergonomics | Type-Fest `Tagged` |
| Numeric unit · dimensional | Brand<number, "Unit"> |
**기본값**: domain ID 의 vanilla brand, validated value 의 Zod, numeric/refinement 의 Effect Brand.
## 🔗 Graph
- 부모: [[TypeScript Type System]]
- 변형: [[Nominal-Typing-in-TypeScript|Nominal Typing]] · [[Opaque Types]]
- 응용: [[Parse Don't Validate]]
- Adjacent: [[Ambient_Declarations]] · [[Schema Validation]]
## 🤖 LLM 활용
**언제**: domain ID 의 brand 의 generate, smart constructor + validator 의 draft, Zod schema 의 brand 의 add.
**언제 X**: 매 brand 의 over-applying — 매 internal helper 의 brand 의 X · 매 boundary 의 only.
## ❌ 안티패턴
- **Brand 의 everywhere**: function signature 의 noise 의 explode — 매 domain primitive 만.
- **Cast 의 sprinkled**: 매 single constructor 의 collapse — validation 의 single source.
- **Brand 의 leak through serialization**: JSON.parse 의 raw string 의 return — boundary parse 의 require.
- **Multiple brand 의 same value**: `Brand<string, "A"> & Brand<string, "B">` — 매 union 의 use 의 X · 매 새 brand 의 prefer.
## 🧪 검증 / 중복
- Verified (TypeScript handbook, Effect-TS docs, Zod 4 docs, Type-Fest Tagged docs, "Parse Don't Validate" Alexis King).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — vanilla + Zod + Effect-TS + Type-Fest variants |
@@ -0,0 +1,258 @@
---
id: wiki-2026-0508-breaking-dependencies
title: Breaking Dependencies
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Decoupling, Dependency Breaking, Refactoring Legacy]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [refactoring, architecture, legacy-code, testing]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Java / TypeScript / Python
framework: language-agnostic
---
# Breaking Dependencies
## 매 한 줄
> **"매 untestable code 를 매 test 가능하게 만드는 첫 단계 = 매 hard dependency 를 매 break."**. Michael Feathers 의 *Working Effectively with Legacy Code* (2004) 의 24 가지 dependency-breaking technique 가 매 canonical reference. 2026 현재 modern DI / 매 hexagonal architecture 가 매 prevention layer, but 매 legacy 에는 여전히 매 Sprout Method / Extract Interface / Adapter 가 핵심.
## 매 핵심
### 매 dependency types
- **Construction dependency**: 매 `new SomeService()` hardcoded.
- **Static dependency**: 매 `Date.now()`, `Math.random()`, `Singleton.getInstance()`.
- **Hidden dependency**: 매 method 안에서 file / DB / network 직접 호출.
- **Temporal coupling**: 매 method A → B 순서 강요.
- **Inheritance dependency**: 매 base class 가 매 hard-to-test 행위 가짐.
### 매 Feathers 의 핵심 24 technique 중 top 8
1. **Sprout Method**: 매 new behavior 를 매 새 method 로 분리해 매 test 가능하게.
2. **Sprout Class**: 매 new behavior 를 매 new class 로.
3. **Extract Interface**: 매 concrete dep → 매 interface → mock.
4. **Extract and Override Call**: 매 hard call 을 매 protected method 로 → subclass 에서 override.
5. **Subclass and Override Method**: 매 testing subclass.
6. **Adapt Parameter**: 매 untestable arg → 매 wrapper interface.
7. **Break Out Method Object**: 매 거대 method → 매 클래스.
8. **Introduce Instance Delegator**: 매 static → 매 instance method 로.
### 매 응용
1. Legacy Java/C# enterprise codebase 의 unit test 도입.
2. Module 간 cyclic dependency 끊기.
3. 매 third-party SDK 의 hard wiring 제거.
4. Microservice extraction 전 prep.
5. 매 monolith 의 plugin 화.
## 💻 패턴
### Extract Interface (Java)
```java
// BEFORE — hard wired
public class OrderService {
public Receipt placeOrder(Order o) {
EmailSender sender = new EmailSender(); // hard dep
sender.send(o.customerEmail, "...");
return Receipt.from(o);
}
}
// AFTER — Extract Interface + DI
public interface Notifier {
void send(String to, String body);
}
public class EmailSender implements Notifier { /* impl */ }
public class OrderService {
private final Notifier notifier;
public OrderService(Notifier notifier) { this.notifier = notifier; }
public Receipt placeOrder(Order o) {
notifier.send(o.customerEmail, "...");
return Receipt.from(o);
}
}
// Test
@Test void placesOrderAndNotifies() {
var fake = mock(Notifier.class);
var svc = new OrderService(fake);
svc.placeOrder(testOrder());
verify(fake).send(eq("a@b.com"), anyString());
}
```
### Sprout Method (TypeScript)
```ts
// BEFORE — 매 huge method, 매 add new logic 못 testable
class Invoice {
process(): void {
// 200 lines 의 legacy
// 매 new logic 추가하면 매 테스트 X
}
}
// AFTER — sprout 로 새 행동만 분리
class Invoice {
process(): void {
// 200 lines 의 legacy (그대로)
this.applyLoyaltyDiscount(); // 매 sprouted
}
applyLoyaltyDiscount(): number { // 매 testable in isolation
if (this.customer.tier === 'gold') return this.total * 0.1;
if (this.customer.tier === 'silver') return this.total * 0.05;
return 0;
}
}
```
### Extract and Override Call (Python)
```python
# BEFORE
class Job:
def run(self):
now = datetime.utcnow() # 매 hard
if now.weekday() >= 5: return
self.do_work()
# AFTER
class Job:
def run(self):
if self._now().weekday() >= 5: return
self.do_work()
def _now(self) -> datetime: # 매 protected — override in test
return datetime.utcnow()
class TestJob(Job):
def __init__(self, fixed_dt): self.fixed_dt = fixed_dt
def _now(self): return self.fixed_dt
# Test
def test_skips_weekend():
j = TestJob(datetime(2026, 5, 9)) # 매 Saturday
j.do_work = MagicMock()
j.run()
j.do_work.assert_not_called()
```
### Adapt Parameter (Java)
```java
// BEFORE — HttpServletRequest hard to construct in test
public Result handle(HttpServletRequest req) {
String userId = req.getHeader("X-User-Id");
return repo.find(userId);
}
// AFTER — adapter interface
public interface RequestAdapter {
String header(String name);
}
public Result handle(RequestAdapter req) {
return repo.find(req.header("X-User-Id"));
}
// Production wraps; test = trivial map
class ServletRequestAdapter implements RequestAdapter {
private final HttpServletRequest delegate;
public String header(String n) { return delegate.getHeader(n); }
}
```
### Subclass and Override (Python — break DB)
```python
class ReportGenerator:
def fetch(self) -> list[dict]:
return db.query("SELECT * FROM orders") # 매 hard
def render(self) -> str:
rows = self.fetch()
return "\n".join(f"{r['id']}: {r['total']}" for r in rows)
class TestableReport(ReportGenerator):
def __init__(self, fake_rows): self.fake_rows = fake_rows
def fetch(self): return self.fake_rows
def test_renders():
r = TestableReport([{"id": 1, "total": 100}])
assert r.render() == "1: 100"
```
### Wrap Method (legacy 호환 유지)
```java
// 매 old API 깨면 안 됨 → 매 wrap
public void payInvoice(Invoice i) {
audit.log(i); // 매 new behavior
payInvoiceLegacy(i); // 매 unchanged
}
private void payInvoiceLegacy(Invoice i) { /* 매 untouched */ }
```
### Seam mapping checklist
```
1. List 매 untestable thing in target method
- Static call? → Introduce Instance Delegator / Replace Function with Function Object
- new? → Extract Interface + inject
- Time/random? → Extract & Override Call
- File/DB/HTTP? → Repository / Adapter
2. Pick 1 dep / day. 매 small step + commit.
3. 매 Test 먼저 (characterization test)
- 매 current behavior 를 lock down
4. Refactor under green tests.
```
### Hexagonal post-state (prevention)
```
[Domain Core] ← [Port (interface)] ← [Adapter (DB / HTTP / FS)]
매 NO direct import 매 from core to adapter
매 Test = stub adapter against port
```
## 매 결정 기준
| 상황 | Technique |
|---|---|
| 매 add new feature 매 large method | Sprout Method |
| 매 hard dep on concrete class | Extract Interface + DI |
| 매 static / time / random | Extract and Override Call |
| 매 framework type 의 arg | Adapt Parameter |
| 매 file / DB / network | Repository / Port-Adapter |
| 매 huge method 의 internal logic | Break Out Method Object |
| 매 base class behavior bad | Subclass and Override |
**기본값**: characterization test 먼저 → 매 minimal mechanical refactor (compiler-driven) → 매 small commit.
## 🔗 Graph
- 부모: [[Refactoring_Best_Practices|Refactoring]]
- 변형: [[Sprout-Method]]
- 응용: [[Test-Driven-Development]] · [[Hexagonal-Architecture]]
- Adjacent: [[Dependency_Injection_(DI)|Dependency-Injection]] · [[SOLID-Principles]] · [[Mocking]]
## 🤖 LLM 활용
**언제**: legacy code unit test 도입, untestable method 마주침, monolith 분해 직전 prep, third-party SDK lock-in 제거.
**언제 X**: 매 already clean architecture (over-refactor 금지), 매 throwaway prototype.
## ❌ 안티패턴
- **Big-bang rewrite**: 매 일부 break → 매 전체 unstable.
- **Test 없이 refactor**: 매 behavior 변경 모름 → 매 silent regression.
- **너무 많은 mock**: 매 test 가 매 implementation 에 결합.
- **Interface 의 1 implementation 영구**: 매 YAGNI — 매 두 번째 user 생기면 그때 추출.
- **God adapter**: 매 1 interface 에 30 method.
- **Refactor + feature 동시 commit**: 매 review 불가.
## 🧪 검증 / 중복
- Verified (Feathers "Working Effectively with Legacy Code" 2004, Fowler "Refactoring" 2nd ed).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Breaking Dependencies with Feathers techniques |
@@ -0,0 +1,183 @@
---
id: wiki-2026-0508-cad-렌더링-최적화
title: CAD 렌더링 최적화
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [CAD Rendering Optimization, CAD Performance, Engineering Visualization]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [cad, rendering, gpu, lod, webgpu]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: WebGPU/Three.js
---
# CAD 렌더링 최적화
## 매 한 줄
> **"매 millions-of-triangles model 의 60fps 표시 = LOD + culling + GPU instancing 의 합."**. 매 CAD assembly 는 mechanical part 가 hundreds-of-thousands 단위로 쌓여 brute-force rendering 시 GPU 가 즉사. 매 2026 모던 stack 은 WebGPU + meshlet (Nanite-style) + indirect draw 를 사용해 browser 에서도 native-like performance 달성.
## 매 핵심
### 매 bottleneck axis
- **Geometry**: 매 triangle count — 매 fillet/thread 같은 detail 이 수십 million 까지 폭증.
- **Draw call**: 매 part 별 separate draw → CPU/GPU sync overhead 가 frame budget 잠식.
- **Overdraw**: 매 transparent assembly 의 layered fragment shading.
- **Memory**: 매 32-bit index + per-vertex normal/UV/color → VRAM 빠르게 saturate.
### 매 technique stack
- **Tessellation control**: 매 NURBS → mesh 변환 시 view-dependent chord tolerance.
- **LOD**: 매 distance / screen-coverage 기반 mesh swap.
- **Frustum / occlusion culling**: 매 BVH + Hi-Z buffer.
- **Instancing**: 매 동일 part (bolt/screw) 의 single draw call.
- **Meshlet (Nanite-like)**: 매 cluster 단위 GPU culling + virtual geometry.
- **Deferred shading**: 매 overdraw 비용 절감.
### 매 응용
1. **Onshape / Fusion 360 web**: 매 browser 안 assembly editing.
2. **Plant 3D walkthrough**: 매 oil refinery / factory digital twin.
3. **AR overlay**: 매 Vision Pro / Quest 3 의 maintenance instruction.
4. **VR design review**: 매 stakeholder 의 immersive walkthrough.
## 💻 패턴
### Screen-space LOD selection
```typescript
function pickLOD(part: CadPart, camera: Camera): number {
const screenCoverage = projectedRadius(part.bounds, camera) / camera.viewport.height;
if (screenCoverage > 0.3) return 0; // full mesh
if (screenCoverage > 0.1) return 1; // 1/4 triangles
if (screenCoverage > 0.03) return 2; // 1/16 triangles
if (screenCoverage > 0.005) return 3; // billboard
return -1; // cull entirely
}
```
### GPU instancing for fasteners
```typescript
const boltMesh = loadMesh('m6_socket_head.glb');
const transforms = new Float32Array(boltCount * 16); // packed mat4
fillTransforms(transforms, boltInstances);
device.queue.writeBuffer(instanceBuffer, 0, transforms);
pass.setPipeline(instancedPipeline);
pass.setVertexBuffer(0, boltMesh.vertices);
pass.setVertexBuffer(1, instanceBuffer);
pass.drawIndexed(boltMesh.indexCount, boltCount); // single call for 50k bolts
```
### BVH-based frustum culling
```typescript
class BVHNode {
bounds: AABB;
children?: [BVHNode, BVHNode];
parts?: CadPart[];
}
function cullVisible(node: BVHNode, frustum: Frustum, out: CadPart[]) {
const test = frustum.testAABB(node.bounds);
if (test === 'outside') return;
if (test === 'inside' || !node.children) {
out.push(...(node.parts ?? collectAll(node)));
return;
}
cullVisible(node.children[0], frustum, out);
cullVisible(node.children[1], frustum, out);
}
```
### Meshlet cluster (Nanite-style)
```wgsl
// WebGPU compute shader — cluster culling
@group(0) @binding(0) var<storage, read> meshlets: array<Meshlet>;
@group(0) @binding(1) var<storage, read_write> visibleList: array<u32>;
@group(0) @binding(2) var<uniform> camera: Camera;
@compute @workgroup_size(64)
fn cullMeshlets(@builtin(global_invocation_id) gid: vec3u) {
let idx = gid.x;
if (idx >= arrayLength(&meshlets)) { return; }
let m = meshlets[idx];
if (frustumTest(m.boundingSphere, camera) &&
coneTest(m.normalCone, camera.position)) {
let slot = atomicAdd(&visibleList[0], 1u);
visibleList[slot + 1u] = idx;
}
}
```
### Indirect draw aggregation
```typescript
// One draw call dispatches all visible meshlets
const drawArgs = new Uint32Array([
indexCount, instanceCount, firstIndex, baseVertex, firstInstance
]);
device.queue.writeBuffer(indirectBuffer, 0, drawArgs);
pass.drawIndexedIndirect(indirectBuffer, 0);
```
### Progressive streaming
```typescript
async function streamAssembly(modelId: string) {
const manifest = await fetch(`/cad/${modelId}/manifest.json`).then(r => r.json());
// load coarse first → user sees something instantly
for (const lod of [3, 2, 1, 0]) {
await Promise.all(manifest.parts.map(p =>
cache.has(`${p.id}_lod${lod}`) ? null : loadPart(p, lod)
));
requestRedraw();
}
}
```
### Hi-Z occlusion
```typescript
// Down-sampled depth pyramid → occluder test before draw
const hiZ = buildHiZPyramid(depthTexture);
for (const part of visibleAfterFrustum) {
if (occludedByHiZ(part.bounds, hiZ, camera)) continue;
drawList.push(part);
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| < 100k triangles, single part | brute force, no LOD |
| 1M-10M triangles, assembly | BVH + frustum culling + LOD |
| 10M-100M triangles | + GPU instancing + meshlets |
| > 100M (plant/ship) | virtual geometry + streaming + occlusion |
| Mobile / VR | aggressive LOD + foveated rendering |
**기본값**: BVH culling + 4-tier LOD + instanced fasteners (covers 90% mid-size assemblies).
## 🔗 Graph
- 부모: [[Computer_Graphics]] · [[GPU_Architecture]]
- 응용: [[Digital_Twin]]
- Adjacent: [[WebGPU]] · [[Three.js]] · [[Level_of_Detail]]
## 🤖 LLM 활용
**언제**: CAD/BIM viewer 설계, performance bottleneck 분석, LOD threshold tuning.
**언제 X**: photorealistic offline rendering (path tracing 영역).
## ❌ 안티패턴
- **Per-part separate draw call**: 매 50k draws/frame 은 어떤 GPU 도 죽음.
- **CPU-side culling only**: 매 GPU-driven culling 없이는 modern bandwidth 활용 불가.
- **Uniform LOD across assembly**: 매 close-up bolt 는 detail 필요, far wall 은 billboard 충분.
- **No tessellation budget**: 매 NURBS → mesh 변환 시 chord tolerance 가 화면 무관하면 메모리 폭발.
## 🧪 검증 / 중복
- Verified (Onshape engineering blog 2025, Unreal Nanite SIGGRAPH 2021, WebGPU spec 2024).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — CAD rendering pipeline, LOD, meshlet, WebGPU patterns |
@@ -0,0 +1,205 @@
---
id: wiki-2026-0508-code-refactoring
title: Code Refactoring
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Refactoring, Code Improvement, Fowler Refactoring]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [refactoring, code-quality, fowler, ide, llm-refactor]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Polyglot
framework: IDE/AST-based-tools
---
# Code Refactoring
## 매 한 줄
> **"매 refactoring = 매 외부 동작은 그대로 두고 internal 구조만 개선하는 disciplined transformation."**. 매 Martin Fowler 1999 "Refactoring" 이 catalog 화한 70+ named transformation 이 backbone, 매 2026 현재 IDE automated refactor + LLM-assisted refactor (Claude Opus 4.7, Cursor) 가 manual rewrite 대체. 매 핵심 disciplines = small steps + green tests + commit per refactor.
## 매 핵심
### 매 catalog (대표)
- **Extract Function / Method**: 매 코드 블록 → 새 function.
- **Inline Function**: 매 trivial wrapper 제거.
- **Rename**: 매 의미 명확한 이름.
- **Extract Variable / Inline Variable**.
- **Move Function / Field**: 매 right class/module 로.
- **Replace Conditional with Polymorphism**.
- **Replace Magic Number with Constant**.
- **Introduce Parameter Object**.
- **Decompose Conditional**.
- **Extract Class / Inline Class**.
### 매 disciplines
- **Tests first**: 매 refactor 전 green test suite.
- **Small steps**: 매 single refactor → run tests → commit.
- **No mixing**: 매 behavior change 와 refactor 동시 X.
- **Reversibility**: 매 step 별 git revert 가능.
### 매 응용
1. **Legacy modernization**: 매 strangler fig + extract.
2. **Performance**: 매 inline hot function, extract slow path.
3. **Test enabling**: 매 dependency 분리.
4. **Onboarding**: 매 confusing code rename + decompose.
## 💻 패턴
### Extract Function
```python
# BEFORE
def print_owing(invoice):
print_banner()
outstanding = sum(o.amount for o in invoice.orders)
print(f"name: {invoice.customer}")
print(f"amount: {outstanding}")
# AFTER
def print_owing(invoice):
print_banner()
outstanding = calculate_outstanding(invoice)
print_details(invoice, outstanding)
def calculate_outstanding(invoice):
return sum(o.amount for o in invoice.orders)
def print_details(invoice, outstanding):
print(f"name: {invoice.customer}")
print(f"amount: {outstanding}")
```
### Replace Conditional with Polymorphism
```typescript
// BEFORE
function pay(employee: Employee) {
switch (employee.type) {
case 'engineer': return baseSalary(employee);
case 'salesman': return baseSalary(employee) + commission(employee);
case 'manager': return baseSalary(employee) + bonus(employee);
}
}
// AFTER
abstract class EmployeeType {
abstract pay(e: Employee): number;
}
class Engineer extends EmployeeType { pay(e) { return baseSalary(e); } }
class Salesman extends EmployeeType { pay(e) { return baseSalary(e) + commission(e); } }
class Manager extends EmployeeType { pay(e) { return baseSalary(e) + bonus(e); } }
```
### Introduce Parameter Object
```python
# BEFORE
def amount_invoiced(start_date, end_date, customer_id, currency, ...): ...
# AFTER
@dataclass
class InvoiceQuery:
range: DateRange
customer_id: str
currency: str
def amount_invoiced(q: InvoiceQuery): ...
```
### Decompose Conditional
```javascript
// BEFORE
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
charge = quantity * winterRate + winterServiceCharge;
} else {
charge = quantity * summerRate;
}
// AFTER
charge = isSummer(date) ? summerCharge(quantity) : winterCharge(quantity);
function isSummer(d) { return !d.before(SUMMER_START) && !d.after(SUMMER_END); }
function summerCharge(q) { return q * summerRate; }
function winterCharge(q) { return q * winterRate + winterServiceCharge; }
```
### Strangler Fig (legacy migration)
```typescript
// route table — gradually shift endpoints to new service
const routes = {
'/users': process.env.NEW_USERS === 'on' ? newUsers : legacyUsers,
'/orders': process.env.NEW_ORDERS === 'on' ? newOrders : legacyOrders,
'/billing': legacyBilling, // not migrated yet
};
// flip flags one at a time, rollback by env var
```
### IDE-driven (IntelliJ / Roslyn)
```bash
# JetBrains command-line refactor (CI batch)
idea.sh inspect $PROJECT inspectionProfile.xml output/ \
-d $MODULE -v2
# C# Roslyn analyzer + code fix runs in `dotnet format analyzers --verify-no-changes`
```
### LLM-assisted refactor (Claude Opus 4.7)
```bash
# 1. select scope, 2. generate diff, 3. tests must stay green
claude refactor \
--scope src/billing/ \
--instruction "Extract OrderTotalCalculator class; preserve all behavior" \
--validate "pytest tests/billing/"
# Claude proposes diff → run tests → commit if green
```
### Test characterization (legacy without tests)
```python
# Before refactor of untested code: write golden tests first
def test_legacy_charge_2025_invoice():
inv = load_fixture('2025_invoice.json')
expected = legacy.calc(inv) # capture current behavior
assert refactored.calc(inv) == expected # equality, not "correctness"
```
## 매 결정 기준
| 상황 | Refactor |
|---|---|
| Long function (> 30 lines) | Extract Function |
| Same param list 5+ places | Introduce Parameter Object |
| `switch (type)` repeated | Replace Conditional with Polymorphism |
| Confusing name | Rename |
| Class doing 2 things | Extract Class |
| Legacy without tests | Characterization tests first |
| Mass code movement | LLM batch + test-gate |
**기본값**: small step + commit per refactor + tests green; LLM 으로 mass rename / extract 가속.
## 🔗 Graph
- 부모: [[Code_Quality]]
- 변형: [[Strangler_Fig]]
- 응용: [[Legacy_Modernization]] · [[Test_Driven_Development]]
- Adjacent: [[Clean_Code]] · [[Design_Patterns]]
## 🤖 LLM 활용
**언제**: bulk rename, extract function, polymorphism conversion, parameter object 도입.
**언제 X**: subtle concurrency / lock-free invariants — 매 manual review 필수.
## ❌ 안티패턴
- **Refactor + feature in same commit**: 매 review/revert 불가능.
- **Refactor without tests**: 매 silent behavior change.
- **Big-bang rewrite**: 매 6개월 후 production 되돌리기 불가능.
- **Premature abstraction**: 매 1번 쓰인 패턴 인터페이스화 — YAGNI.
- **Trust-LLM-and-skip-tests**: 매 LLM hallucinated edge case 통과시킴.
## 🧪 검증 / 중복
- Verified (Fowler "Refactoring" 2nd ed 2018, "Working Effectively with Legacy Code" Feathers 2004).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Fowler catalog, disciplines, IDE/LLM-assisted patterns |
@@ -0,0 +1,174 @@
---
id: wiki-2026-0508-concurrent-rendering
title: Concurrent Rendering
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [React Concurrent, Concurrent Mode, React 18 Concurrent]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [react, concurrent, rendering, scheduler, transitions]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: react
---
# Concurrent Rendering
## 매 한 줄
> **"매 render 매 interruptible, prioritizable, abandonable"**. React 18 (2022) 에 stable. Fiber architecture (2017) 의 결실. 2026 현재 React 19+ 의 default; `useTransition`, `useDeferredValue`, Suspense, streaming SSR, React Compiler 매 모든 것 위에 빌드.
## 매 핵심
### 매 핵심 idea
- **Interruptible** — render 중 high-priority work (input, animation) 매 들어오면 yield.
- **Concurrent (NOT parallel)** — single-threaded JS 위에서 cooperative scheduling.
- **Time-slicing** — 5ms chunk 매 yield to browser (`scheduler` package).
- **Multiple in-progress trees** — current + work-in-progress; double buffering.
- **Lane-based priority** — sync, default, transition, idle lane.
### 매 hook / API
- **`useTransition`** — non-urgent update (filter, navigation).
- **`useDeferredValue`** — debounce-like, 매 lower priority value.
- **`startTransition`** — imperative version.
- **`Suspense`** — async boundary, fallback UI.
- **`use` hook** (React 19) — read promise during render.
### 매 응용
1. Search-as-you-type — input 매 sync, list filter 매 transition.
2. Tab switching — 매 instant feel, 매 expensive subtree 의 background render.
3. SSR streaming — 매 progressive shell + island hydration.
4. Route navigation — `<Link>` prefetch + transition.
## 💻 패턴
### useTransition — heavy filter
```tsx
function Search() {
const [query, setQuery] = useState('');
const [list, setList] = useState<Item[]>(allItems);
const [isPending, startTransition] = useTransition();
return (
<>
<input
value={query}
onChange={(e) => {
setQuery(e.target.value); // urgent
startTransition(() => { // non-urgent
setList(allItems.filter(i => i.name.includes(e.target.value)));
});
}}
/>
{isPending && <Spinner />}
<List items={list} />
</>
);
}
```
### useDeferredValue
```tsx
function Page({ query }: { query: string }) {
const deferred = useDeferredValue(query);
return <ExpensiveResults query={deferred} />;
}
```
### Suspense + use (React 19+)
```tsx
function UserProfile({ userPromise }: { userPromise: Promise<User> }) {
const user = use(userPromise); // suspends if pending
return <h1>{user.name}</h1>;
}
<Suspense fallback={<Skeleton />}>
<UserProfile userPromise={fetchUser(id)} />
</Suspense>
```
### Streaming SSR (Next.js 15 / React 19)
```tsx
// app/page.tsx
export default async function Page() {
return (
<>
<Header />
<Suspense fallback={<FeedSkeleton />}>
<Feed /> {/* streamed once data ready */}
</Suspense>
</>
);
}
```
### React Compiler (2026, automatic memoization)
```tsx
// no useMemo / useCallback needed — compiler inserts
function Cart({ items }: { items: Item[] }) {
const total = items.reduce((s, i) => s + i.price, 0); // auto-memoized
return <div>{total}</div>;
}
```
### Selective hydration
```tsx
// chat panel hydrates first if user clicks it,
// even if header is still loading
<Suspense fallback={<Sk />}>
<Header />
</Suspense>
<Suspense fallback={<Sk />}>
<Chat />
</Suspense>
```
### Cancel stale render (transition supersession)
```tsx
// older transition automatically discarded when new one starts
startTransition(() => setQuery('a')); // discarded
startTransition(() => setQuery('ab')); // wins
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Input + heavy derived UI | `useTransition` |
| External lib slow value | `useDeferredValue` |
| Async data | `Suspense` + `use` |
| SSR with slow data | streaming + Suspense islands |
| Manual memoization (legacy) | replace with React Compiler |
**기본값**: React 19+ with Compiler; transitions for any non-urgent update.
## 🔗 Graph
- 부모: [[React]] · [[Rendering Pipeline]]
- 변형: [[Fiber_Architecture|Fiber Architecture]] · [[Time_Slicing|Time Slicing]]
- 응용: [[Streaming SSR]]
- Adjacent: [[Virtual_DOM과_Reconciliation|Virtual DOM]] · [[Reconciliation]] · [[React Compiler]]
## 🤖 LLM 활용
**언제**: identify component 매 transition 으로 wrap 할 후보, code review 매 missed Suspense boundary.
**언제 X**: scheduler internals 의 deep debug (need devtools profiler).
## ❌ 안티패턴
- **`startTransition` for urgent input**: input lag.
- **No Suspense fallback**: 매 entire tree freeze 까지 falling back.
- **Manual memoization with React Compiler**: redundant + sometimes 더 느림.
- **Async setState in transition without race control**: stale data.
- **Deferred value of huge object reference**: 매 GC pressure.
## 🧪 검증 / 중복
- Verified (React 18 release notes 2022, React 19 docs 2026, Acdlite/Sebastian Markbåge talks).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content with React 19 + Compiler patterns |
@@ -0,0 +1,178 @@
---
id: wiki-2026-0508-control-systems-engineering
title: Control Systems Engineering
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [control-systems, feedback-control, PID-control]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [control-systems, pid, mpc, feedback]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: do-mpc/control
---
# Control Systems Engineering
## 매 한 줄
> **"매 control 의 매 measure → compare → actuate 의 closed loop"**. 매 PID (1922 Minorsky) 가 매 95% industrial loops, 매 MPC (Model Predictive Control) 가 매 multivariable + constrained problems 의 dominant. 2026 의 매 RL-augmented control + neural ODEs 가 매 emerging — 매 Boston Dynamics, Tesla Autopilot, NVIDIA GR00T 가 hybrid.
## 매 핵심
### 매 building blocks
- **Plant** — 매 controlled system (motor, reactor, drone).
- **Sensor** — 매 measurement (encoder, IMU, thermocouple).
- **Controller** — 매 algorithm (PID, MPC, LQR).
- **Actuator** — 매 output (PWM, valve, voltage).
- **Reference / setpoint** — 매 desired state.
### 매 stability
- **Open-loop**: 매 simple, 매 no feedback — 매 disturbance 에 fragile.
- **Closed-loop**: 매 feedback — 매 disturbance reject + setpoint track.
- **Stability criteria**: Routh-Hurwitz, Nyquist, Bode (gain margin > 6 dB, phase margin > 45°).
### 매 controller spectrum
1. **Bang-bang** — 매 thermostat.
2. **PID** — 매 95% loops.
3. **State-space (LQR / pole placement)** — MIMO linear.
4. **MPC** — 매 constrained, predictive.
5. **Adaptive / gain scheduling** — 매 nonlinear plants.
6. **RL / learned policy** — 매 high-dim, 매 simulation 의 train.
7. **Robust H∞** — 매 worst-case guarantees.
## 💻 패턴
### Discrete PID with anti-windup
```python
class PID:
def __init__(self, kp, ki, kd, dt, u_min, u_max):
self.kp, self.ki, self.kd, self.dt = kp, ki, kd, dt
self.u_min, self.u_max = u_min, u_max
self.i, self.prev_e = 0.0, 0.0
def step(self, setpoint, measurement):
e = setpoint - measurement
self.i += e * self.dt
d = (e - self.prev_e) / self.dt
u = self.kp*e + self.ki*self.i + self.kd*d
u_clamped = max(self.u_min, min(self.u_max, u))
# 매 anti-windup: 매 saturate 시 integrator 의 back-calc
if u != u_clamped:
self.i -= (u - u_clamped) / self.ki if self.ki else 0
self.prev_e = e
return u_clamped
```
### Ziegler-Nichols 의 tune
```python
def ziegler_nichols(Ku, Tu, kind='PID'):
if kind == 'PID':
return dict(kp=0.6*Ku, ki=1.2*Ku/Tu, kd=0.075*Ku*Tu)
if kind == 'PI':
return dict(kp=0.45*Ku, ki=0.54*Ku/Tu, kd=0)
```
### State-space LQR (CartPole)
```python
import numpy as np
from scipy.linalg import solve_continuous_are
A = np.array([[0,1,0,0],[0,0,-mp*g/M,0],[0,0,0,1],[0,0,(M+mp)*g/(M*l),0]])
B = np.array([[0],[1/M],[0],[-1/(M*l)]])
Q = np.diag([1, 1, 10, 10]); R = np.array([[0.1]])
P = solve_continuous_are(A, B, Q, R)
K = np.linalg.inv(R) @ B.T @ P
u = -K @ x # state feedback
```
### MPC with do-mpc
```python
import do_mpc
model = do_mpc.model.Model('continuous')
x = model.set_variable('_x', 'x', shape=(2,1))
u = model.set_variable('_u', 'u')
model.set_rhs('x', np.array([[x[1]],[u - 0.1*x[1]]]))
model.setup()
mpc = do_mpc.controller.MPC(model)
mpc.set_param(n_horizon=20, t_step=0.1)
mpc.set_objective(mterm=x[0]**2, lterm=x[0]**2 + 0.01*u**2)
mpc.bounds['lower','_u','u'] = -5; mpc.bounds['upper','_u','u'] = 5
mpc.setup()
```
### Kalman filter (state estimation)
```python
def kalman_step(x, P, u, z, A, B, H, Q, R):
x_pred = A @ x + B @ u
P_pred = A @ P @ A.T + Q
K = P_pred @ H.T @ np.linalg.inv(H @ P_pred @ H.T + R)
x = x_pred + K @ (z - H @ x_pred)
P = (np.eye(len(x)) - K @ H) @ P_pred
return x, P
```
### RL policy (PPO via stable-baselines3)
```python
from stable_baselines3 import PPO
import gymnasium as gym
env = gym.make("Pendulum-v1")
model = PPO("MlpPolicy", env, verbose=1)
model.learn(total_timesteps=200_000)
```
### Real-time loop (Linux PREEMPT_RT)
```python
import time, os
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(80))
T = 0.001 # 1 kHz
while True:
t0 = time.perf_counter()
u = pid.step(setpoint, sensor.read())
actuator.write(u)
while time.perf_counter() - t0 < T: pass
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 SISO + linear | PID |
| 매 MIMO + linear | LQR / state-space |
| Constrained + slow plant | MPC |
| Nonlinear + simulator 가능 | RL (PPO, SAC) |
| Safety-critical + uncertain | Robust H∞ / sliding mode |
| 매 very fast (>10 kHz) | Hardware PID (FPGA) |
**기본값**: PID with proper tuning + anti-windup; escalate to MPC if multivariable or constrained.
## 🔗 Graph
- 부모: [[Cyber-Physical-Systems]] · [[Robotics]]
- 변형: [[PID]] · [[MPC]]
- 응용: [[Digital-Twin]]
- Adjacent: [[Kalman-Filter-and-State-Tracking|Kalman-Filter]] · [[Reinforcement-Learning]]
## 🤖 LLM 활용
**언제**: 매 controller derivation explanation, 매 transfer function manipulation, 매 tuning suggestion based on step response, 매 simulation script generation.
**언제 X**: 매 actual real-time loop (deterministic 코드 / FPGA). 매 safety certification (formal verification 필요).
## ❌ 안티패턴
- **No anti-windup**: 매 actuator saturate 시 integral runaway → overshoot.
- **Derivative on error (vs measurement)**: 매 setpoint step 시 derivative kick — derivative-on-PV 사용.
- **Tune via trial-and-error only**: 매 system identification 의 사용 (Ziegler-Nichols, FOPDT fit).
- **MPC without warm-start**: 매 solve time 의 explode — previous solution 의 reuse.
- **No filter on derivative**: 매 measurement noise 가 D term 의 amplify.
- **RL on real hardware first**: 매 sim-to-real 의 가야 — safe exploration.
## 🧪 검증 / 중복
- Verified (Åström & Murray "Feedback Systems", Skogestad MIMO control, do-mpc docs, IEEE control textbooks).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — control engineering: PID, LQR, MPC, RL, Kalman |
@@ -0,0 +1,171 @@
---
id: wiki-2026-0508-dom
title: DOM (Document Object Model)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [DOM, Document Object Model, DOM Tree]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [dom, web, browser, html, javascript]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: javascript
framework: browser
---
# DOM (Document Object Model)
## 매 한 줄
> **"매 HTML/XML document 의 tree 표현, language-agnostic API"**. W3C 표준 (1998), 현재 WHATWG DOM Living Standard. 매 browser 매 internal representation; 2026 현재 React/Vue/Solid 매 abstraction layer 위에 있지만, performance/edge cases 매 직접 DOM 이해 매 essential.
## 매 핵심
### 매 구조
- **Document** root.
- **Element node** (`<div>`, `<p>`).
- **Text node** (literal text).
- **Attribute** (element 의 property; not separate child node since DOM4).
- **Comment node**.
- **DocumentFragment** — lightweight sub-tree, not connected.
- **ShadowRoot** — encapsulated sub-tree (Web Components).
### 매 traversal
- `parentNode`, `childNodes`, `firstChild`, `lastChild`, `nextSibling`, `previousSibling`.
- `children` (Element only), `firstElementChild`.
- `querySelector` / `querySelectorAll` — CSS selector.
- `closest(selector)` — ancestor matching.
### 매 mutation
- `appendChild`, `insertBefore`, `removeChild`, `replaceChild` (legacy).
- `append`, `prepend`, `before`, `after`, `replaceWith`, `remove` (modern).
- `cloneNode(deep)`.
### 매 응용
1. Vanilla JS DOM 조작.
2. React reconciler 매 virtual DOM diff → real DOM mutation.
3. Web Components Shadow DOM encapsulation.
4. Server-side render (jsdom, happy-dom) 매 SSR.
5. Browser automation (Playwright, Puppeteer).
## 💻 패턴
### Modern element creation (no innerHTML)
```javascript
const card = Object.assign(document.createElement('article'), {
className: 'card',
});
card.append(
Object.assign(document.createElement('h2'), { textContent: title }),
Object.assign(document.createElement('p'), { textContent: body }),
);
container.append(card);
```
### Event delegation
```javascript
list.addEventListener('click', (e) => {
const item = e.target.closest('.item');
if (!item || !list.contains(item)) return;
handleClick(item.dataset.id);
});
```
### DocumentFragment — batch insert
```javascript
const frag = document.createDocumentFragment();
for (const item of items) {
const li = document.createElement('li');
li.textContent = item.name;
frag.append(li);
}
list.append(frag); // single reflow
```
### MutationObserver
```javascript
const observer = new MutationObserver((mutations) => {
for (const m of mutations) {
if (m.type === 'childList') console.log('children changed');
}
});
observer.observe(target, { childList: true, subtree: true, attributes: true });
```
### Shadow DOM (Web Component)
```javascript
class CounterButton extends HTMLElement {
#count = 0;
connectedCallback() {
const root = this.attachShadow({ mode: 'open' });
root.innerHTML = `<style>button{padding:8px}</style><button>0</button>`;
root.querySelector('button').onclick = () => {
this.#count++;
root.querySelector('button').textContent = this.#count;
};
}
}
customElements.define('counter-button', CounterButton);
```
### Range & Selection
```javascript
const range = document.createRange();
range.selectNodeContents(el);
const text = range.toString();
```
### IntersectionObserver — lazy load
```javascript
const io = new IntersectionObserver((entries) => {
for (const e of entries) {
if (e.isIntersecting) {
e.target.src = e.target.dataset.src;
io.unobserve(e.target);
}
}
});
document.querySelectorAll('img[data-src]').forEach((img) => io.observe(img));
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| App-level UI | React / Vue / Solid (don't touch DOM) |
| Library / web component | Shadow DOM + custom element |
| One-off page | Vanilla JS (`querySelector`, `append`) |
| Test / SSR | jsdom / happy-dom |
| Watch external mutations | MutationObserver |
**기본값**: framework abstraction; vanilla DOM API for libraries / leaf optimization.
## 🔗 Graph
- 부모: [[Web Standards]]
- 변형: [[Virtual_DOM과_Reconciliation|Virtual DOM]] · [[Shadow DOM]]
- 응용: [[React]] · [[Web Components]] · [[Playwright]]
- Adjacent: [[CSSOM]] · [[Reflow_and_Repaint|Reflow & Repaint]]
## 🤖 LLM 활용
**언제**: DOM snippet 생성, accessibility audit, querySelector 추천.
**언제 X**: real-time interaction (LLM 매 round-trip 너무 느림).
## ❌ 안티패턴
- **innerHTML with user input**: XSS.
- **Layout thrashing**: read-write-read-write 매 force reflow 매 loop.
- **No event delegation**: 매 list item 매 listener → memory leak.
- **Detached node leak**: removed but reference 보유 → GC 실패.
- **Manipulate DOM in framework-controlled subtree**: React reconciler 와 충돌.
## 🧪 검증 / 중복
- Verified (WHATWG DOM Living Standard 2026, MDN).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full canonical content with modern DOM APIs |
@@ -0,0 +1,184 @@
---
id: wiki-2026-0508-dora-metrics
title: DORA Metrics
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [dora, four-keys, accelerate-metrics]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [dora, devops, metrics, delivery-performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: sql
framework: github-actions/grafana
---
# DORA Metrics
## 매 한 줄
> **"매 software delivery performance 의 매 4 numbers"**: deployment frequency, lead time for changes, change failure rate, mean time to restore (MTTR). 매 Forsgren/Humble/Kim "Accelerate" (2018) + 매 yearly DORA report 가 매 source-of-truth. 2026 의 매 5번째 metric (reliability) 의 official.
## 매 핵심
### 매 the 4 (now 5)
1. **Deployment Frequency (DF)** — production deploys per period. Elite: on-demand (multiple/day).
2. **Lead Time for Changes (LT)** — commit → production. Elite: < 1 day.
3. **Change Failure Rate (CFR)** — % deploys causing incident/rollback. Elite: 05%.
4. **Mean Time to Restore (MTTR)** — incident detection → resolution. Elite: < 1 hour.
5. **Reliability** (added 2021/2022 reports) — meeting/exceeding SLO targets.
### 매 performance bands (2024 report)
- **Elite** — frequent deploys, < 1 day LT, 05% CFR, < 1h MTTR.
- **High** — weeklymonthly, 1 day1 week, 010%, < 1 day.
- **Medium** — monthly6m, 1 week1 month, 015%, < 1 week.
- **Low** — < 6m, > 6m, > 64%, > 1 week.
### 매 accelerators (capabilities)
- Trunk-based development.
- Continuous integration.
- Test automation.
- Loosely coupled architecture.
- Generative culture (Westrum).
- Database change automation.
- Empowered teams.
## 💻 패턴
### Lead time SQL (GitHub + production deploy events)
```sql
-- 매 first commit in PR → production deploy 의 measure
WITH deploys AS (
SELECT service, deploy_id, deployed_at, sha
FROM deployments WHERE environment = 'production'
),
commits AS (
SELECT pr.merge_commit_sha AS sha, MIN(c.committed_at) AS first_commit_at
FROM pull_requests pr JOIN commits c ON c.pr_id = pr.id
GROUP BY pr.merge_commit_sha
)
SELECT d.service,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM d.deployed_at - c.first_commit_at)) AS lt_p50_seconds,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM d.deployed_at - c.first_commit_at)) AS lt_p95_seconds
FROM deploys d JOIN commits c USING (sha)
WHERE d.deployed_at > NOW() - INTERVAL '90 days'
GROUP BY d.service;
```
### GitHub Actions 의 deploy event emit
```yaml
- name: Record deployment
if: success()
run: |
curl -X POST "$DORA_API/deployments" \
-H "Authorization: Bearer $TOKEN" \
-d "{\"service\":\"orders\",\"sha\":\"${{ github.sha }}\",\"environment\":\"production\",\"deployed_at\":\"$(date -u +%FT%TZ)\"}"
```
### Change failure (PagerDuty + deploy correlation)
```ts
async function changeFailureRate(service: string, days = 30) {
const deploys = await db.deployments.count({ service, since: daysAgo(days) });
const failedDeploys = await db.deployments.count({
service, since: daysAgo(days),
correlatedIncidentWithin: '4h', // 매 incident 가 deploy 후 4h 내 의 fail count
});
return failedDeploys / deploys;
}
```
### MTTR from PagerDuty
```ts
import { api } from '@pagerduty/pdjs';
const pd = api({ token: process.env.PD_TOKEN! });
const { data } = await pd.get('/incidents', {
data: { since: daysAgo(30), service_ids: [SVC_ID], statuses: ['resolved'] },
});
const durations = data.incidents.map(i =>
(new Date(i.resolved_at).getTime() - new Date(i.created_at).getTime()) / 1000);
const mttr = durations.reduce((a,b)=>a+b,0) / durations.length;
```
### Four Keys (Google) on BigQuery
```sql
-- 매 https://github.com/dora-team/fourkeys 의 reference
SELECT
COUNTIF(event_type = 'deployment') AS deploys,
AVG(TIMESTAMP_DIFF(deploy_time, first_commit_time, MINUTE)) AS lt_minutes,
COUNTIF(failed) / NULLIF(COUNTIF(event_type = 'deployment'), 0) AS cfr,
AVG(TIMESTAMP_DIFF(resolved_time, incident_time, MINUTE)) AS mttr_minutes
FROM `project.four_keys.events_raw`
WHERE deploy_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
```
### Grafana dashboard panel (PromQL-style)
```promql
# Deployment frequency (deploys per day per service)
sum by (service) (rate(deployments_total{env="production"}[7d])) * 86400
# Change failure rate
sum by (service) (deployments_failed_total[30d])
/ sum by (service) (deployments_total[30d])
# Lead time p50
histogram_quantile(0.5, sum by (le, service) (rate(deploy_lead_time_seconds_bucket[30d])))
```
### Reliability (SLO-aligned 5th metric)
```ts
// 매 service 의 SLO 의 meeting-or-exceeding 의 % of measurement windows
const reliability = await prom.query(`
(sum_over_time(slo_compliance{service="$svc"}[30d]) /
count_over_time(slo_compliance{service="$svc"}[30d])) * 100
`);
```
### Anti-gaming guardrails
```ts
// 매 metric 의 isolated 의 game 가 가능 — pair 의 always 의 read
const elite = (df > 1/day) && (lt < 1*day) && (cfr < 0.05) && (mttr < 1*hour);
// 매 elite 가 X 만 high cfr 의 hide 의 X.
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Greenfield team | Adopt Four Keys (open source) on BigQuery |
| GitHub-centric | dora-team/fourkeys + Cloud Run pipelines |
| Multi-tool | LinearB / Sleuth / Faros AI / Jellyfish (SaaS) |
| Self-host | Apache DevLake (LF AI) |
| Enterprise governance | Faros + custom dashboards |
**기본값**: Apache DevLake (open source) or Four Keys reference impl; weekly review with team; show all 4 (5) together — never single metric.
## 🔗 Graph
- 부모: [[DevOps]] · [[Continuous-Delivery]]
- 변형: [[Engineering-Metrics]]
- 응용: [[Trunk-Based-Development]] · [[Continuous-Integration]] · [[SRE]]
- Adjacent: [[Postmortem-Culture]]
## 🤖 LLM 활용
**언제**: 매 metric definition explanation, 매 SQL/PromQL query authoring, 매 trend interpretation, 매 retrospective talking points generation.
**언제 X**: 매 individual performance evaluation (DORA 의 team-level metric — never individual). 매 metric tuning to look good (gaming).
## ❌ 안티패턴
- **Single metric optimization**: 매 deploy frequency 의 increase 만 → CFR explodes. 매 4 의 always 의 together 보기.
- **Individual performance ranking**: 매 explicitly anti-pattern in DORA research. 매 team-level만.
- **Vanity deploys**: 매 empty commits / config-only changes 의 count → meaningless.
- **MTTR from "ticket close"**: 매 customer-impact end 의 measure, 매 ticket admin 가 X.
- **Comparing teams in different domains**: 매 fintech vs internal tool 의 baselines 가 different.
- **No deployment instrumentation**: 매 manual spreadsheet 가 X. 매 auto-emit deploy event.
## 🧪 검증 / 중복
- Verified (Forsgren/Humble/Kim "Accelerate" 2018, Google DORA 2024 State of DevOps report, dora-team/fourkeys, Apache DevLake).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — DORA 4(5) metrics, queries, anti-patterns |
@@ -0,0 +1,170 @@
---
id: wiki-2026-0508-deepreadonly
title: DeepReadonly
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [deep-readonly, recursive-readonly, immutable-type]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-utility, immutability]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: typescript-5.x
---
# DeepReadonly
## 매 한 줄
> **"매 `Readonly<T>` 의 surface-only — 매 nested mutation 가 still possible"**. 매 DeepReadonly<T> 가 매 recursively 의 every property 의 readonly 의 mark — 매 redux state, config object, frozen domain model 의 essential. TS 5.x 의 매 `const` type parameter + DeepReadonly 가 매 powerful combo.
## 매 핵심
### 매 vs Readonly
- `Readonly<T>` — 매 top-level only. 매 `obj.nested.mutate = X` 가 still allowed.
- `DeepReadonly<T>` — 매 every level 의 recursive freeze.
### 매 type-only vs runtime
- DeepReadonly 의 매 compile-time type guarantee — 매 runtime 의 mutation 의 X protect.
- 매 runtime freeze 의 `Object.freeze` (shallow) 또는 `deepFreeze` helper 사용.
- TypeScript 5.0+ `as const` 의 매 literal-level deep readonly 의 produce.
### 매 사용처
1. Redux/Zustand state shape — 매 mutation prevent.
2. Configuration schemas (env config, feature flags).
3. API response DTOs after parse.
4. Domain entities in DDD value objects.
5. Test fixtures (prevent accidental modification).
## 💻 패턴
### Basic DeepReadonly
```ts
type DeepReadonly<T> = T extends (...args: any[]) => any
? T
: T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T;
interface User {
id: string;
profile: { name: string; tags: string[] };
}
const u: DeepReadonly<User> = { id: '1', profile: { name: 'a', tags: ['x'] } };
// u.profile.name = 'b'; // ❌ Cannot assign
// u.profile.tags.push('y'); // ❌ readonly array
```
### Handles Map / Set / Array
```ts
type DeepReadonly<T> =
T extends (infer U)[] ? readonly DeepReadonly<U>[]
: T extends Map<infer K, infer V> ? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends Set<infer U> ? ReadonlySet<DeepReadonly<U>>
: T extends Promise<infer U> ? Promise<DeepReadonly<U>>
: T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T;
```
### Brand-aware (preserve nominal types)
```ts
type Brand<T, B> = T & { readonly __brand: B };
type DeepReadonly<T> = T extends Brand<infer U, infer B>
? Brand<DeepReadonly<U>, B>
: T extends object
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: T;
```
### Runtime deepFreeze pair
```ts
export function deepFreeze<T>(obj: T): DeepReadonly<T> {
if (obj && typeof obj === 'object' && !Object.isFrozen(obj)) {
Object.freeze(obj);
for (const key of Object.keys(obj)) deepFreeze((obj as any)[key]);
}
return obj as DeepReadonly<T>;
}
```
### `as const` + DeepReadonly
```ts
const config = {
features: { newCheckout: true, beta: ['user1', 'user2'] },
limits: { rpm: 100 },
} as const;
// 매 `as const` 가 매 every literal 의 deeply readonly + literal-typed 로 만듦.
type Config = typeof config;
// Config['features']['beta'] === readonly ['user1', 'user2']
```
### Mutable inverse (DeepWritable)
```ts
type DeepWritable<T> = T extends (...args: any[]) => any
? T
: T extends object
? { -readonly [K in keyof T]: DeepWritable<T[K]> }
: T;
function clone<T>(x: DeepReadonly<T>): DeepWritable<T> {
return structuredClone(x as T) as DeepWritable<T>;
}
```
### Zod + DeepReadonly
```ts
import { z } from 'zod';
const UserSchema = z.object({ id: z.string(), tags: z.array(z.string()) }).readonly();
type User = DeepReadonly<z.infer<typeof UserSchema>>;
```
### Function args (Redux reducer)
```ts
function reducer<S, A>(state: DeepReadonly<S>, action: A): S {
// state.x = ... // ❌ compile error
return { ...(state as S), updated: true } as S;
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Literal config | `as const` |
| Generic state shape | `DeepReadonly<T>` utility |
| Runtime guarantee 필요 | `deepFreeze` + DeepReadonly |
| Performance hot path | 매 type-only DeepReadonly (no runtime cost) |
| Library author 가 expose | DeepReadonly + readonly arrays in public API |
**기본값**: type-only DeepReadonly + `as const` for literals; runtime `deepFreeze` only for security-sensitive boundaries.
## 🔗 Graph
- 부모: [[TypeScript-Type-System]] · [[Immutability]]
- 변형: [[Readonly]] · [[as-const]]
- 응용: [[Zustand]] · [[Domain-Driven-Design]]
- Adjacent: [[Branded-Types]] · [[Zod]] · [[Structural-Sharing]]
## 🤖 LLM 활용
**언제**: 매 utility type 의 design / extension, 매 type error explanation, 매 readonly violation 의 codemod 작성.
**언제 X**: 매 runtime data validation (Zod 사용). 매 hot-path performance tuning (TS types 가 erased — runtime cost 0).
## ❌ 안티패턴
- **함수 type 의 readonly 적용**: 매 `(...args) => any` 가 readonly 의 의미 X — special-case 필요.
- **Date / RegExp 의 recurse**: 매 built-in instances 가 깨짐 — exclude 의 type guard.
- **DeepReadonly + cast away**: `state as Mutable` 가 매 type safety 의 destroy.
- **Runtime mutation through cast**: 매 `(state as any).x = 1` — 매 type lie 의 propagate.
- **Naive `keyof T` on union**: distributive conditional 의 사용.
## 🧪 검증 / 중복
- Verified (TypeScript 5.x docs, type-fest library, ts-toolbelt).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — DeepReadonly utility type variants and patterns |
@@ -0,0 +1,162 @@
---
id: wiki-2026-0508-dependencies-의존성
title: Dependencies (의존성)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [npm-dependencies, package-dependencies, supply-chain]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [dependencies, npm, semver, supply-chain]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: javascript
framework: npm/pnpm
---
# Dependencies (의존성)
## 매 한 줄
> **"매 dependency 의 liability 가 X asset"**. 매 npm install 이 매 third-party code 를 매 production 에 inject — 매 supply chain attack (event-stream 2018, ua-parser-js 2021, xz-utils 2024 backdoor) 가 매 매년 발생. 2026 modern stack 의 매 pnpm + lockfile + minimum-deps + SBOM (CycloneDX) 가 매 standard.
## 매 핵심
### 매 Dependency 종류
- **dependencies**: 매 production runtime 의 사용 (Express, React).
- **devDependencies**: 매 build/test only (Vitest, TypeScript, ESLint).
- **peerDependencies**: 매 host 가 provide (React plugin 의 React).
- **optionalDependencies**: 매 install 실패 가 OK (platform-specific binaries).
- **bundledDependencies**: 매 package tarball 안 ship.
### 매 Semver
- `^1.2.3` — minor + patch updates (1.x.x), 매 npm default. 매 unsafe 가 0.x 에서 (^0.2.3 → 0.2.x only).
- `~1.2.3` — patch only (1.2.x).
- `1.2.3` — exact pin, 매 reproducibility 의 best.
- `*` / `latest` — 매 X. 매 절대 사용 X.
### 매 Lockfile
- **pnpm-lock.yaml** / **package-lock.json** / **yarn.lock**: 매 exact resolved versions + integrity hashes.
-`npm ci` 사용 (매 install 가 X) — 매 lockfile 강제, deterministic install.
- 매 commit 의 must.
### 매 Supply Chain Risks
- **Typosquatting**: `reqeusts`, `lodahs`.
- **Compromised maintainer**: 매 ua-parser-js 2021.
- **Malicious update**: 매 event-stream 2018, xz-utils 2024.
- **Dependency confusion**: 매 internal package name 가 public registry 에 publish 됨.
## 💻 패턴
### Pinning + lockfile
```json
{
"dependencies": {
"react": "18.3.1",
"express": "~4.21.0",
"zod": "^3.23.8"
},
"engines": { "node": ">=20.10.0", "pnpm": ">=9.0.0" }
}
```
### pnpm 의 strict install
```bash
# CI 의 deterministic install
pnpm install --frozen-lockfile
# 매 lockfile mismatch 시 error.
# 매 audit
pnpm audit --audit-level=high
```
### Renovate config
```json
// renovate.json
{
"extends": ["config:recommended"],
"lockFileMaintenance": { "enabled": true, "schedule": ["before 5am on Monday"] },
"vulnerabilityAlerts": { "enabled": true, "labels": ["security"] },
"packageRules": [
{ "matchUpdateTypes": ["minor", "patch"], "automerge": true, "matchCurrentVersion": "!/^0/" },
{ "matchPackagePatterns": ["^@types/"], "automerge": true }
]
}
```
### SBOM 생성 (CycloneDX)
```bash
npx @cyclonedx/cyclonedx-npm --output-file sbom.json
# 매 SLSA / EU CRA compliance 의 사용.
```
### Known-good integrity check
```bash
# 매 npm install 후 lockfile integrity 검증
pnpm install --frozen-lockfile --prefer-offline
# Subresource integrity 가 lockfile 에 자동 record.
```
### Allowed-dependencies guard (CI)
```ts
// scripts/check-deps.ts
import pkg from '../package.json' with { type: 'json' };
const ALLOWED_LICENSES = new Set(['MIT', 'Apache-2.0', 'BSD-3-Clause', 'ISC']);
// 매 license-checker 사용 의 production deps audit.
```
### Provenance verification
```bash
# 매 npm 9.5+ 의 sigstore provenance
npm install --foreground-scripts=false
npm audit signatures
# 매 GitHub Actions 의 publish 한 package 만 trust.
```
### Dependency removal
```bash
pnpm dlx depcheck
# 매 unused dep 찾기. 매 quarterly cleanup.
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Library author | `peerDependencies` + minimal `dependencies` |
| Application | Pin all critical (React, framework), `^` for utilities |
| Monorepo | pnpm workspaces + catalogs (pnpm 9.5+) |
| 매 high-security (fintech, gov) | Exact pin all, Renovate manual approve, internal mirror |
| 매 prototype | `^` everywhere, 매 lockfile commit 만 |
**기본값**: pnpm + frozen lockfile + Renovate auto-merge minors + SBOM in CI.
## 🔗 Graph
- 부모: [[Software-Architecture]]
- 변형: [[Monorepo]]
- 응용: [[Dependency-Analysis]] · [[SBOM]]
- Adjacent: [[Supply-Chain-Security]] · [[Renovate]] · [[Dependabot]]
## 🤖 LLM 활용
**언제**: 매 package.json review, 매 vulnerability triage, 매 dep upgrade plan generation, 매 SBOM diff explanation.
**언제 X**: 매 actual install / build (deterministic tooling 가 better). 매 license decision (legal review 필요).
## ❌ 안티패턴
- **`*` or `latest`**: 매 reproducibility destroyed.
- **lockfile gitignore**: 매 다른 dev / CI 가 different versions install.
- **`npm install` in CI**: 매 `npm ci` / `pnpm install --frozen-lockfile` 사용.
- **0.x with `^`**: 매 ^0.2.3 가 0.3.0 으로 jump 가능 — breaking changes.
- **Untyped transitive deps**: 매 매 indirect 의 audit X. SBOM 의 review.
- **Package without provenance**: 매 2026 의 sigstore signed packages prefer.
## 🧪 검증 / 중복
- Verified (npm docs, pnpm docs, SLSA framework, CycloneDX spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — npm dependency management, semver, supply chain hardening |
@@ -0,0 +1,168 @@
---
id: wiki-2026-0508-digital-twin
title: Digital Twin
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [digital-twin, virtual-replica, cyber-physical-system]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [digital-twin, iot, simulation, cps]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: NVIDIA-Omniverse/Azure-Digital-Twins
---
# Digital Twin
## 매 한 줄
> **"매 digital twin 의 매 physical asset 의 living mirror"**. 매 sensor stream 가 매 simulation model 에 feed → 매 prediction / what-if / control. 2026 의 매 NVIDIA Omniverse + OpenUSD, Azure Digital Twins, AWS IoT TwinMaker 가 매 enterprise standard. 매 LLM-augmented reasoning over twin (Claude Opus 4.7 + DTDL graph query) 의 매 emerging.
## 매 핵심
### 매 3-tier
- **Digital Model** — 매 static representation, 매 sync X.
- **Digital Shadow** — 매 one-way sync (physical → digital).
- **Digital Twin** — 매 bidirectional sync (digital → physical control 의 가능).
### 매 ingredient
- **3D geometry** (OpenUSD, glTF).
- **Telemetry** (MQTT, OPC UA, AVRO over Kafka).
- **Physics / behavior** (FMU, Modelica, Isaac Sim, Omniverse PhysX).
- **Ontology / DTDL** (Digital Twins Definition Language).
- **AI layer** (anomaly detection, forecasting, RL policy).
### 매 응용
1. **Manufacturing**: BMW iFactory — 매 line 의 reconfigure 의 digital first.
2. **City** — Singapore Virtual Singapore, Helsinki 3D+.
3. **Energy grid** — 매 outage prediction, demand response.
4. **Healthcare** — patient-specific cardiac twin (Dassault Living Heart).
5. **Robotics fleet** — 매 Isaac Sim 의 sim-to-real RL training.
## 💻 패턴
### Azure Digital Twins (DTDL v3)
```json
{
"@context": "dtmi:dtdl:context;3",
"@id": "dtmi:com:factory:Pump;1",
"@type": "Interface",
"contents": [
{ "@type": "Property", "name": "serialNumber", "schema": "string" },
{ "@type": "Telemetry", "name": "rpm", "schema": "double" },
{ "@type": "Telemetry", "name": "temperature", "schema": "double" },
{ "@type": "Command", "name": "shutdown" },
{ "@type": "Relationship", "name": "feedsInto", "target": "dtmi:com:factory:Tank;1" }
]
}
```
### MQTT → twin update (Python)
```python
import paho.mqtt.client as mqtt
from azure.digitaltwins.core import DigitalTwinsClient
dt = DigitalTwinsClient("https://factory.api.weu.digitaltwins.azure.net", credential)
def on_msg(client, _, msg):
payload = json.loads(msg.payload)
patch = [{"op": "replace", "path": "/rpm", "value": payload["rpm"]},
{"op": "replace", "path": "/temperature", "value": payload["temp"]}]
dt.update_digital_twin(payload["twin_id"], patch)
c = mqtt.Client()
c.on_message = on_msg
c.connect("mqtt.factory.local", 1883)
c.subscribe("factory/+/telemetry")
c.loop_forever()
```
### Twin graph query (Cypher-like)
```text
SELECT pump, tank
FROM DIGITALTWINS pump
JOIN tank RELATED pump.feedsInto
WHERE pump.temperature > 85
AND IS_OF_MODEL(pump, 'dtmi:com:factory:Pump;1')
```
### Omniverse + OpenUSD scene composition
```python
from pxr import Usd, UsdGeom, Sdf
stage = Usd.Stage.CreateNew("factory.usda")
factory = UsdGeom.Xform.Define(stage, "/Factory")
pump = stage.OverridePrim("/Factory/Pump_42")
pump.CreateAttribute("custom:rpm", Sdf.ValueTypeNames.Float).Set(1480.0)
pump.CreateAttribute("custom:temperature", Sdf.ValueTypeNames.Float).Set(72.3)
stage.Save()
```
### Anomaly detection on twin stream
```python
from river import anomaly # online learning
detector = anomaly.HalfSpaceTrees(seed=42)
async for event in kafka_consumer("factory.telemetry"):
score = detector.score_one({"rpm": event.rpm, "temp": event.temp})
detector.learn_one({"rpm": event.rpm, "temp": event.temp})
if score > 0.95:
await dt.update_relationships(event.twin_id, "alert_state", "anomaly")
```
### LLM reasoning over twin graph
```python
graph_context = dt.query_twins("SELECT * FROM digitaltwins WHERE temperature > 80")
response = anthropic.messages.create(
model="claude-opus-4-7",
system="You analyze factory digital twin state for root-cause hypotheses.",
messages=[{"role": "user", "content": f"Twins: {graph_context}\nWhy is line 3 throughput dropping?"}],
)
```
### Sim-to-real RL (Isaac Sim)
```python
from omni.isaac.gym.vec_env import VecEnvBase
env = VecEnvBase(headless=True)
# 매 4096 parallel pump sims 의 train, 매 policy 가 real pump 에 deploy.
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 high-fidelity physics | NVIDIA Omniverse + Isaac Sim |
| 매 enterprise IoT graph | Azure Digital Twins (DTDL) |
| 매 AWS-native | AWS IoT TwinMaker |
| 매 city / GIS | CesiumJS + 3D Tiles |
| 매 scientific sim | Modelica + FMU |
**기본값**: Azure Digital Twins or AWS TwinMaker for graph + telemetry; Omniverse for 3D/physics; OpenUSD for interchange.
## 🔗 Graph
- 부모: [[Cyber-Physical-Systems]]
- 응용: [[Predictive-Maintenance]]
- Adjacent: [[Control_Systems_Engineering|Control-Systems-Engineering]] · [[MQTT]]
## 🤖 LLM 활용
**언제**: 매 twin graph 의 natural-language query → DTDL/SQL translation, 매 anomaly explanation, 매 maintenance work order generation.
**언제 X**: 매 hard-realtime control loop (sub-ms). 매 safety-critical actuation (deterministic controller 의 사용).
## ❌ 안티패턴
- **3D model only**: 매 telemetry 가 X — 매 just CAD viewer.
- **No bidirectional channel**: 매 just shadow, 매 not twin.
- **Monolithic schema**: 매 DTDL inheritance / interfaces 의 사용.
- **Synchronous queries on hot path**: 매 read replica / cache.
- **No data retention policy**: 매 telemetry storage cost 가 explodes — tiered storage (hot Kafka → warm Parquet → cold S3).
## 🧪 검증 / 중복
- Verified (Microsoft DTDL v3 spec, NVIDIA Omniverse docs, AWS IoT TwinMaker, Gartner 2025 digital twin report).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — digital twin tiers, DTDL, Omniverse, sim-to-real |
@@ -0,0 +1,191 @@
---
id: wiki-2026-0508-distributed-systems-fallacies
title: Distributed Systems Fallacies
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Fallacies of Distributed Computing, 8 Fallacies, Deutsch Fallacies]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [distributed-systems, architecture, networking, reliability]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: polyglot
framework: distributed-systems
---
# Distributed Systems Fallacies
## 매 한 줄
> **"매 network 의 invisible 한 assumption 의 매 production failure 의 source"**. 1994년 Peter Deutsch (Sun) 가 매 7 fallacies 의 articulate, 1997년 James Gosling 가 8th 의 add. 매 2026 cloud-native 시대 에도 매 microservices / serverless / edge compute 의 매 매 valid.
## 매 핵심
### 매 8 Fallacies
1. **Network 의 reliable**: 매 packet drop / partition / DNS failure 의 inevitable.
2. **Latency 의 zero**: 매 LAN ~0.5ms, 매 cross-region ~150ms, 매 satellite ~600ms.
3. **Bandwidth 의 infinite**: 매 video / ML model weights / log shipping 의 saturate.
4. **Network 의 secure**: 매 default 의 insecure — 매 zero-trust assume.
5. **Topology 의 안 변함**: 매 autoscaling / k8s pod reschedule / failover 의 매 second.
6. **Administrator 의 single**: 매 multi-cloud / multi-region 의 매 다른 policy.
7. **Transport cost 의 zero**: 매 serialization / TLS handshake / egress fee 의 real.
8. **Network 의 homogeneous**: 매 IPv4/IPv6, 매 protocol versions, 매 MTU mismatch.
### 매 왜 fallacy 인가
- 매 dev 의 localhost / monolith mental model 의 distributed 에 적용 시 fail.
- 매 "happy path" coding 의 매 timeout / retry / circuit breaker 의 lack.
- 매 50ms RTT 의 매 100 calls 의 5 second user-facing latency.
### 매 응용
1. Microservices design — 매 call graph 의 latency budget 산정.
2. Cross-region replication — 매 split-brain / eventual consistency 의 plan.
3. Edge computing — 매 intermittent connectivity 의 first-class.
## 💻 패턴
### Pattern 1: Timeout + Retry with Exponential Backoff
```typescript
async function callWithRetry<T>(
fn: () => Promise<T>,
opts = { maxRetries: 3, baseMs: 100, timeoutMs: 2000 }
): Promise<T> {
for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
try {
return await Promise.race([
fn(),
new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error("timeout")), opts.timeoutMs)
),
]);
} catch (err) {
if (attempt === opts.maxRetries) throw err;
const jitter = Math.random() * opts.baseMs;
await new Promise(r => setTimeout(r, opts.baseMs * 2 ** attempt + jitter));
}
}
throw new Error("unreachable");
}
```
### Pattern 2: Circuit Breaker (Resilience4j-style)
```typescript
class CircuitBreaker {
private failures = 0;
private state: "closed" | "open" | "half-open" = "closed";
private openedAt = 0;
constructor(private threshold = 5, private cooldownMs = 30_000) {}
async exec<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === "open" && Date.now() - this.openedAt < this.cooldownMs)
throw new Error("circuit open");
if (this.state === "open") this.state = "half-open";
try {
const r = await fn();
this.failures = 0; this.state = "closed";
return r;
} catch (e) {
if (++this.failures >= this.threshold) {
this.state = "open"; this.openedAt = Date.now();
}
throw e;
}
}
}
```
### Pattern 3: Bulkhead (concurrency limiter)
```typescript
import pLimit from "p-limit";
const dbLimit = pLimit(20); // 매 DB pool 의 isolate
const apiLimit = pLimit(50); // 매 external API 의 separate
async function getUser(id: string) {
return dbLimit(() => db.users.findOne({ id }));
}
```
### Pattern 4: Idempotency Key
```typescript
async function chargeCard(req: ChargeReq, idemKey: string) {
const cached = await redis.get(`idem:${idemKey}`);
if (cached) return JSON.parse(cached);
const result = await stripe.charges.create(req);
await redis.setex(`idem:${idemKey}`, 86400, JSON.stringify(result));
return result;
}
```
### Pattern 5: Latency Budget
```typescript
// 매 user-facing 200ms 의 budget
// API gateway: 20ms
// auth check: 10ms (cached)
// service call: 50ms (timeout 100ms)
// DB query: 30ms (timeout 80ms)
// serialization: 10ms
// buffer: 80ms
// 매 each hop 의 explicit budget — over 시 fail fast.
```
### Pattern 6: Chaos Testing (Toxiproxy)
```bash
# 매 latency injection
toxiproxy-cli toxic add api -t latency -a latency=500 -a jitter=100
# 매 packet loss
toxiproxy-cli toxic add db -t timeout -a timeout=2000
```
### Pattern 7: Health check with deep probe
```typescript
app.get("/health/deep", async (_, res) => {
const checks = await Promise.allSettled([
db.raw("SELECT 1").then(() => ({ db: "ok" })),
redis.ping().then(() => ({ redis: "ok" })),
fetch(upstream + "/health", { signal: AbortSignal.timeout(500) }),
]);
const failed = checks.filter(c => c.status === "rejected");
res.status(failed.length ? 503 : 200).json({ checks });
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| LAN microservice call | timeout 1-2s, retry 2x |
| Cross-region call | timeout 5-10s, circuit breaker |
| 3rd-party API | bulkhead + circuit breaker + idempotency |
| Streaming / WebSocket | heartbeat + auto-reconnect |
| Critical write | idempotency key 의 mandatory |
**기본값**: 매 every remote call 의 timeout + retry + circuit breaker 의 wrap.
## 🔗 Graph
- 부모: [[Distributed Systems]] · [[Software Architecture]]
- 변형: [[CAP Theorem]] · [[PACELC]]
- 응용: [[Microservices Architecture]] · [[Service Mesh]]
- Adjacent: [[Resilience Patterns]] · [[Chaos Engineering]]
## 🤖 LLM 활용
**언제**: 매 distributed system design review, 매 incident postmortem, 매 SLO 산정.
**언제 X**: 매 single-process monolith, 매 batch job 의 isolated.
## ❌ 안티패턴
- **Infinite retry**: 매 retry storm — 매 backoff + max attempts 의 mandatory.
- **Timeout 의 unset**: 매 default infinite — 매 thread pool exhaustion.
- **Synchronous fan-out**: 매 N services 의 sequential await — 매 N×latency.
- **Trust LAN security**: 매 zero-trust / mTLS 의 default.
- **Ignore tail latency**: 매 p50 의 보고 의 — 매 p99 / p99.9 의 user experience.
## 🧪 검증 / 중복
- Verified (Deutsch 1994 / Gosling 1997 original list, AWS Builders' Library, Google SRE book).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 8 fallacies + resilience patterns |
@@ -0,0 +1,208 @@
---
id: wiki-2026-0508-distributed-tracing
title: Distributed Tracing
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [distributed-tracing, opentelemetry-tracing, request-tracing]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [observability, tracing, opentelemetry, jaeger]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: opentelemetry/tempo
---
# Distributed Tracing
## 매 한 줄
> **"매 trace 가 매 cross-service request 의 X-ray"**. 매 span tree 가 매 service hop, latency, error 의 reveal — 매 microservice debugging 의 essential. 2026 의 매 OpenTelemetry (OTel) 가 매 universal standard, 매 Tempo / Jaeger / Honeycomb / Datadog 가 매 backend, 매 W3C Trace Context 가 매 propagation.
## 매 핵심
### 매 building blocks
- **Trace** — 매 root request 의 unique ID (trace_id, 128-bit).
- **Span** — 매 single operation (HTTP call, DB query, function); has parent_span_id.
- **Context propagation** — `traceparent` HTTP header (W3C) carries trace_id+span_id+flags.
- **Baggage** — key/value propagated alongside (user_id, tenant).
- **Sampling** — 매 head (decide at ingress) vs tail (decide after seeing whole trace).
### 매 OTel architecture
1. **SDK** — instrumentation 의 in-app (auto + manual).
2. **Collector** — 매 receive → process (batch, sample, redact) → export.
3. **Backend** — Tempo (Grafana), Jaeger, Honeycomb, Datadog APM.
4. **UI** — Grafana, Jaeger UI, vendor.
### 매 응용
1. Latency root cause (which span 의 slow).
2. Error correlation (trace 의 `error=true` spans).
3. Service dependency map (service graph from spans).
4. Capacity planning (RED metrics derived from spans).
5. SLO debugging (trace 의 SLO budget burn 의 attribute).
## 💻 패턴
### OTel Node.js auto-instrumentation
```ts
// otel.ts (loaded with --import / NODE_OPTIONS)
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { Resource } from '@opentelemetry/resources';
const sdk = new NodeSDK({
resource: new Resource({ 'service.name': 'orders-api', 'service.version': '1.4.2' }),
traceExporter: new OTLPTraceExporter({ url: 'http://otel-collector:4318/v1/traces' }),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
```
### Manual span (TypeScript)
```ts
import { trace, SpanStatusCode } from '@opentelemetry/api';
const tracer = trace.getTracer('orders');
export async function placeOrder(input: OrderInput) {
return tracer.startActiveSpan('placeOrder', async (span) => {
span.setAttributes({ 'order.customer_id': input.customerId, 'order.line_count': input.lines.length });
try {
const order = await db.orders.insert(input);
await kafka.produce('orders.placed', order);
span.setStatus({ code: SpanStatusCode.OK });
return order;
} catch (e) {
span.recordException(e as Error);
span.setStatus({ code: SpanStatusCode.ERROR, message: (e as Error).message });
throw e;
} finally {
span.end();
}
});
}
```
### Python (FastAPI auto-instrument)
```python
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint="otel-collector:4317")))
trace.set_tracer_provider(provider)
app = FastAPI()
FastAPIInstrumentor.instrument_app(app)
HTTPXClientInstrumentor().instrument()
```
### Trace context propagation (W3C)
```text
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
^ ^ ^ ^
version trace_id (32 hex) parent_id (16) flags
tracestate: vendor1=value,vendor2=value
baggage: userId=42,tenantId=acme
```
### OTel Collector pipeline
```yaml
# otel-collector.yaml
receivers:
otlp: { protocols: { grpc: {}, http: {} } }
processors:
batch: { timeout: 1s }
tail_sampling:
decision_wait: 30s
policies:
- { name: errors, type: status_code, status_code: { status_codes: [ERROR] } }
- { name: slow, type: latency, latency: { threshold_ms: 1000 } }
- { name: rest, type: probabilistic, probabilistic: { sampling_percentage: 5 } }
exporters:
otlphttp/tempo: { endpoint: http://tempo:4318 }
loki: { endpoint: http://loki:3100/loki/api/v1/push }
service:
pipelines:
traces: { receivers: [otlp], processors: [batch, tail_sampling], exporters: [otlphttp/tempo] }
```
### Trace ↔ Log correlation
```ts
import pino from 'pino';
import { trace } from '@opentelemetry/api';
const log = pino();
function logWithTrace(msg: string, extra: object = {}) {
const span = trace.getActiveSpan();
const ctx = span?.spanContext();
log.info({ ...extra, trace_id: ctx?.traceId, span_id: ctx?.spanId }, msg);
}
// 매 Loki/Tempo derived field 의 trace 의 jump from log line.
```
### Frontend → backend trace
```ts
// 매 browser OTel SDK 의 traceparent 의 inject
import { trace, context } from '@opentelemetry/api';
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
new WebTracerProvider().register();
new FetchInstrumentation({
propagateTraceHeaderCorsUrls: [/api\.example\.com/],
}).enable();
```
### eBPF-based zero-instrumentation (Beyla / Pixie)
```bash
# Grafana Beyla — 매 Go/Node/Python 의 auto-trace 의 eBPF 의 capture, 매 code change X.
beyla --config beyla.yaml
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Greenfield | OTel SDK + Tempo (Grafana stack) |
| Multi-cloud SaaS | Honeycomb / Datadog APM |
| Polyglot legacy | OTel Collector + auto-instrument per lang |
| Zero-code start | eBPF (Beyla, Pixie) |
| 매 cost control | Tail sampling on errors+slow, 5% baseline |
| Strong cardinality | Honeycomb (designed for high-cardinality) |
**기본값**: OTel SDK + W3C Trace Context + Collector with tail sampling + Tempo or vendor backend.
## 🔗 Graph
- 부모: [[Observability]] · [[Microservices]]
- 변형: [[Tempo]]
- 응용: [[Service-Mesh]]
- Adjacent: [[OpenTelemetry]] · [[Logs]]
## 🤖 LLM 활용
**언제**: 매 trace tree 의 root-cause hypothesis, 매 sampling policy review, 매 OTel Collector config debug, 매 span attribute schema design.
**언제 X**: 매 production sampling decision 의 binding (cost + signal tradeoff 가 deep). 매 PII redaction 의 sole reviewer (security review 필요).
## ❌ 안티패턴
- **No sampling**: 매 cost / storage explode — tail sample on errors+slow.
- **High-cardinality on every span**: 매 user_id on every span 가 indexable backend 가 X 면 expensive.
- **Frontend trace 의 X**: 매 server-side latency 만 가 보임 — 매 user-perceived 의 miss.
- **Logs without trace_id**: 매 trace ↔ log jump 가 X.
- **Manual span without `end()`**: 매 leak.
- **Sync span across async boundary**: 매 context lost — `startActiveSpan` 사용.
- **Vendor lock-in via SDK**: 매 OTel SDK + vendor exporter 의 use, vendor SDK 의 X.
## 🧪 검증 / 중복
- Verified (OpenTelemetry spec, W3C Trace Context, Grafana Tempo docs, Honeycomb engineering blog).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — distributed tracing with OpenTelemetry, sampling, propagation |
@@ -0,0 +1,196 @@
---
id: wiki-2026-0508-event-mediator
title: Event Mediator
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Mediator Pattern, Event Bus]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, design-pattern, event-driven, decoupling]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: nodejs
---
# Event Mediator
## 매 한 줄
> **"매 N×N component coupling 의 N×1 mediator hub 의 collapse"**. Event Mediator 매 multiple components 의 direct coupling 의 elimination — 매 components 매 mediator 를 publish/subscribe, 매 mediator 매 routing/orchestration 의 own. GoF Mediator pattern 의 event-driven evolution.
## 매 핵심
### 매 Mediator vs Observer
- **Observer**: 매 1 subject → N observers, 매 unidirectional broadcast.
- **Mediator**: 매 N senders ↔ N receivers, 매 hub 의 bidirectional routing.
- **Event Bus**: 매 Mediator 의 generic implementation — 매 string-keyed event types.
### 매 동기 vs 비동기
- **Sync mediator**: 매 in-process method dispatch — 매 EventEmitter, MediatR.
- **Async mediator**: 매 message queue 의 backed — 매 RabbitMQ, Kafka, Redis Streams.
- **Hybrid**: 매 in-process sync + cross-service async (e.g., NestJS CQRS).
### 매 응용
1. UI components decoupling — chat rooms, form fields.
2. Microservices orchestration — saga coordinator.
3. CQRS command/query bus — MediatR.
4. Game event systems — unit death, achievement triggers.
## 💻 패턴
### Typed Event Bus (TypeScript)
```typescript
type EventMap = {
'user.signup': { userId: string; email: string };
'order.placed': { orderId: string; total: number };
'cache.invalidate': { key: string };
};
class EventMediator<M> {
private handlers = new Map<keyof M, Set<(p: any) => void | Promise<void>>>();
on<K extends keyof M>(event: K, handler: (payload: M[K]) => void | Promise<void>) {
if (!this.handlers.has(event)) this.handlers.set(event, new Set());
this.handlers.get(event)!.add(handler);
return () => this.handlers.get(event)!.delete(handler);
}
async emit<K extends keyof M>(event: K, payload: M[K]) {
const hs = this.handlers.get(event);
if (!hs) return;
await Promise.all([...hs].map(h => h(payload)));
}
}
const bus = new EventMediator<EventMap>();
bus.on('user.signup', async ({ userId, email }) => {
await sendWelcomeEmail(email);
});
```
### Mediator with Request/Response (MediatR-style)
```typescript
interface IRequest<TResponse> { __response?: TResponse }
interface IHandler<TReq extends IRequest<TRes>, TRes> {
handle(req: TReq): Promise<TRes>;
}
class Mediator {
private handlers = new Map<Function, IHandler<any, any>>();
register<T extends IRequest<R>, R>(reqCtor: new (...a: any[]) => T, h: IHandler<T, R>) {
this.handlers.set(reqCtor, h);
}
async send<R>(req: IRequest<R>): Promise<R> {
const h = this.handlers.get(req.constructor);
if (!h) throw new Error(`No handler for ${req.constructor.name}`);
return h.handle(req);
}
}
class GetUserQuery implements IRequest<User> { constructor(public id: string) {} }
class GetUserHandler implements IHandler<GetUserQuery, User> {
async handle(q: GetUserQuery) { return db.users.findById(q.id); }
}
```
### Saga Mediator (orchestrated)
```typescript
class OrderSaga {
constructor(private bus: EventMediator<OrderEvents>) {
bus.on('order.created', this.onCreated.bind(this));
bus.on('payment.failed', this.onPaymentFailed.bind(this));
}
async onCreated({ orderId }: { orderId: string }) {
await this.bus.emit('payment.requested', { orderId });
}
async onPaymentFailed({ orderId, reason }: any) {
await this.bus.emit('order.cancelled', { orderId, reason });
await this.bus.emit('inventory.released', { orderId });
}
}
```
### Middleware Pipeline
```typescript
type Middleware<E> = (event: E, next: () => Promise<void>) => Promise<void>;
class PipelineMediator<E> {
private middlewares: Middleware<E>[] = [];
use(m: Middleware<E>) { this.middlewares.push(m); }
async dispatch(event: E) {
let i = -1;
const run = async (idx: number): Promise<void> => {
if (idx <= i) throw new Error('next() called twice');
i = idx;
const fn = this.middlewares[idx];
if (fn) await fn(event, () => run(idx + 1));
};
await run(0);
}
}
// usage: logging, validation, retry, dead-letter
```
### Cross-Service Mediator (Kafka)
```typescript
import { Kafka } from 'kafkajs';
const kafka = new Kafka({ brokers: ['localhost:9092'] });
const producer = kafka.producer();
const consumer = kafka.consumer({ groupId: 'order-svc' });
await consumer.subscribe({ topic: 'orders', fromBeginning: false });
await consumer.run({
eachMessage: async ({ message }) => {
const evt = JSON.parse(message.value!.toString());
await handler[evt.type]?.(evt.payload);
},
});
await producer.send({
topic: 'orders',
messages: [{ key: orderId, value: JSON.stringify({ type: 'order.placed', payload }) }],
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 2-3 components 의 direct call | 매 mediator skip — 매 over-engineering |
| 5+ components, fan-out broadcast | 매 in-process EventEmitter |
| CQRS / clean architecture | 매 MediatR-style request bus |
| Cross-service, durability | 매 Kafka / RabbitMQ |
| Long-running workflow | 매 saga orchestrator (Temporal, Inngest) |
**기본값**: 매 typed in-process EventEmitter (Node) 또는 MediatR (.NET) — 매 cross-service 의 Kafka.
## 🔗 Graph
- 부모: [[Design-Patterns]] · [[Event-Driven-Architecture]]
- 변형: [[Observer-Pattern]] · [[Pub-Sub]]
- 응용: [[CQRS]] · [[Microservices]]
- Adjacent: [[Event-Sourcing]]
## 🤖 LLM 활용
**언제**: 매 N×N coupling 의 emerge — 매 5+ components 매 mutual callbacks. CQRS / saga implementation.
**언제 X**: 매 simple 2-component dependency — 매 direct injection 매 sufficient. Hot-path latency-critical (mediator dispatch overhead).
## ❌ 안티패턴
- **God Mediator**: 매 mediator 매 business logic 의 absorb — 매 anemic handlers, 매 mediator 의 1000+ lines. Mediator 의 routing only.
- **Event soup**: 매 untyped string events — 매 'user_signup' vs 'userSignup' typo 의 silent failure. Typed map 의 use.
- **Sync chain pretending async**: 매 emit() 매 await chain 의 200ms latency — 매 async queue 의 use.
- **Lost events**: 매 in-memory bus 매 crash 의 lose — 매 durability 매 required 의 persistent queue.
## 🧪 검증 / 중복
- Verified (GoF Design Patterns; MediatR docs; NestJS CQRS).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Event Mediator pattern 의 typed/saga/Kafka 의 5 patterns |
@@ -0,0 +1,174 @@
---
id: wiki-2026-0508-event-storming
title: Event Storming
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [EventStorming, DDD discovery workshop]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
verification_status: applied
tags: [ddd, modeling, workshop, architecture, discovery]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: methodology
framework: ddd
---
# Event Storming
## 매 한 줄
> **"매 sticky-note 의 도메인 의 explosion"**. Alberto Brandolini 의 2013 invent, 매 domain experts + devs 의 한 방 (혹은 Miro/FigJam) 에 모여 매 orange sticky note (domain event) 의 timeline 의 plot. 매 2026 의 매 distributed workshop tool (Miro AI, FigJam AI) 의 매 LLM-assisted aggregation 의 standard.
## 매 핵심
### 매 sticky note color convention
- 🟧 **Orange** — Domain Event (past tense — "OrderPlaced", "PaymentReceived").
- 🟦 **Blue** — Command (intent — "PlaceOrder", "RefundPayment").
- 🟨 **Yellow** — Actor / Persona.
- 🟪 **Purple** — Policy / Reactive logic ("when X then Y").
- 🟩 **Green** — Read Model / View.
- 🟥 **Red / Pink** — Hotspot / Issue (매 unclear / disagreement).
-**White** — Aggregate (매 consistency boundary).
- 🟫 **Brown** — External system.
### 매 3 levels
1. **Big Picture** — 매 entire business — 매 chaos exploration, 매 hours.
2. **Process Level** — 매 한 process flow — 매 commands / policies / read models.
3. **Design Level** — 매 aggregate / bounded context — 매 implementation 의 input.
### 매 step-by-step (Big Picture)
1. **Chaotic exploration** — 매 모두 orange events 의 plaster.
2. **Timeline** — 매 left → right 의 sort.
3. **Pivotal events** — 매 phase boundary 의 mark.
4. **Hotspot identification** — 매 red sticky 의 disagreement.
5. **Bounded context** — 매 swimlane 의 split.
### 매 응용
1. Greenfield DDD design — 매 aggregate / bounded context discovery.
2. Legacy understanding — 매 domain knowledge 의 surface.
3. Microservice decomposition — 매 service boundary 의 inform.
## 💻 패턴
### Pattern 1: Miro-export → JSON event log
```typescript
interface DomainEvent {
id: string;
name: string; // PascalCase past tense
timestamp: number; // 매 column index
aggregate?: string;
triggeredBy?: string; // command id
hotspots: string[];
}
const events: DomainEvent[] = [
{ id: "e1", name: "OrderPlaced", timestamp: 1, aggregate: "Order",
triggeredBy: "c1", hotspots: [] },
{ id: "e2", name: "PaymentReceived", timestamp: 2, aggregate: "Payment",
triggeredBy: "c2", hotspots: ["partial-payment-policy"] },
];
```
### Pattern 2: Event → TypeScript event type
```typescript
// 매 sticky 의 code 의 transition
export type OrderEvent =
| { type: "OrderPlaced"; orderId: string; items: Item[]; placedAt: Date }
| { type: "OrderPaid"; orderId: string; paymentId: string }
| { type: "OrderShipped"; orderId: string; trackingNo: string }
| { type: "OrderCancelled"; orderId: string; reason: string };
```
### Pattern 3: Policy as code
```typescript
// Purple sticky: "When OrderPaid then schedule shipment"
function onOrderPaid(e: Extract<OrderEvent, {type:"OrderPaid"}>) {
shipmentService.schedule({ orderId: e.orderId });
}
eventBus.on("OrderPaid", onOrderPaid);
```
### Pattern 4: Aggregate boundary check
```typescript
// 매 white sticky 의 invariant
class OrderAggregate {
private events: OrderEvent[] = [];
place(items: Item[]) {
if (items.length === 0) throw new Error("empty order");
this.events.push({ type: "OrderPlaced", orderId: this.id, items, placedAt: new Date() });
}
// 매 모든 mutation 의 매 event 의 emit.
}
```
### Pattern 5: Bounded context map (Mermaid)
```mermaid
flowchart LR
subgraph Sales
Order
Cart
end
subgraph Billing
Payment
Invoice
end
subgraph Logistics
Shipment
end
Order -- "OrderPlaced" --> Payment
Payment -- "OrderPaid" --> Shipment
```
### Pattern 6: AI-assisted event extraction (2026)
```typescript
// 매 transcript / Miro export → event suggestions
const prompt = `From this user interview, extract domain events (PascalCase past tense),
commands, and hotspots. Output JSON matching: { events:[], commands:[], hotspots:[] }.
Interview: ${transcript}`;
const result = await claude.messages.create({
model: "claude-opus-4-7",
max_tokens: 4000,
messages: [{ role: "user", content: prompt }],
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Greenfield complex domain | Big Picture → Process → Design |
| Legacy reverse engineering | Big Picture only |
| Microservice split | Process Level + bounded context |
| Small CRUD app | Skip — overkill |
| Distributed team | Miro / FigJam + AI summarizer |
**기본값**: 매 complex domain 시 Big Picture (4 hours), 매 implementation 직전 Design Level.
## 🔗 Graph
- 응용: [[Bounded Context]] · [[CQRS]]
- Adjacent: [[Event Sourcing]] · [[User Story Mapping]] · [[C4 Model]]
## 🤖 LLM 활용
**언제**: 매 domain discovery, 매 microservice boundary 의 find, 매 onboarding 의 understanding.
**언제 X**: 매 trivial CRUD, 매 well-known domain (e.g., todo app).
## ❌ 안티패턴
- **Tech-first sticky**: 매 "INSERT INTO orders" — 매 domain event 의 X.
- **Present tense**: 매 "PlaceOrder" 의 event 의 X — 매 command.
- **No business expert**: 매 dev-only — 매 EventStorming purpose 의 lost.
- **Skip hotspot**: 매 red sticky 의 ignore — 매 가장 valuable disagreement.
- **Premature aggregate**: 매 Big Picture 에서 white sticky 의 too early.
## 🧪 검증 / 중복
- Verified (Brandolini "Introducing EventStorming" book 2021, DDD Europe talks).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — sticky color + 3 levels + AI-assisted |
@@ -0,0 +1,187 @@
---
id: wiki-2026-0508-eventual-consistency
title: Eventual Consistency
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Eventual Consistency, BASE, AP System]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [distributed-systems, database, consistency, cap]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: sql
framework: cassandra
---
# Eventual Consistency
## 매 한 줄
> **"매 update 후 충분한 시간이 지나면 매 모든 replica 가 같은 값에 수렴한다"**. 매 Eventual Consistency는 CAP theorem 의 AP 선택 — strong consistency 의 latency/availability cost 대신 매 staleness 허용. DynamoDB, Cassandra, Riak 의 default model. 2026 globally-distributed system 의 매 default trade-off.
## 매 핵심
### 매 CAP & PACELC
- **CAP**: partition 시 Consistency vs Availability 택 1
- **PACELC** (Abadi): partition 없을 때도 Latency vs Consistency
- 매 Eventual = AP + EL (Else Latency)
- 매 strong consistency 는 quorum write/read latency cost
### 매 BASE vs ACID
- **B**asically **A**vailable: 매 partial failure 시 partial response
- **S**oft state: 매 state 는 변할 수 있음 (replica sync)
- **E**ventual consistency: 매 시간이 지나면 수렴
- 매 ACID와 trade-off — choose per use case
### 매 응용
1. DNS (TTL-based eventual).
2. CDN cache invalidation.
3. Social media feed (read-your-writes는 보장).
4. Shopping cart (Amazon Dynamo paper).
## 💻 패턴
### Cassandra tunable consistency
```python
from cassandra.cluster import Cluster
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement
cluster = Cluster(['node1', 'node2', 'node3'])
session = cluster.connect('myapp')
# 매 write: ONE = fast, eventual; QUORUM = stronger
write = SimpleStatement(
"INSERT INTO users (id, name) VALUES (%s, %s)",
consistency_level=ConsistencyLevel.QUORUM
)
session.execute(write, (user_id, name))
# 매 R + W > N → strong consistency
# 매 R=1, W=1, N=3 → eventual
```
### CRDT (G-Counter, conflict-free)
```python
class GCounter:
def __init__(self, node_id: str):
self.node_id = node_id
self.counts = {node_id: 0}
def increment(self):
self.counts[self.node_id] += 1
def value(self) -> int:
return sum(self.counts.values())
def merge(self, other: 'GCounter'):
# 매 idempotent + commutative + associative
for nid, count in other.counts.items():
self.counts[nid] = max(self.counts.get(nid, 0), count)
```
### Vector Clock (causal ordering)
```python
class VectorClock:
def __init__(self, node_id):
self.node_id = node_id
self.clock = {}
def tick(self):
self.clock[self.node_id] = self.clock.get(self.node_id, 0) + 1
def update(self, other_clock):
for nid, ts in other_clock.items():
self.clock[nid] = max(self.clock.get(nid, 0), ts)
self.tick()
def happens_before(self, other) -> bool:
return all(self.clock.get(k, 0) <= other.clock.get(k, 0)
for k in self.clock) and self.clock != other.clock
```
### Read-your-writes (sticky session)
```nginx
upstream backend {
ip_hash; # 매 same client → same backend → reads see own writes
server backend1;
server backend2;
server backend3;
}
```
### Last-Write-Wins (DynamoDB style)
```python
def lww_merge(local: dict, remote: dict) -> dict:
if remote['updated_at'] > local['updated_at']:
return remote
elif remote['updated_at'] < local['updated_at']:
return local
else:
# 매 tie-break by node_id
return remote if remote['node_id'] > local['node_id'] else local
```
### Hinted Handoff (Cassandra)
```yaml
# cassandra.yaml
hinted_handoff_enabled: true
max_hint_window_in_ms: 10800000 # 매 3 hours
# 매 down node 회복 시 hint replay → eventual consistency 보장
```
### Anti-Entropy (Merkle tree sync)
```python
def merkle_sync(local_tree, remote_tree, path=""):
if local_tree.hash == remote_tree.hash:
return # 매 subtree identical, skip
if local_tree.is_leaf:
sync_data(path)
return
for i, (l, r) in enumerate(zip(local_tree.children, remote_tree.children)):
merkle_sync(l, r, path + f"/{i}")
```
## 매 결정 기준
| 상황 | Consistency |
|---|---|
| Bank transfer | Strong (linearizable) |
| Social feed | Eventual |
| Shopping cart | Eventual + LWW |
| Counter (likes, views) | Eventual + CRDT |
| Configuration / leader election | Strong (Raft, etcd) |
| User profile | Read-your-writes |
**기본값**: 매 eventual + CRDT (counter, set, register). 매 money / lock / unique-id 는 strong.
## 🔗 Graph
- 부모: [[Distributed Systems]] · [[CAP Theorem]]
- 변형: [[Strong Consistency]] · [[Read-Your-Writes]]
- 응용: [[Cassandra]] · [[CRDT]]
- Adjacent: [[Vector Clock]] · [[Quorum]]
## 🤖 LLM 활용
**언제**: 매 system design interview, distributed DB 선택, conflict resolution strategy.
**언제 X**: 매 financial transaction, inventory deduction — strong consistency 필요.
## ❌ 안티패턴
- **모든 곳에 eventual**: 매 money/lock 도 eventual → 매 double-spend, race.
- **Conflict ignore**: 매 LWW만 쓰고 user-visible conflict 무시 → 매 silent data loss.
- **No bounded staleness**: 매 sync 영원히 안 됨 → "eventual" 의미 무.
- **Vector clock 무한 성장**: 매 GC/pruning 없음 → 매 metadata explosion.
## 🧪 검증 / 중복
- Verified (DeCandia et al., "Dynamo: Amazon's Highly Available Key-value Store", 2007).
- Verified (Brewer, CAP Theorem, PODC 2000).
- Verified (Vogels, "Eventually Consistent", CACM 2009).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — CAP/BASE + CRDT + Dynamo patterns |
@@ -0,0 +1,157 @@
---
id: wiki-2026-0508-excess-property-checking
title: Excess Property Checking
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [TypeScript Excess Property, Strict Object Literal]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-system, structural-typing]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: none
---
# Excess Property Checking
## 매 한 줄
> **"매 fresh object literal 의 only 의 strict property check"**. TypeScript 매 structural typing 매 normally 의 extra properties 의 allow, 매 but 의 fresh object literal 의 directly 의 typed slot 의 assign 시 매 extra properties 의 error 의 raise. Typo 방지 + intent clarity 의 design choice.
## 매 핵심
### 매 Why exists
- 매 structural typing 매 `{a:1, b:2}``{a:number}` 의 assignable.
- 매 그러나 매 literal 매 typo 의 high risk — `{ colour: 'red' }``{ color?: string }` 매 silent ignore.
- 매 TS 매 fresh literal 의 special-case — 매 `Object literal may only specify known properties` 의 error.
### 매 Fresh-ness 매 lost
- 매 variable 의 assign 시 매 widened — `const x = { extra: 1 }; fn(x)` 매 ok.
- 매 spread 매 fresh-ness 의 keep (TS 4.0+).
- 매 type assertion `as T` 매 bypass.
- 매 index signature `[k: string]: ...` 매 disable.
### 매 응용
1. React props typo detection.
2. Config object validation.
3. API request body shape enforcement.
4. Discriminated union narrowing aid.
## 💻 패턴
### Basic excess error
```typescript
interface Point { x: number; y: number }
const p: Point = { x: 1, y: 2, z: 3 };
// ^^^^ Object literal may only specify known properties
```
### Bypass via intermediate variable
```typescript
const tmp = { x: 1, y: 2, z: 3 };
const p: Point = tmp; // OK — fresh-ness lost
// Use this only when extra properties are intentional
```
### Index signature 의 opt-out
```typescript
interface Config {
name: string;
[key: string]: unknown; // 매 extra props 의 allow
}
const c: Config = { name: 'x', debug: true, port: 3000 }; // OK
```
### React props 의 typo guard
```typescript
type ButtonProps = { label: string; onClick: () => void };
function Button(props: ButtonProps) { /* ... */ }
<Button label="Save" onCick={save} />
// ^^^^^ Property 'onCick' does not exist
// Excess property check catches typo at JSX call site
```
### Discriminated union with strict checks
```typescript
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; side: number };
const s: Shape = { kind: 'circle', radius: 5, side: 3 };
// ^^^^ excess
// 매 kind 의 narrow 의 'circle', 매 side 의 not allowed
```
### Spread 의 preserve fresh-ness (TS 4.0+)
```typescript
type T = { a: number };
const base = { a: 1 };
const x: T = { ...base, b: 2 }; // 매 error — b 의 excess
```
### Optional excess via Exact type emulation
```typescript
type Exact<T, U extends T> = T & {
[K in Exclude<keyof U, keyof T>]: never;
};
function strict<T>() {
return <U extends T>(x: Exact<T, U>): T => x as T;
}
const point = strict<Point>()({ x: 1, y: 2, z: 3 });
// ^^^^ Type 'number' is not assignable to 'never'
// 매 variable assign path 의 also 의 strict
```
### Util: 매 satisfies operator (TS 4.9+)
```typescript
const config = {
endpoint: 'https://api.example.com',
timeout: 5000,
retries: 3,
} satisfies { endpoint: string; timeout: number };
// ^^^^ 매 retries 의 excess error
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Config / DTO literal | 매 default check 의 leverage |
| Plugin system 의 unknown extras | 매 index signature 의 add |
| Test fixture 의 extra debug fields | 매 intermediate var 또는 `as` |
| 매 strict 의 want 의 variable path | 매 `Exact` helper 또는 `satisfies` |
| Library author 의 strict API | 매 `satisfies` 또는 nominal brand |
**기본값**: 매 default behavior 의 leverage — 매 typo 매 catch. 매 escape 매 minimize, 매 `satisfies` 의 prefer.
## 🔗 Graph
- 부모: [[TypeScript]] · [[TypeScript 타입 시스템 (TypeScript Type System)|Type-System]]
- 변형: [[Structural Typing|Structural-Typing]] · [[Satisfies-Operator]]
- Adjacent: [[API 응답 및 상태 모델링 (State Modeling and API Responses)|Discriminated-Unions]]
## 🤖 LLM 활용
**언제**: 매 typo-prone literal — config, props, API body. Schema-bound inputs.
**언제 X**: 매 plugin / metadata 의 extra props 매 intentional — 매 index signature 의 add.
## ❌ 안티패턴
- **`as T` 의 bypass habit**: 매 error 의 mask, 매 typo 의 ship — 매 fix 의 root cause.
- **Index signature 의 over-permissive**: 매 모든 class 매 `[k: string]: any` 의 add — 매 type safety 의 destroy.
- **Intermediate var 의 escape**: 매 `const x = {...}; fn(x)` 매 intent 의 obscure — 매 명시적 cast 의 prefer.
- **`satisfies` 의 ignore**: 매 TS 4.9+ 매 widening 없는 strict literal 의 best tool — 매 underused.
## 🧪 검증 / 중복
- Verified (TS handbook "Object Types"; TS 4.9 release notes).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — excess property check + satisfies/Exact patterns |
@@ -0,0 +1,201 @@
---
id: wiki-2026-0508-exploration-vs-exploitation
title: Exploration vs Exploitation
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Explore-Exploit, Multi-Armed Bandit Tradeoff, RL Tradeoff]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [reinforcement-learning, bandits, decision-theory, optimization]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: numpy
---
# Exploration vs Exploitation
## 매 한 줄
> **"매 known-best 의 exploit 의 unknown 의 explore 의 fundamental tradeoff"**. Exploration-exploitation dilemma 매 RL · bandits · A/B testing 의 core — 매 current best action 의 only 의 take 시 매 better unknown 의 miss, 매 too much explore 시 매 reward 의 burn. Optimal balance 매 horizon, prior, regret budget 의 function.
## 매 핵심
### 매 Spectrum
- **Pure exploit (greedy)**: 매 always 매 argmax Q(a) — 매 local optimum trap.
- **Pure explore (random)**: 매 always uniform — 매 expected regret O(T).
- **ε-greedy**: 매 prob ε 매 explore, 매 prob 1−ε 매 exploit.
- **UCB**: 매 confidence-bounded 매 deterministic explore.
- **Thompson Sampling**: 매 posterior sampling 매 Bayesian optimal.
### 매 Regret bounds
- 매 ε-greedy(static): O(T).
- 매 ε-greedy(decaying 1/t): O(log T).
- 매 UCB1: O(log T) — provably tight for stochastic bandit.
- 매 Thompson Sampling: matches Lai-Robbins lower bound.
### 매 응용
1. A/B/n testing — adaptive traffic allocation.
2. Recommender systems — cold start.
3. Hyperparameter tuning (Optuna, Vizier).
4. RL games — Atari, AlphaGo MCTS.
5. LLM 매 sampling temperature, top-p.
6. Drug trials — bandit-style adaptive design.
## 💻 패턴
### ε-greedy bandit
```python
import numpy as np
class EpsilonGreedy:
def __init__(self, k, eps=0.1):
self.k = k
self.eps = eps
self.Q = np.zeros(k)
self.N = np.zeros(k)
def select(self):
if np.random.rand() < self.eps:
return np.random.randint(self.k)
return int(np.argmax(self.Q))
def update(self, a, r):
self.N[a] += 1
self.Q[a] += (r - self.Q[a]) / self.N[a]
```
### UCB1
```python
class UCB1:
def __init__(self, k):
self.k, self.t = k, 0
self.Q = np.zeros(k)
self.N = np.zeros(k)
def select(self):
self.t += 1
for a in range(self.k):
if self.N[a] == 0:
return a # cold-start each arm once
ucb = self.Q + np.sqrt(2 * np.log(self.t) / self.N)
return int(np.argmax(ucb))
def update(self, a, r):
self.N[a] += 1
self.Q[a] += (r - self.Q[a]) / self.N[a]
```
### Thompson Sampling (Bernoulli)
```python
class ThompsonBernoulli:
def __init__(self, k):
self.alpha = np.ones(k) # successes + 1
self.beta = np.ones(k) # failures + 1
def select(self):
samples = np.random.beta(self.alpha, self.beta)
return int(np.argmax(samples))
def update(self, a, r):
if r > 0: self.alpha[a] += 1
else: self.beta[a] += 1
```
### Decaying ε schedule
```python
def epsilon(t, start=1.0, end=0.05, decay=10000):
return end + (start - end) * np.exp(-t / decay)
# DQN-style: 매 early episodes 의 explore-heavy, 매 late 의 exploit
```
### Boltzmann (softmax) exploration
```python
def softmax_select(Q, tau=1.0):
p = np.exp(Q / tau)
p /= p.sum()
return np.random.choice(len(Q), p=p)
# tau→0 매 greedy, tau→∞ 매 uniform
```
### Contextual bandit (LinUCB)
```python
class LinUCB:
def __init__(self, k, d, alpha=1.0):
self.A = [np.eye(d) for _ in range(k)]
self.b = [np.zeros(d) for _ in range(k)]
self.alpha = alpha
def select(self, x): # context vector
ucb = []
for a in range(len(self.A)):
Ainv = np.linalg.inv(self.A[a])
theta = Ainv @ self.b[a]
mean = theta @ x
bonus = self.alpha * np.sqrt(x @ Ainv @ x)
ucb.append(mean + bonus)
return int(np.argmax(ucb))
def update(self, a, x, r):
self.A[a] += np.outer(x, x)
self.b[a] += r * x
```
### LLM sampling 의 explore-exploit
```python
# temperature=0 → exploit (deterministic argmax)
# temperature=1 → explore (full distribution)
# top-p=0.9 → constrained explore (nucleus)
def sample_token(logits, temperature=0.7, top_p=0.9):
logits = logits / temperature
probs = softmax(logits)
sorted_idx = np.argsort(probs)[::-1]
cum = np.cumsum(probs[sorted_idx])
cutoff = np.searchsorted(cum, top_p) + 1
keep = sorted_idx[:cutoff]
p = probs[keep] / probs[keep].sum()
return np.random.choice(keep, p=p)
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Stationary stochastic bandit | 매 UCB1 또는 Thompson |
| Bernoulli reward | 매 Thompson Beta-binomial |
| Contextual features 의 available | 매 LinUCB / NeuralBandit |
| Non-stationary (drift) | 매 sliding-window UCB / discounted TS |
| Deep RL | 매 ε-greedy decay 또는 noisy nets |
| LLM creative generation | 매 temperature 0.7-1.0 + top-p 0.9 |
**기본값**: 매 Thompson Sampling — 매 strong empirical 의 winner, 매 simple implementation.
## 🔗 Graph
- 부모: [[Reinforcement-Learning]] · [[Decision-Theory]]
- 변형: [[Multi-Armed-Bandit]]
- 응용: [[Recommender-Systems]] · [[Hyperparameters|Hyperparameter-Tuning]] · [[MCTS]]
- Adjacent: [[Bayesian-Optimization]] · [[Active-Learning]] · [[LLM-Sampling]]
## 🤖 LLM 활용
**언제**: 매 sequential decision 매 reward feedback. Cold-start recommender. A/B 의 multi-arm 의 generalize.
**언제 X**: 매 known reward distribution + horizon→∞ — 매 closed-form optimal. Single-shot decision.
## 어려운 점 (안티패턴)
- **Static ε too high**: 매 ε=0.5 forever — 매 final 50% traffic 의 random arm 의 burn. Decay 의 use.
- **No cold-start arms**: 매 UCB 의 N[a]=0 의 not-handled — 매 inf 의 produce, 매 each arm 의 1 초기 pull 의 require.
- **Non-stationarity ignored**: 매 reward drift 의 discount 없이 의 stale Q value 의 trust.
- **Reward leakage**: 매 future info 매 leak — 매 fake "exploit" 매 actually 의 cheat.
## 🧪 검증 / 중복
- Verified (Sutton & Barto Ch. 2; Lai-Robbins 1985; Russo et al. "Tutorial on Thompson Sampling" 2018).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — explore-exploit + 7 algorithm patterns |
@@ -0,0 +1,210 @@
---
id: wiki-2026-0508-fault-tolerance
title: Fault Tolerance
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Fault Tolerance, 장애 내성, Resilience Engineering]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, distributed-systems, resilience, erlang]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: erlang
framework: otp
---
# Fault Tolerance
## 매 한 줄
> **"매 system은 fail한다 — 매 question은 'when'이지 'if' 아님"**. 매 fault tolerance는 component failure에도 system이 계속 동작하도록 design — Erlang/OTP의 "let it crash" philosophy에서 modern Kubernetes self-healing까지 evolution. 2026 cloud-native에서는 chaos engineering, circuit breaker, bulkhead가 default.
## 매 핵심
### 매 Fault vs Error vs Failure
- **Fault**: 매 root cause (bug, hardware glitch, network partition)
- **Error**: 매 fault의 manifestation (incorrect state)
- **Failure**: 매 service가 contract 위반 (user-visible)
- 매 goal: fault → error containment, error → failure prevention
### 매 Erlang Philosophy
- **Let it crash**: 매 defensive coding 대신 supervisor가 restart
- **Process isolation**: 매 lightweight process per actor, shared-nothing
- **Hot code reload**: 매 zero-downtime upgrade
- 매 WhatsApp이 2 billion users를 50 engineers로 운영한 비결
### 매 응용
1. Erlang/OTP supervisor tree (telecom, WhatsApp, Discord).
2. Kubernetes pod restart + liveness probes.
3. Circuit breaker (Hystrix, resilience4j).
4. Distributed databases (Cassandra hinted handoff, Spanner).
## 💻 패턴
### Erlang Supervisor Tree
```erlang
-module(my_sup).
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
SupFlags = #{strategy => one_for_one,
intensity => 5,
period => 10},
Children = [
#{id => worker1,
start => {worker, start_link, []},
restart => permanent,
shutdown => 5000,
type => worker}
],
{ok, {SupFlags, Children}}.
```
### Circuit Breaker (Python)
```python
from pybreaker import CircuitBreaker
db_breaker = CircuitBreaker(fail_max=5, reset_timeout=60)
@db_breaker
def query_db(sql: str):
return db.execute(sql)
try:
result = query_db("SELECT * FROM users")
except CircuitBreakerError:
return cached_response() # fallback
```
### Retry with Exponential Backoff
```python
import asyncio
import random
async def retry_with_backoff(fn, max_retries=5, base=1.0):
for attempt in range(max_retries):
try:
return await fn()
except Exception as e:
if attempt == max_retries - 1:
raise
delay = base * (2 ** attempt) + random.uniform(0, 1)
await asyncio.sleep(delay)
```
### Bulkhead Pattern (Go)
```go
import "golang.org/x/sync/semaphore"
type Service struct {
dbSem *semaphore.Weighted // 10 concurrent DB calls
apiSem *semaphore.Weighted // 50 concurrent API calls
}
func (s *Service) CallDB(ctx context.Context) error {
if err := s.dbSem.Acquire(ctx, 1); err != nil {
return err
}
defer s.dbSem.Release(1)
return doDBWork()
}
```
### Kubernetes Liveness/Readiness
```yaml
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
```
### Chaos Engineering (Litmus)
```yaml
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
spec:
experiments:
- name: pod-delete
spec:
components:
env:
- name: TOTAL_CHAOS_DURATION
value: '60'
- name: PODS_AFFECTED_PERC
value: '50'
```
### Saga Pattern (Compensation)
```python
class OrderSaga:
async def execute(self, order):
steps = []
try:
payment = await charge_card(order)
steps.append(("refund", payment.id))
inventory = await reserve_stock(order)
steps.append(("release", inventory.id))
await ship_order(order)
except Exception:
for action, ref in reversed(steps):
await compensate(action, ref)
raise
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Telecom-grade uptime (5 nines) | Erlang/OTP supervisor tree |
| Microservices REST | Circuit breaker + retry + timeout |
| Stateful distributed DB | Quorum + hinted handoff |
| Container orchestration | K8s liveness/readiness + PodDisruptionBudget |
| Cross-service transactions | Saga + compensation |
**기본값**: 매 timeout + retry + circuit breaker 3종 세트 + chaos testing.
## 🔗 Graph
- 부모: [[Distributed Systems]]
- 변형: [[Circuit Breaker]]
- 응용: [[Kubernetes]] · [[Microservices]]
- Adjacent: [[Chaos Engineering]] · [[Eventual Consistency]] · [[CAP Theorem]]
## 🤖 LLM 활용
**언제**: 매 distributed system design 시 failure mode enumeration, supervisor tree 설계, retry strategy 추천.
**언제 X**: 매 single-process script — fault tolerance overhead 가 value 보다 큼.
## ❌ 안티패턴
- **Catch-all exception swallow**: 매 error를 log만 하고 무시 → 매 silent corruption.
- **Infinite retry**: 매 backoff 없는 retry → 매 thundering herd, cascading failure.
- **Shared fate**: 매 단일 DB 의존 모든 service → 매 single point of failure.
- **No timeout**: 매 hang된 dependency가 매 caller exhaust.
## 🧪 검증 / 중복
- Verified (Joe Armstrong, "Making Reliable Distributed Systems in the Presence of Software Errors", 2003).
- Verified (Netflix Chaos Engineering principles, principlesofchaos.org).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Erlang/OTP + modern resilience patterns |
@@ -0,0 +1,198 @@
---
id: wiki-2026-0508-feature-driven-architecture
title: Feature-Driven Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [FDD, Feature Slices, Vertical Slice Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, feature-slices, modularity, frontend]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: nextjs
---
# Feature-Driven Architecture
## 매 한 줄
> **"매 layer-by-type 의 feature-by-vertical-slice 의 invert"**. Feature-Driven Architecture 매 codebase 의 organization unit 매 feature/use-case — 매 each feature 매 own UI + state + API + tests 의 own. Frontend 매 FSD (Feature-Sliced Design), Backend 매 vertical slice / modular monolith 의 manifest.
## 매 핵심
### 매 Why
- **Layer-by-type problem**: 매 `controllers/`, `services/`, `models/` 매 small project 의 fine, 매 100+ features 시 매 cross-cutting changes 의 5 directories 의 touch.
- **Feature 의 lifecycle**: 매 feature 의 add/remove/own 의 single folder 의 happen.
- **Team scaling**: 매 vertical squad 의 own 매 single feature folder, 매 conflicts 의 minimize.
### 매 FSD layers (frontend)
1. `app/` — global setup, routing, providers.
2. `pages/` — route compositions.
3. `widgets/` — composite UI blocks.
4. `features/` — user actions (login, addToCart).
5. `entities/` — business objects (User, Product).
6. `shared/` — UI kit, utils, API client.
- 매 import rule: 매 upper layer → lower layer only.
### 매 응용
1. Next.js / Remix apps with FSD.
2. Modular monolith — Java/.NET vertical slices.
3. Mobile (RN/Flutter) feature modules.
4. Microfrontend per-feature deployment.
## 💻 패턴
### FSD folder layout
```
src/
├── app/ # providers, router, global styles
├── pages/
│ └── checkout/
│ └── ui/Checkout.tsx
├── widgets/
│ └── header/ui/Header.tsx
├── features/
│ ├── auth-login/
│ │ ├── ui/LoginForm.tsx
│ │ ├── model/store.ts
│ │ ├── api/login.ts
│ │ └── index.ts # public api
│ └── cart-add-item/
├── entities/
│ ├── user/{ui, model, api}/
│ └── product/{ui, model, api}/
└── shared/
├── ui/Button.tsx
└── api/baseQuery.ts
```
### Public API (index.ts barrel)
```typescript
// features/auth-login/index.ts
export { LoginForm } from './ui/LoginForm';
export { useLoginMutation } from './api/login';
// 매 internal model/store 의 not exported — encapsulation
```
### ESLint 의 enforce layer rules
```javascript
// .eslintrc — eslint-plugin-boundaries
module.exports = {
plugins: ['boundaries'],
settings: {
'boundaries/elements': [
{ type: 'app', pattern: 'src/app/*' },
{ type: 'pages', pattern: 'src/pages/*' },
{ type: 'features', pattern: 'src/features/*' },
{ type: 'entities', pattern: 'src/entities/*' },
{ type: 'shared', pattern: 'src/shared/*' },
],
},
rules: {
'boundaries/element-types': ['error', {
default: 'disallow',
rules: [
{ from: 'pages', allow: ['features', 'entities', 'shared'] },
{ from: 'features', allow: ['entities', 'shared'] },
{ from: 'entities', allow: ['shared'] },
],
}],
},
};
```
### Vertical slice (.NET / Node)
```typescript
// features/place-order/handler.ts
export class PlaceOrderCommand {
constructor(public userId: string, public items: Item[]) {}
}
export async function placeOrder(cmd: PlaceOrderCommand, deps: Deps) {
const user = await deps.users.findById(cmd.userId);
if (!user) throw new NotFoundError();
const order = Order.create(user, cmd.items);
await deps.orders.save(order);
await deps.bus.emit('order.placed', { orderId: order.id });
return { orderId: order.id };
}
// features/place-order/route.ts
router.post('/orders', async (req, res) => {
const result = await placeOrder(req.body, deps);
res.json(result);
});
// 매 single folder 매 use-case 의 entire handle
```
### Cross-feature communication via events
```typescript
// features/cart-checkout — 매 features/inventory-update 의 NOT 매 import
// 매 instead: emit event, 매 inventory feature 의 subscribe
import { bus } from '@/shared/event-bus';
async function checkout(cart: Cart) {
await bus.emit('checkout.completed', { items: cart.items });
}
// features/inventory-update/index.ts
bus.on('checkout.completed', async ({ items }) => {
await decrementStock(items);
});
```
### Feature flag boundary
```typescript
// features/new-search-v2/index.ts
import { useFlag } from '@/shared/feature-flags';
import { SearchV1 } from '@/features/search-v1';
import { SearchV2 } from './ui/SearchV2';
export function Search() {
const v2 = useFlag('search-v2');
return v2 ? <SearchV2 /> : <SearchV1 />;
}
// Removal 의 single folder delete
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Solo / < 10 features | 매 layer-by-type 매 fine |
| Frontend, growing team | 매 FSD |
| Backend, modular monolith | 매 vertical slice (CQRS-style) |
| Microservices | 매 service-per-feature 매 already |
| Strict isolation 의 needed | 매 ESLint boundaries + barrel exports |
**기본값**: 매 frontend 매 FSD, 매 backend 매 vertical slice — 매 cross-feature 의 events.
## 🔗 Graph
- 부모: [[Software-Architecture]] · [[Modular-Monolith]]
- 변형: [[Feature-Sliced-Design]] · [[Vertical-Slice-Architecture]] · [[Hexagonal-Architecture]]
- 응용: [[Microfrontends]] · [[CQRS]] · [[Bounded-Context]]
- Adjacent: [[Domain-Driven-Design]] · [[Clean-Architecture]]
## 🤖 LLM 활용
**언제**: 매 10+ features, 매 multi-team. Frontend 매 page-driven 의 outgrow. Modular monolith 매 service split 의 prepare.
**언제 X**: 매 small app (<10 screens). 매 prototype phase — 매 over-structure cost > benefit.
## ❌ 안티패턴
- **Cross-feature direct import**: 매 `features/cart``features/checkout/internal` 의 import — 매 coupling 의 reintroduce. Public API 만 의 use.
- **God shared/**: 매 모든 utility 의 `shared/utils/` 의 dump — 매 entities/features 의 leak 의 should.
- **Premature feature split**: 매 single-screen app 의 7 features 의 carve — 매 navigation cost.
- **Layer skipping**: 매 `entities``features` 의 import — 매 dependency rule violation.
## 🧪 검증 / 중복
- Verified (feature-sliced.design official; Jimmy Bogard "Vertical Slice Architecture").
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — FSD layout + ESLint boundaries + vertical slice patterns |
@@ -0,0 +1,166 @@
---
id: wiki-2026-0508-fiber-architecture
title: Fiber Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [React Fiber, Reconciler]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [react, frontend, reconciliation]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: react
---
# Fiber Architecture
## 매 한 줄
> **"매 reconciliation 을 interruptible 한 unit 으로 쪼갠다"**. 매 React 16 (2017) 에서 stack reconciler 를 대체 — 매 work loop 가 매 fiber node 단위로 yield 가능하므로 매 concurrent rendering, Suspense, transitions 의 토대. 2026 React 19 의 Server Components, Actions, `use` hook 모두 매 fiber tree 위에서 동작.
## 매 핵심
### 매 fiber node
- 매 React element 1:1 의 mutable bookkeeping object.
-`child / sibling / return` pointer 로 tree linkage (매 array 가 아닌 linked list).
- `pendingProps`, `memoizedProps`, `memoizedState`, `effectTag`, `lanes`.
- 매 두 tree: **current** (committed) + **workInProgress** (next render) — 매 double buffering.
### 매 work loop
1. **Render phase** (interruptible) — 매 beginWork → completeWork DFS, 매 frame budget 만료 시 yield.
2. **Commit phase** (synchronous) — 매 DOM mutation, ref attach, layout effect.
3. **Lanes** — 매 priority bitmask (Sync, Default, Transition, Idle).
### 매 응용
1. `useTransition` / `useDeferredValue` — 매 low-priority lane.
2. Suspense boundary — 매 throw promise → fallback render.
3. Server Components (RSC) — 매 server fiber 의 serialize.
4. Concurrent rendering / time slicing.
## 💻 패턴
### Fiber node 의 shape (개념)
```ts
type Fiber = {
type: any; key: string | null;
child: Fiber | null; sibling: Fiber | null; return: Fiber | null;
alternate: Fiber | null; // current ↔ workInProgress
pendingProps: any; memoizedProps: any; memoizedState: any;
flags: number; // Placement | Update | Deletion
lanes: number; childLanes: number;
stateNode: any; // DOM node | class instance
};
```
### Work loop (개념)
```ts
function workLoopConcurrent() {
while (workInProgress !== null && !shouldYield()) {
workInProgress = performUnitOfWork(workInProgress);
}
}
function performUnitOfWork(fiber: Fiber): Fiber | null {
const next = beginWork(fiber.alternate, fiber, renderLanes);
if (next === null) return completeUnitOfWork(fiber);
return next;
}
```
### useTransition (React 19)
```tsx
import { useTransition, useState } from "react";
export function Search() {
const [query, setQuery] = useState("");
const [results, setResults] = useState<string[]>([]);
const [isPending, startTransition] = useTransition();
return (
<>
<input value={query} onChange={e => {
setQuery(e.target.value); // sync lane
startTransition(() => setResults(filter(e.target.value))); // transition lane
}}/>
{isPending ? <Spinner/> : <List items={results}/>}
</>
);
}
```
### Suspense + use (React 19)
```tsx
import { Suspense, use } from "react";
function Profile({ promise }: { promise: Promise<User> }) {
const user = use(promise); // 매 throw 시 Suspense fallback
return <h1>{user.name}</h1>;
}
export default () => (
<Suspense fallback={<Skeleton/>}>
<Profile promise={fetchUser()}/>
</Suspense>
);
```
### Server Component (RSC)
```tsx
// app/page.tsx — 매 server fiber, payload 로 serialize
export default async function Page() {
const posts = await db.posts.findMany();
return <PostList posts={posts}/>; // 매 client 로는 RSC payload 전송
}
```
### useDeferredValue
```tsx
const deferred = useDeferredValue(query); // 매 stale value 로 render, urgent update 우선
```
### Lane priority debug (React DevTools)
```
Profiler tab → Highlight transitions → 매 어느 lane 에서 commit 됐는지 확인
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 즉시 반영 input | 직접 setState (sync lane) |
| 무거운 list filter | startTransition (transition lane) |
| Async data 의 render | Suspense + use |
| Server-only data fetch | RSC (`async function Page`) |
| Stale UI 허용 + responsive | useDeferredValue |
**기본값**: React 19 + RSC (Next.js App Router), client side 는 transition + Suspense.
## 🔗 Graph
- 부모: [[React]] · [[Reconciliation]]
- 변형: [[React Server Components]] · [[Concurrent Features|Concurrent Rendering]]
- 응용: [[Suspense]] · [[useTransition]] · [[useDeferredValue]] · [[Streaming SSR]]
- Adjacent: [[Virtual_DOM과_Reconciliation|Virtual DOM]] · [[Hydration]]
## 🤖 LLM 활용
**언제**: 매 jank 진단, transition vs sync 결정, Suspense boundary 위치 reasoning.
**언제 X**: 매 non-React framework — 매 Vue / Svelte / Solid 는 매 다른 reconciler.
## ❌ 안티패턴
- **Sync setState in event for heavy work**: 매 main thread block.
- **Suspense without boundary**: 매 root crash — 매 ErrorBoundary + Suspense pair.
- **useTransition for urgent input**: 매 typing latency 발생.
- **Mutating fiber internals**: 매 React 의 internal — 매 forward-compat 보장 X.
- **Effect 의 setState loop**: 매 무한 render — 매 dependency 정확히.
## 🧪 검증 / 중복
- Verified (React 19 release notes, Andrew Clark *fiber* RFC, React docs 2026, Vercel RSC docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — fiber + lanes + React 19 (RSC, use, transition) 정리 |
@@ -0,0 +1,229 @@
---
id: wiki-2026-0508-fragment-bound
title: Fragment-bound
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [React Fragment, Fragment-bound Component, Multi-root Component]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [react, frontend, jsx, dom]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: react
---
# Fragment-bound
## 매 한 줄
> **"매 component 의 root 의 wrapper div 의 elimination"**. React Fragment (`<>...</>` 또는 `<Fragment>`) 매 component 매 multiple sibling roots 의 return 의 enable — 매 unnecessary `<div>` wrapper 의 avoid. "Fragment-bound" component 매 single DOM root 의 not-have, 매 layout (Grid, Table, Flex) 매 fragile 의 implication 의 carry.
## 매 핵심
### 매 Why Fragment
- **DOM cleanliness**: 매 wrapper div 의 CSS Grid/Flex 의 break — 매 child 매 grid item 의 directly 의 must be.
- **No semantic noise**: 매 `<table>``<tr>``<td>` 의 nest 의 wrapper div 의 invalid HTML.
- **Performance (marginal)**: 매 fewer DOM nodes — 매 hot lists 의 measurable.
### 매 Forms
- `<></>` — short syntax, 매 no key/props.
- `<Fragment key={...}>` — 매 list iteration 매 key 의 needed 시.
- `<React.Fragment>` — explicit import, 매 build tooling 의 short syntax 의 not-support 시.
### 매 Fragment-bound implications
- 매 ref 의 attach 의 not-possible (매 single DOM node 의 not-have).
- 매 parent 매 child layout 의 control 의 must — 매 child 매 own root 의 not-have.
- 매 portals 매 separate concern.
### 매 응용
1. Table rows / cells (`<TableRow>` returning `<td>...</td><td>...</td>`).
2. Grid items in CSS Grid layout.
3. Component library — wrapper-less primitives.
4. Conditional sibling rendering.
## 💻 패턴
### Basic Fragment
```tsx
function Greeting() {
return (
<>
<h1>Hello</h1>
<p>World</p>
</>
);
}
// 매 DOM 의 <h1>+<p> 의 sibling, 매 no wrapper
```
### Fragment with key (list)
```tsx
import { Fragment } from 'react';
function Glossary({ items }: { items: { term: string; def: string }[] }) {
return (
<dl>
{items.map(it => (
<Fragment key={it.term}>
<dt>{it.term}</dt>
<dd>{it.def}</dd>
</Fragment>
))}
</dl>
);
}
// 매 short syntax 매 key prop 의 not-accept — 매 explicit Fragment 의 use
```
### Table row composition
```tsx
function ProductRow({ product }: { product: Product }) {
return (
<>
<td>{product.name}</td>
<td>{product.price}</td>
<td>{product.stock}</td>
</>
);
}
function ProductTable({ products }: { products: Product[] }) {
return (
<table>
<tbody>
{products.map(p => (
<tr key={p.id}><ProductRow product={p} /></tr>
))}
</tbody>
</table>
);
}
// 매 wrapper div 매 tr 안 의 invalid HTML — 매 Fragment 의 only correct
```
### CSS Grid items
```tsx
function GridGroup() {
return (
<>
<div className="grid-item">A</div>
<div className="grid-item">B</div>
<div className="grid-item">C</div>
</>
);
}
function Layout() {
return (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)' }}>
<GridGroup /> {/* 매 3 children 의 grid items 의 directly */}
</div>
);
}
// 매 wrapper div 의 add 시 매 single grid cell 의 collapse
```
### Conditional sibling rendering
```tsx
function Notification({ user }: { user?: User }) {
if (!user) return null;
return (
<>
{user.unreadCount > 0 && (
<span className="badge">{user.unreadCount}</span>
)}
<span className="name">{user.name}</span>
</>
);
}
```
### Ref forwarding 매 NOT possible
```tsx
// 매 X — Fragment 매 ref 의 not-attach 의
const Bad = forwardRef<HTMLDivElement>((props, ref) => (
<>
<h1 ref={ref}>Title</h1> {/* 매 child element 의 ref 의 forward 의 must */}
<p>Body</p>
</>
));
// 매 O — 매 explicit child 의 ref 의 forward
const Card = forwardRef<HTMLHeadingElement, { title: string; body: string }>(
({ title, body }, ref) => (
<>
<h1 ref={ref}>{title}</h1>
<p>{body}</p>
</>
),
);
```
### Suspense / ErrorBoundary 매 Fragment children
```tsx
function App() {
return (
<Suspense fallback={<Spinner />}>
<>
<Header />
<Main />
<Footer />
</>
</Suspense>
);
}
// 매 Suspense 매 single child 의 not-require — 매 Fragment 의 N children 의 all 의 wait
```
### Slot pattern 의 fragment-aware
```tsx
type SlotProps = { children: ReactNode };
function Slot({ children }: SlotProps) {
// 매 children 매 Fragment 매 single 매 multiple 매 unwrap 의 logic
if (isValidElement(children) && children.type === Fragment) {
return <>{children.props.children}</>;
}
return <>{children}</>;
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Component 매 단일 root 의 natural | 매 `<div>` 의 use |
| Wrapper div 매 layout 의 break | 매 Fragment |
| Table / dl / select children | 매 Fragment 의 mandatory |
| List item with multiple roots | 매 Fragment with key |
| Ref / styling 의 root needed | 매 div / specific element 의 use |
**기본값**: 매 wrapper 매 semantic value 의 carry 의 div, 매 그렇지 않으면 매 Fragment.
## 🔗 Graph
- 부모: [[React]] · [[JSX]]
- 변형: [[Slot-Pattern]]
- 응용: [[CSS-Grid]] · [[Component-Composition]]
## 🤖 LLM 활용
**언제**: 매 multi-root component. Table/Grid layout 의 wrapper 의 break 의 시. List item 매 multiple sibling 의 render.
**언제 X**: 매 single root + ref/styling needed — 매 div 의 use. Wrapper 의 styling target 의 expected 시.
## ❌ 안티패턴
- **Wrapper div habit**: 매 모든 component 매 `<div>` 의 wrap — 매 div soup, 매 layout 의 fragile.
- **Fragment without key in list**: 매 `<>``.map` 안 의 use — 매 React warning + reconciliation 의 broken.
- **Trying to ref a Fragment**: 매 Fragment 의 DOM node 의 not-have — 매 forwardRef 의 specific child 의 forward 의 must.
- **Fragment inside single-child API**: 매 some libs (older) 매 single child 의 expect — 매 Fragment 의 expand, 매 break.
## 🧪 검증 / 중복
- Verified (React docs "Fragments"; React 16.2 release notes).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Fragment patterns + table/grid/key examples |
@@ -0,0 +1,218 @@
---
id: wiki-2026-0508-functional-programming
title: Functional Programming
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [FP, Functional Programming, 함수형 프로그래밍]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [paradigm, programming, haskell, scala, rust]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: haskell
framework: multi
---
# Functional Programming
## 매 한 줄
> **"매 function이 first-class — 매 computation은 immutable value 의 transformation"**. 매 FP는 lambda calculus(Church 1936)에서 시작, Haskell/ML/Lisp 통해 academic 으로, 매 React/Redux/Rx 의 mainstream 침투. 2026 mainstream language 모두 FP feature 흡수 (lambdas, map/filter, immutable, pattern match).
## 매 핵심
### 매 Pillars
- **Pure function**: 매 same input → same output, no side effect
- **Immutability**: 매 data 변경 대신 new value 생성
- **First-class function**: 매 function = value (pass, return, store)
- **Referential transparency**: 매 expression을 value로 substitute 가능
- **Higher-order function**: 매 function in/out
### 매 Type system 매력
- **ADT** (algebraic data types): sum (Either, Option) + product (tuple, record)
- **Pattern matching**: 매 exhaustive case analysis
- **Type inference**: 매 Hindley-Milner (ML, Haskell, Rust)
- **Typeclasses** (Haskell) / Traits (Rust) / Type classes (Scala)
### 매 응용
1. React functional components + hooks (modern frontend).
2. Rust iterators + Option/Result (systems FP).
3. Scala/Akka (distributed reactive).
4. Haskell (compilers, finance, formal verification).
5. F# (.NET FP, fintech).
## 💻 패턴
### Haskell — pure + ADT
```haskell
data Tree a = Leaf | Node (Tree a) a (Tree a)
insert :: Ord a => a -> Tree a -> Tree a
insert x Leaf = Node Leaf x Leaf
insert x t@(Node l v r)
| x < v = Node (insert x l) v r
| x > v = Node l v (insert x r)
| otherwise = t
-- 매 IO monad: side effect 격리
main :: IO ()
main = do
putStrLn "Enter name:"
name <- getLine
putStrLn $ "Hello, " ++ name
```
### Rust — iterators + Option
```rust
fn process(nums: Vec<i32>) -> Vec<i32> {
nums.iter()
.filter(|&&x| x > 0)
.map(|&x| x * x)
.take(10)
.collect()
}
// 매 Option chaining (no null)
fn find_user(id: u64) -> Option<String> {
db.get(id)
.and_then(|u| u.email)
.map(|e| e.to_lowercase())
}
```
### Scala — case class + pattern match
```scala
sealed trait Shape
case class Circle(r: Double) extends Shape
case class Rect(w: Double, h: Double) extends Shape
def area(s: Shape): Double = s match {
case Circle(r) => math.Pi * r * r
case Rect(w, h) => w * h
}
// 매 immutable List + fold
val sum = List(1, 2, 3, 4).foldLeft(0)(_ + _)
```
### TypeScript — immutable + HOF
```typescript
// 매 readonly + pipe
const pipe = <T>(...fns: Array<(x: T) => T>) =>
(x: T): T => fns.reduce((v, f) => f(v), x);
const addOne = (n: number) => n + 1;
const double = (n: number) => n * 2;
const pipeline = pipe<number>(addOne, double);
console.log(pipeline(3)); // 8
// 매 Result type (avoid throw)
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
```
### Haskell — Functor / Monad
```haskell
-- 매 Maybe monad: null-safe chain
safeDivide :: Double -> Double -> Maybe Double
safeDivide _ 0 = Nothing
safeDivide x y = Just (x / y)
calc :: Maybe Double
calc = do
a <- safeDivide 10 2
b <- safeDivide a 0 -- 매 short-circuit Nothing
return (b + 1)
-- 매 result: Nothing
```
### Elm — pure UI
```elm
type Msg = Increment | Decrement
type alias Model = { count : Int }
update : Msg -> Model -> Model
update msg model =
case msg of
Increment -> { model | count = model.count + 1 }
Decrement -> { model | count = model.count - 1 }
view : Model -> Html Msg
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, text (String.fromInt model.count)
, button [ onClick Increment ] [ text "+" ]
]
```
### Python — functools (FP-lite)
```python
from functools import reduce, partial, lru_cache
# 매 immutable transform
@lru_cache(maxsize=None)
def fib(n: int) -> int:
return n if n < 2 else fib(n-1) + fib(n-2)
# 매 currying via partial
multiply = lambda x, y: x * y
double = partial(multiply, 2)
print(list(map(double, [1, 2, 3]))) # [2, 4, 6]
# 매 reduce
product = reduce(lambda a, b: a * b, [1, 2, 3, 4], 1)
```
### Persistent data structures (Clojure)
```clojure
(def v [1 2 3])
(def v2 (conj v 4)) ; 매 v unchanged, structural sharing
(println v) ; [1 2 3]
(println v2) ; [1 2 3 4]
;; 매 transducer (composable transformation)
(def xform (comp (filter odd?) (map #(* % %))))
(transduce xform + [1 2 3 4 5]) ; 1 + 9 + 25 = 35
```
## 매 결정 기준
| 상황 | FP fit |
|---|---|
| Concurrent / parallel | High — immutability eliminates race |
| Compilers / parsers | High — ADT + pattern match natural fit |
| UI state management | High — Redux/Elm pure update |
| Game loop (perf-critical) | Low — manual memory + mutation 필요 |
| OS kernel / driver | Low — direct hardware control 필요 |
| Domain modeling | High — ADT 가 매 invariants 표현 |
**기본값**: 매 mainstream language 에서 매 pure function preference + immutable default + side effect 격리.
## 🔗 Graph
- 응용: [[프론트엔드_및_UIUX_표준|Redux]] · [[CQRS]]
- Adjacent: [[Immutability]] · [[Type Theory]] · [[Algebraic Data Types]]
## 🤖 LLM 활용
**언제**: 매 refactor toward purity, type signature 설계, monad/applicative usage 설명.
**언제 X**: 매 hot loop micro-opt — mutation + cache locality 가 더 빠름.
## ❌ 안티패턴
- **Premature abstraction**: 매 Functor/Monad 도입했는데 매 use case 1개 → 매 cognitive overhead.
- **Pure obsession**: 매 logging/IO 도 monad transformer stack — 매 maintenance 지옥.
- **Recursion without TCO**: 매 stack overflow (Python — TCO 없음).
- **Over-currying**: 매 모든 function 1-arg curried → 매 readability 저하.
## 🧪 검증 / 중복
- Verified (Hutton, "Programming in Haskell", 2nd ed., 2016).
- Verified (Okasaki, "Purely Functional Data Structures", 1998).
- Verified (Wadler, "Theorems for free!", 1989).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — pure FP + modern Haskell/Scala/Rust patterns |
@@ -0,0 +1,159 @@
---
id: wiki-2026-0508-gates
title: Gates
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Quality Gates, CI Gates, Release Gates]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, ci-cd, quality, governance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: yaml
framework: github-actions
---
# Gates
## 매 한 줄
> **"매 quality gate 의 build/release 의 progress 의 block 의 conditional checkpoint 의 정의"**. 매 SonarQube popularization 의 origin (~2008), 매 modern CI/CD 의 essential part — 매 PR merge / deploy 의 prerequisite 의 automated assertion 의 set.
## 매 핵심
### 매 Gate 종류
- **Build Gate**: compile + unit test pass.
- **Quality Gate**: coverage ≥ 80%, no critical SonarQube issues.
- **Security Gate**: SAST (Semgrep, CodeQL), SCA (Dependabot, Snyk), secret scan.
- **Performance Gate**: bundle size, Lighthouse, p99 latency budget.
- **Manual Approval Gate**: prod deploy 의 human reviewer.
### 매 Gate 위치
- **PR Gate**: pre-merge — fast (<5 min).
- **Main Branch Gate**: post-merge — heavier (E2E, integration).
- **Release Gate**: pre-deploy — canary metrics, smoke tests.
- **Production Gate**: post-deploy — error rate watcher, auto-rollback.
### 매 응용
1. SonarQube Quality Gate (coverage / duplication / issues).
2. GitHub branch protection rules.
3. ArgoCD sync waves with health gates.
## 💻 패턴
### GitHub Actions Quality Gate
```yaml
name: PR Gate
on: pull_request
jobs:
gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm test -- --coverage
- name: Coverage gate
run: |
COV=$(jq '.total.lines.pct' coverage/coverage-summary.json)
if (( $(echo "$COV < 80" | bc -l) )); then
echo "Coverage $COV% < 80%"; exit 1
fi
- uses: github/codeql-action/analyze@v3
```
### SonarQube Quality Gate
```yaml
- uses: SonarSource/sonarqube-scan-action@v3
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- uses: SonarSource/sonarqube-quality-gate-action@v1
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
```
### Bundle Size Gate
```yaml
- uses: andresz1/size-limit-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
skip_step: install
```
### Manual Approval Gate (GitHub Environments)
```yaml
deploy-prod:
environment:
name: production
url: https://app.example.com
runs-on: ubuntu-latest
needs: [test, security]
steps:
- run: ./deploy.sh prod
```
Configured in repo Settings → Environments → required reviewers.
### ArgoCD Sync Wave Gate
```yaml
metadata:
annotations:
argocd.argoproj.io/sync-wave: "1"
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
```
### Canary Gate (Argo Rollouts)
```yaml
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- analysis:
templates: [{ templateName: success-rate }]
- setWeight: 50
- pause: { duration: 10m }
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Fast PR feedback | unit + lint + type only (<3 min) |
| Compliance-heavy | SAST + SCA + license + signed commits |
| High-traffic prod | canary + auto-rollback gate |
| Monorepo | path-filtered gates (only run affected) |
**기본값**: PR gate (lint+test+typecheck) → main gate (E2E+coverage) → prod gate (manual approval+canary).
## 🔗 Graph
- 부모: [[CI-CD]] · [[DevOps]]
- 변형: [[Quality-Gate]]
- 응용: [[GitHub-Actions]] · [[ArgoCD]] · [[SonarQube]]
- Adjacent: [[Trunk-Based-Development]] · [[Feature-Flags]]
## 🤖 LLM 활용
**언제**: gate 의 thresholds 의 review, gate config 의 generation, failure log 의 root cause 의 analysis.
**언제 X**: gate policy 의 organizational decision (compliance, risk tolerance) — human ownership 필요.
## ❌ 안티패턴
- **Gate inflation**: 매 PR 의 30+ checks → developer frustration, gaming via skip flags.
- **Flaky gates**: intermittent failures 의 normalize → real failures 의 ignore.
- **Bypass culture**: admin 의 "merge anyway" 의 routine usage.
- **No rollback gate**: deploy 후 metrics 의 watch 없이 → bad release 의 prolong.
- **Unmeasured threshold**: "good enough" coverage % 의 arbitrary 의 set.
## 🧪 검증 / 중복
- Verified (Google SRE Book, GitHub branch protection docs, SonarQube Quality Gates).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — quality gates / CI gates 의 full content |
@@ -0,0 +1,185 @@
---
id: wiki-2026-0508-god-object-antipattern
title: God Object Antipattern
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [God Class, Blob, Monster Class]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, antipattern, oop, refactoring, code-smell]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: language-agnostic
---
# God Object Antipattern
## 매 한 줄
> **"매 single class/module 의 too many responsibilities 의 absorption 의 통한 maintainability 의 collapse"**. 매 Brown et al. "AntiPatterns" (1998) 의 catalog, 매 procedural code 의 OOP 로 의 lift-and-shift 의 결과 — 매 modern microservices 시대 의 "God Service" 로 의 mutation.
## 매 핵심
### 매 Symptoms
- 1000+ LOC class, 50+ methods.
- 매 unrelated domain 의 mix (User + Order + Payment + Logging).
- 매 import 의 fan-in 의 high — 매 module 의 reference 의 most.
- Test 의 setup 의 100+ lines mock.
- Git log 의 churn 의 highest hot-spot.
### 매 Causes
- SRP (Single Responsibility) 의 violation.
- Premature centralization ("Manager", "Controller", "Helper" suffix).
- Feature 의 incremental 의 add 의 always-cheapest-place 의 dump.
- Refactoring fear (test 의 X, dependency 의 web).
### 매 응용 (detection)
1. SonarQube "Brain Class" rule.
2. Lizard / radon 의 cyclomatic + LOC metric.
3. CodeScene hotspot map.
## 💻 패턴
### Smell — God Class
```typescript
// 🚨 God Object
export class ApplicationManager {
users: User[] = [];
orders: Order[] = [];
cart: Cart;
paymentGateway: Stripe;
logger: Logger;
cache: Redis;
// ... 47 more fields
registerUser(...) { /* 80 lines */ }
authenticateUser(...) { /* 60 lines */ }
createOrder(...) { /* 120 lines, calls payment, cache, log */ }
refundOrder(...) { /* 90 lines */ }
sendEmail(...) { /* 40 lines */ }
generateReport(...) { /* 200 lines */ }
// ... 50 more methods
}
```
### Refactor — Extract Class (SRP)
```typescript
export class UserService {
constructor(private repo: UserRepository, private hasher: PasswordHasher) {}
async register(input: RegisterInput) { /* ... */ }
async authenticate(creds: Credentials) { /* ... */ }
}
export class OrderService {
constructor(
private repo: OrderRepository,
private payment: PaymentGateway,
private events: EventBus,
) {}
async create(input: CreateOrderInput) { /* ... */ }
async refund(orderId: string) { /* ... */ }
}
export class ReportingService { /* ... */ }
```
### Replace Conditional with Polymorphism
```typescript
// Before: god method 의 switch
processPayment(method: string, amount: number) {
if (method === 'card') { /* ... */ }
else if (method === 'paypal') { /* ... */ }
else if (method === 'crypto') { /* ... */ }
}
// After: Strategy
interface PaymentMethod { charge(amount: number): Promise<Receipt>; }
class CardPayment implements PaymentMethod { /* ... */ }
class PayPalPayment implements PaymentMethod { /* ... */ }
class CryptoPayment implements PaymentMethod { /* ... */ }
class PaymentService {
constructor(private methods: Map<string, PaymentMethod>) {}
charge(method: string, amount: number) {
return this.methods.get(method)!.charge(amount);
}
}
```
### Extract Aggregate (DDD)
```typescript
// God 의 split → Aggregate Root + Value Objects
export class Order {
private constructor(
public readonly id: OrderId,
private items: LineItem[],
private status: OrderStatus,
) {}
static create(customerId: CustomerId, items: LineItem[]): Order { /* ... */ }
addItem(item: LineItem) { /* invariant 의 enforce */ }
confirm(): DomainEvent[] { /* ... */ }
}
```
### ESLint Rule (max-lines-per-function/class)
```json
{
"rules": {
"max-lines": ["error", { "max": 400, "skipBlankLines": true }],
"max-lines-per-function": ["error", 60],
"complexity": ["error", 10]
}
}
```
### SonarQube Detection
```properties
sonar.cpd.exclusions=**/*.test.ts
# Rule: java:S2972 (Inner classes should not have too many lines)
# Rule: typescript:S138 (Functions should not have too many lines)
# Rule: common:DuplicatedBlocks
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Class > 500 LOC | Extract Class by responsibility |
| Method > 60 LOC | Extract Method, Replace Temp with Query |
| Long parameter list | Introduce Parameter Object |
| Switch on type | Replace Conditional with Polymorphism |
| Cross-domain mix | Extract Bounded Context (DDD) |
**기본값**: 매 SRP — 매 class 의 one reason to change.
## 🔗 Graph
- 부모: [[Code-Smells]]
- 변형: [[Big-Ball-of-Mud]] · [[Distributed-Monolith]]
- 응용: [[Refactoring_Best_Practices|Refactoring]] · [[SOLID]] · [[DDD]]
- Adjacent: [[High-Cohesion-Low-Coupling]] · [[Single Responsibility Principle (SRP)|Single-Responsibility-Principle]] · [[Bounded-Context]]
## 🤖 LLM 활용
**언제**: god class 의 detect, extract-class 의 refactor 의 suggest, responsibility 의 cluster 의 propose.
**언제 X**: 매 large refactor 의 final commit (test coverage 의 human verification 필수).
## ❌ 안티패턴
- **Manager/Helper suffix**: 매 dumping ground 의 invitation.
- **Static God**: `Utils` static class 의 grow → 매 testability 의 destroy.
- **God Service**: microservice 시대 의 god — single service 의 매 domain 의 own.
- **Refactor without tests**: 매 god 의 split 의 시 behavior 의 break 의 silent.
- **Premature split**: 매 50 LOC class 의 over-decompose → 매 anemic + indirection 의 hell.
## 🧪 검증 / 중복
- Verified (Brown et al. "AntiPatterns" 1998, Fowler "Refactoring" 2nd ed., SonarSource rules).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — god object antipattern 의 full content |
@@ -0,0 +1,173 @@
---
id: wiki-2026-0508-high-cohesion-low-coupling
title: High Cohesion Low Coupling
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Cohesion and Coupling, Loose Coupling High Cohesion]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [architecture, design-principles, modularity, oop, refactoring]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: language-agnostic
---
# High Cohesion Low Coupling
## 매 한 줄
> **"매 module 내부 의 element 의 strong relatedness (cohesion) + module 간 의 minimal dependency (coupling) 의 maximize"**. 매 Larry Constantine 의 1968 structured design 의 origin, 매 modern 의 SOLID, DDD bounded context, microservices 의 universal foundation — 매 changeability 의 single 의 most important predictor.
## 매 핵심
### 매 Cohesion 7 levels (Constantine, low → high)
1. Coincidental (random grouping).
2. Logical (similar category, e.g., "Utils").
3. Temporal (executed at same time).
4. Procedural (sequence of steps).
5. Communicational (act on same data).
6. Sequential (output of one → input of next).
7. **Functional** (single, well-defined task) — 매 target.
### 매 Coupling 6 levels (low → high)
1. **Data** (parameters of primitives) — 매 ideal.
2. Stamp (parameters of composite).
3. Control (flag-driven branching).
4. External (shared protocol).
5. Common (shared global).
6. Content (one module 의 internals 의 mutate) — 매 worst.
### 매 응용
1. Module boundary 의 design.
2. Microservice 의 split criteria (DDD bounded context).
3. Refactoring 의 direction-finder.
## 💻 패턴
### Smell — Low Cohesion
```typescript
// 🚨 Logical cohesion only
export class Utils {
formatDate(d: Date) { /* ... */ }
parseCSV(s: string) { /* ... */ }
hashPassword(p: string) { /* ... */ }
sendEmail(to: string) { /* ... */ }
}
```
### Refactor — Functional Cohesion
```typescript
// formatting/date.ts
export const formatISO = (d: Date) => d.toISOString().slice(0, 10);
// parsing/csv.ts
export const parseCSV = (s: string) => /* ... */;
// auth/password.ts
export const hashPassword = (p: string) => bcrypt.hash(p, 12);
// email/send.ts
export const sendEmail = (to: string, body: string) => transporter.send(/* ... */);
```
### Smell — High Coupling (Content)
```typescript
class OrderService {
constructor(private inventory: InventoryService) {}
reserve(id: string) {
// 🚨 Reaches into private state
this.inventory['stock'].set(id, 0);
}
}
```
### Refactor — Data Coupling via Interface
```typescript
interface InventoryPort {
reserve(sku: string, qty: number): Promise<ReservationId>;
}
class OrderService {
constructor(private inventory: InventoryPort) {}
async reserve(sku: string, qty: number) {
return this.inventory.reserve(sku, qty);
}
}
```
### Dependency Inversion (Hexagonal)
```typescript
// domain/order.ts (no infra import)
export interface OrderRepository {
save(o: Order): Promise<void>;
byId(id: string): Promise<Order | null>;
}
// infra/postgres-order-repo.ts
export class PostgresOrderRepository implements OrderRepository { /* ... */ }
// app/wire.ts
const repo: OrderRepository = new PostgresOrderRepository(pool);
const svc = new OrderService(repo);
```
### Event-Driven Decoupling
```typescript
// publisher
events.emit('OrderPlaced', { orderId, customerId, total });
// subscribers (independent modules)
events.on('OrderPlaced', sendConfirmationEmail);
events.on('OrderPlaced', updateAnalytics);
events.on('OrderPlaced', allocateInventory);
```
### Coupling Metric — Fan-in / Fan-out
```bash
# madge 의 dep graph
npx madge --circular --extensions ts src/
npx madge --summary --extensions ts src/ # fan-in/fan-out per module
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Module > 500 LOC, scattered concerns | Split by responsibility (cohesion↑) |
| Module imports 20+ siblings | Introduce interface / facade |
| Cross-module mutation | Event / message passing |
| Shared mutable global | Replace with pure function or DI |
| Microservice split | DDD bounded context boundary |
**기본값**: 매 functional cohesion + data coupling 의 target — 매 interface 의 통한 dependency 의 invert.
## 🔗 Graph
- 부모: [[Software-Architecture]] · [[Modularity]]
- 변형: [[Single Responsibility Principle (SRP)|Single-Responsibility-Principle]] · [[Bounded-Context]] · [[Hexagonal-Architecture]]
- 응용: [[SOLID]] · [[Microservices]] · [[Clean-Architecture]]
- Adjacent: [[God-Object-Antipattern]] · [[Dependency-Inversion]]
## 🤖 LLM 활용
**언제**: module 의 cohesion/coupling 의 review, refactor 의 direction 의 suggest, dep graph 의 hot-spot 의 highlight.
**언제 X**: 매 architectural boundary 의 final decision (domain expert + business context 필요).
## ❌ 안티패턴
- **God Module**: low cohesion + high fan-in (모두 의 import).
- **Anemic Module**: data 만, behavior 의 다른 module 의 own → procedural disguised as OOP.
- **Tight ORM coupling**: domain entity 의 ORM annotation 의 saturation → infra 의 leak.
- **Premature abstraction**: 매 single use-case 의 interface 의 introduce → 매 indirection 의 cost.
- **Shared library 의 god lib**: 매 service 의 shared "common" 의 god — 매 deploy lockstep.
## 🧪 검증 / 중복
- Verified (Constantine "Structured Design" 1979, Martin "Clean Architecture", Evans "DDD").
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — cohesion/coupling principles 의 full content |
@@ -0,0 +1,158 @@
---
id: wiki-2026-0508-hydration
title: Hydration
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Client Hydration, SSR Hydration]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [web, ssr, react, frontend]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: react
---
# Hydration
## 매 한 줄
> **"매 server 가 render 한 static HTML 에 client JS 가 event handler / state 를 부여하는 과정"**. 매 SSR 의 SEO + first paint 이점 + SPA 의 interactivity 의 결합. 2026 시점 매 trend 는 매 less hydration — Astro Islands, React Server Components, Qwik resumability 가 매 full-page hydration 을 대체.
## 매 핵심
### 매 단계
1. **Server**: render to HTML string (`renderToString` / `renderToPipeableStream`).
2. **Client**: HTML parsing → first paint (TTFB / FCP).
3. **Hydration**: JS download → React/framework 가 component tree 의 event listener attach + state restore.
4. **Interactive**: TTI 도달.
### 매 cost
- 매 download + parse + execute JS — 매 모바일 mid-tier 에서 무거움.
- Hydration mismatch — 매 server vs client output 차이 시 warning + re-render.
- 매 unused interactivity 도 매 hydrate (Wasted hydration).
### 매 modern alternatives
- **Selective / progressive hydration** (React 18+): Suspense 단위로 lazy hydrate.
- **Islands architecture** (Astro, Fresh): 매 interactive island 만 ship + hydrate.
- **Resumability** (Qwik): hydration 자체 제거 — 매 server 에서 serialize 한 closure 를 매 event 시점에 lazy resume.
- **React Server Components**: 매 server-only component 는 ship X — 매 client component 만 hydrate.
### 매 응용
1. Next.js / Remix App Router (RSC + selective hydration).
2. Astro (islands).
3. Qwik / QwikCity (resumability).
4. SvelteKit, SolidStart (fine-grained reactivity, hydration cheaper).
## 💻 패턴
### React 19 SSR + hydrateRoot
```ts
// server.ts
import { renderToPipeableStream } from "react-dom/server";
import App from "./App";
const stream = renderToPipeableStream(<App/>, {
bootstrapScripts: ["/client.js"],
onShellReady() { stream.pipe(res); },
});
// client.ts
import { hydrateRoot } from "react-dom/client";
import App from "./App";
hydrateRoot(document, <App/>);
```
### Suspense for selective hydration
```tsx
<Suspense fallback={<Skeleton/>}>
<HeavyChart/>{/* 매 이 boundary 만 lazy hydrate */}
</Suspense>
```
### Astro Islands
```astro
---
import Counter from "../components/Counter.svelte";
---
<h1>Static</h1>
<Counter client:visible /> {/* 매 viewport 진입 시 hydrate */}
```
### Qwik resumability
```tsx
import { component$, useSignal } from "@builder.io/qwik";
export default component$(() => {
const c = useSignal(0);
// 매 click 전에는 JS 미실행 — 매 lazy resume
return <button onClick$={() => c.value++}>{c.value}</button>;
});
```
### Avoiding hydration mismatch
```tsx
// 매 client-only value (Date.now, window) 는 useEffect 에서
function Now() {
const [t, setT] = useState<string | null>(null);
useEffect(() => setT(new Date().toISOString()), []);
return <span>{t ?? ""}</span>; // 매 server: empty, client: 실제값
}
```
### React Server Components (Next.js)
```tsx
// app/page.tsx — server component, 매 hydrate X
export default async function Page() {
const data = await db.posts.findMany();
return <ClientWidget data={data}/>; // 매 ClientWidget 만 hydrate
}
```
### Streaming SSR (Node)
```ts
const stream = renderToPipeableStream(<App/>, {
onShellReady() { res.setHeader("content-type", "text/html"); stream.pipe(res); },
onError(err) { console.error(err); },
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Mostly static + 적은 island | Astro / 11ty + islands |
| Full app, dynamic data | Next.js App Router (RSC) |
| Extreme TTI 우선 | Qwik (resumability) |
| Fine-grained reactivity | Svelte / Solid |
| 매 SEO 불필요 SPA | CSR (no hydration) |
**기본값**: Next.js 15 App Router (RSC + selective hydration). 매 mostly-static 사이트 는 Astro.
## 🔗 Graph
- 부모: [[SSR]] · [[Web Architecture]]
- 변형: [[Selective Hydration]] · [[Islands Architecture]] · [[Resumability]]
- 응용: [[Next.js]] · [[Astro]] · [[Qwik]] · [[Remix]]
- Adjacent: [[Fiber_Architecture|Fiber Architecture]] · [[Streaming SSR]] · [[React Server Components]] · [[Core Web Vitals Optimization (INP, LCP 개선)|Core Web Vitals]]
## 🤖 LLM 활용
**언제**: TTI / LCP / INP 진단, framework 선택, hydration mismatch 디버깅.
**언제 X**: 매 SEO + first paint 둘 다 불필요한 internal tool — 매 CSR SPA 면 충분.
## ❌ 안티패턴
- **Hydration mismatch (Date.now, Math.random)**: 매 server-client output 불일치 → re-render.
- **Hydrating entire static page**: 매 island 분리 안 함 → JS 무겁게.
- **Heavy useEffect in root**: 매 hydration 직후 main thread block.
- **Conditional render based on `typeof window`**: 매 mismatch 의 흔한 원인.
- **Hydrating below-the-fold immediately**: 매 selective + visibility 활용.
## 🧪 검증 / 중복
- Verified (React 19 docs, Next.js 15 docs, Astro docs, Qwik docs, Addy Osmani *Hydration* 2024).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — hydration + islands + RSC + resumability 정리 |
@@ -0,0 +1,183 @@
---
id: wiki-2026-0508-implementation-separation
title: Implementation Separation
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Implementation Separation, Interface-Implementation Split, Hexagonal Boundaries]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, interface, dependency-inversion, hexagonal, ports-adapters]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript/Python/Go
framework: language-agnostic
---
# Implementation Separation
## 매 한 줄
> **"매 'what' 매 'how' 의 분리"**. Implementation separation 매 interface (contract) 매 implementation (mechanism) 매 명시적 분리 — 매 dependency inversion, ports-and-adapters, hexagonal architecture 의 core idea. 매 testability, swappability, evolution 매 enable.
## 매 핵심
### 매 Why separate
- **Test**: 매 fake/mock 매 swap-in.
- **Swap**: 매 Postgres → DynamoDB 매 caller code unchanged.
- **Boundary**: 매 layer/module 매 명확.
- **Parallel work**: 매 interface freeze → 매 team 매 parallel implementation.
### 매 Levels of separation
1. **Interface keyword** (Java, C#, Go, TypeScript): 매 syntax 매 enforce.
2. **Abstract base class** (Python, C++): 매 ABC, virtual.
3. **Protocol/structural typing** (Python typing.Protocol, TypeScript): 매 duck typing 매 static check.
4. **Trait** (Rust): 매 zero-cost.
5. **Module boundary** (Haskell .hs-boot, OCaml .mli): 매 module-level.
### 매 응용
1. **Repository pattern**: 매 `UserRepo` interface, 매 `PgUserRepo` impl.
2. **Strategy pattern**: 매 algorithm 매 swap.
3. **Adapter (port)**: 매 external service 매 wrap.
4. **Test doubles**: 매 InMemory* impl.
## 💻 패턴
### TypeScript — port + adapter
```typescript
// Port (domain owns this)
export interface UserRepo {
findById(id: string): Promise<User | null>;
save(u: User): Promise<void>;
}
// Adapter (infrastructure)
export class PgUserRepo implements UserRepo {
constructor(private db: Pool) {}
async findById(id: string) {
const r = await this.db.query('select * from users where id=$1', [id]);
return r.rows[0] ? mapUser(r.rows[0]) : null;
}
async save(u: User) {
await this.db.query('insert into users ...', [u.id, u.name]);
}
}
// In-memory test double
export class InMemoryUserRepo implements UserRepo {
private map = new Map<string, User>();
async findById(id: string) { return this.map.get(id) ?? null; }
async save(u: User) { this.map.set(u.id, u); }
}
```
### Python Protocol (structural)
```python
from typing import Protocol
class Notifier(Protocol):
def send(self, to: str, msg: str) -> None: ...
class EmailNotifier:
def send(self, to: str, msg: str) -> None:
smtp.sendmail(...)
class SlackNotifier:
def send(self, to: str, msg: str) -> None:
requests.post("https://slack/api", json={"channel": to, "text": msg})
def notify_user(n: Notifier, user_id: str, msg: str) -> None:
n.send(user_id, msg) # any structural match works
```
### Go — implicit interface
```go
type Cache interface {
Get(key string) ([]byte, bool)
Set(key string, val []byte, ttl time.Duration)
}
type RedisCache struct{ client *redis.Client }
func (r *RedisCache) Get(k string) ([]byte, bool) { /* ... */ }
func (r *RedisCache) Set(k string, v []byte, ttl time.Duration) { /* ... */ }
type MemCache struct{ m sync.Map }
func (m *MemCache) Get(k string) ([]byte, bool) { /* ... */ }
func (m *MemCache) Set(k string, v []byte, ttl time.Duration) { /* ... */ }
```
### Rust trait
```rust
pub trait Storage {
fn put(&self, key: &str, val: &[u8]) -> anyhow::Result<()>;
fn get(&self, key: &str) -> anyhow::Result<Option<Vec<u8>>>;
}
pub struct S3Storage { client: aws_sdk_s3::Client }
impl Storage for S3Storage { /* ... */ }
pub struct LocalFs { root: PathBuf }
impl Storage for LocalFs { /* ... */ }
pub fn save_blob<S: Storage>(s: &S, k: &str, v: &[u8]) -> anyhow::Result<()> {
s.put(k, v)
}
```
### Hexagonal layout
```
src/
domain/ # pure logic, no I/O
user.ts
order.ts
ports/ # interfaces
user_repo.ts
payment_gateway.ts
app/ # use-cases, depend on ports only
place_order.ts
adapters/ # impl of ports
pg_user_repo.ts
stripe_gateway.ts
infra/ # composition root
main.ts
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 single impl, no test isolation needed | 매 직접 class — 매 over-engineer 금지 |
| 매 ≥2 impls or test doubles 필요 | 매 interface/protocol/trait |
| 매 cross-team boundary | 매 interface freeze 매 contract |
| 매 swappable infra (DB, queue, cache) | 매 port + adapter |
| 매 perf-critical hot loop | 매 generics/static dispatch (no vtable) |
**기본값**: 매 ports 매 domain 옆, adapters 매 infra layer, 매 composition root 매 wire.
## 🔗 Graph
- 부모: [[Hexagonal-Architecture]] · [[Dependency-Inversion-Principle]]
- 변형: [[Ports-and-Adapters]] · [[Clean-Architecture]] · [[Onion-Architecture]]
- 응용: [[Test-Doubles]]
- Adjacent: [[High-Cohesion-Low-Coupling]] · [[SOLID]]
## 🤖 LLM 활용
**언제**: 매 architecture refactor; 매 testability 부족; 매 multiple infra backend; 매 team boundary.
**언제 X**: 매 single-use script; 매 prototype; 매 only one impl forever.
## ❌ 안티패턴
- **IFoo + FooImpl 매 1:1 forever**: 매 interface 매 swap/test point 없으면 매 잡음.
- **Leaky abstraction**: 매 interface method 매 SQL string 받음 — 매 impl 의 detail 노출.
- **Anemic port**: 매 CRUD method 만 매 interface — 매 domain logic 매 caller 에 leak.
- **Adapter 매 domain 의 의존**: 매 dep 매 wrong direction.
## 🧪 검증 / 중복
- Verified (Cockburn 2005 "Hexagonal Architecture", Evans DDD, Martin "Clean Architecture", Vernon IDDD).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content (port/adapter, multi-language patterns) |
@@ -0,0 +1,167 @@
---
id: wiki-2026-0508-in-memory-data-grid
title: In-Memory Data Grid
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [IMDG, Distributed Cache, In-Memory Computing]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, distributed-systems, cache, performance, jvm]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: java
framework: hazelcast-ignite
---
# In-Memory Data Grid
## 매 한 줄
> **"매 distributed RAM 의 partitioned + replicated 의 통한 sub-ms key-value + compute 의 horizontal scale"**. 매 Oracle Coherence (2001) 의 commercial origin, 매 Hazelcast (2008) / Apache Ignite (2014) 의 OSS 의 popularization — 매 modern 의 Redis Cluster + Apache Ignite + Hazelcast 5.x 의 dominant.
## 매 핵심
### 매 IMDG vs Distributed Cache
- **Cache (Redis, Memcached)**: 매 read-through, eviction-driven, simple K/V.
- **IMDG (Hazelcast, Ignite, Coherence)**: + co-located compute, SQL, transactions, near-cache, entry processors, CP subsystem.
### 매 Core Capabilities
- **Partitioning**: consistent hash, 매 271 partitions (Hazelcast default).
- **Replication**: backup count (sync/async), 매 partition 의 N-1 backup.
- **Near Cache**: client-side mirror, invalidation 의 push.
- **Entry Processor**: 매 data-local computation (move code to data).
- **Continuous Query**: predicate-based push.
- **CP Subsystem**: Raft-based linearizable primitives (Hazelcast 4+).
### 매 응용
1. Session store / shopping cart (low-latency).
2. Real-time risk / pricing (compute grid).
3. Hybrid OLTP+stream (Ignite + Kafka).
## 💻 패턴
### Hazelcast 5 — Embedded + IMap
```java
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
IMap<String, Order> orders = hz.getMap("orders");
orders.put("o-123", new Order(...));
Order o = orders.get("o-123"); // sub-ms
// Pessimistic lock 의 partition-local
orders.executeOnKey("o-123", entry -> {
Order cur = entry.getValue();
cur.markPaid();
entry.setValue(cur);
return null;
});
```
### Apache Ignite — SQL over Cache
```java
IgniteConfiguration cfg = new IgniteConfiguration();
Ignite ignite = Ignition.start(cfg);
CacheConfiguration<Long, Person> ccfg = new CacheConfiguration<>("Person");
ccfg.setIndexedTypes(Long.class, Person.class);
IgniteCache<Long, Person> cache = ignite.getOrCreateCache(ccfg);
List<List<?>> rows = cache.query(new SqlFieldsQuery(
"SELECT name, salary FROM Person WHERE salary > ? ORDER BY salary DESC")
.setArgs(100_000)).getAll();
```
### Hazelcast Near Cache
```yaml
hazelcast-client:
near-cache:
orders:
in-memory-format: OBJECT
invalidate-on-change: true
time-to-live-seconds: 60
max-size: 10000
eviction-policy: LRU
```
### Entry Processor (move compute to data)
```java
public class IncrementVersion implements EntryProcessor<String, Order, Long> {
public Long process(Map.Entry<String, Order> e) {
Order o = e.getValue();
o.setVersion(o.getVersion() + 1);
e.setValue(o);
return o.getVersion();
}
}
Long v = orders.executeOnKey("o-1", new IncrementVersion());
```
### Continuous Query (Hazelcast)
```java
IMap<String, Order> orders = hz.getMap("orders");
orders.addEntryListener((EntryAddedListener<String, Order>) ev -> {
if (ev.getValue().getAmount() > 10_000) alert(ev.getValue());
}, Predicates.greaterThan("amount", 10_000), true);
```
### CP Subsystem — Linearizable Counter
```java
CPSubsystem cp = hz.getCPSubsystem();
IAtomicLong seq = cp.getAtomicLong("order-seq");
long next = seq.incrementAndGet(); // Raft-backed, linearizable
```
### Kubernetes Deployment (Hazelcast Operator)
```yaml
apiVersion: hazelcast.com/v1alpha1
kind: Hazelcast
metadata: { name: hz }
spec:
clusterSize: 5
repository: hazelcast/hazelcast
version: "5.5"
persistence:
baseDir: /data/hot-restart
pvc: { accessModes: [ReadWriteOnce], requestStorage: 50Gi }
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Simple K/V cache | Redis / Memcached |
| Java-heavy + SQL on cache | Apache Ignite |
| Compute + cache + CP primitives | Hazelcast 5 |
| Multi-language polyglot | Redis Cluster + redis-om |
| Persistent in-memory DB | Ignite native persistence / Aerospike |
**기본값**: 매 Java/Kotlin stack — Hazelcast 5; 매 polyglot — Redis Cluster.
## 🔗 Graph
- 부모: [[Distributed-Systems]]
- 변형: [[Distributed-Cache]] · [[NewSQL]]
- 응용: [[Apache-Ignite]]
- Adjacent: [[CAP-Theorem]] · [[Consistent-Hashing]]
## 🤖 LLM 활용
**언제**: IMDG 의 sizing 의 estimate, partition strategy 의 review, Hazelcast/Ignite config 의 generate.
**언제 X**: 매 production 의 capacity planning 의 final sign-off (real workload benchmark 필수).
## ❌ 안티패턴
- **Distributed monolith state**: 매 service 의 IMDG 의 shared mutable state — 매 hidden coupling.
- **N+1 across grid**: client-side loop 의 단일 키 fetch — 매 batch API 의 use.
- **No backup count**: backup=0 → 매 node loss 의 data loss.
- **Serialization neglect**: default Java serialization → 매 slow + bloated, 매 IdentifiedDataSerializable / Compact 의 use.
- **Treating IMDG as durable DB**: 매 persistence 의 explicit config 없이 → restart 의 data loss.
## 🧪 검증 / 중복
- Verified (Hazelcast 5.5 docs, Apache Ignite 2.16 docs, Oracle Coherence 14c docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — IMDG (Hazelcast/Ignite) 의 full content |
@@ -0,0 +1,179 @@
---
id: wiki-2026-0508-incremental-static-regeneration-
title: Incremental Static Regeneration (ISR)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [ISR, Stale-While-Revalidate Static, On-Demand Revalidation]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, nextjs, ssg, caching, web]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: nextjs
---
# Incremental Static Regeneration (ISR)
## 매 한 줄
> **"매 static page 의 build-time 의 prerender + runtime 의 stale-while-revalidate 의 통한 fresh 의 hybrid"**. 매 Next.js 9.5 (2020) 의 introduction, 매 Vercel 의 patent (US 11,055,090), 매 modern 의 Next.js 15 App Router 의 `revalidate` + `revalidateTag` + `revalidatePath` 의 first-class.
## 매 핵심
### 매 ISR 동작
1. Build 시 page 의 prerender → static HTML + JSON.
2. Request 의 cached HTML 의 즉시 serve.
3. `revalidate: N` 초 후 첫 request 의 background regenerate trigger.
4. 매 그 request 는 stale 의 받음, 매 다음 request 는 fresh.
5. On-demand: webhook → `revalidateTag('post-123')` 의 cache 의 invalidate.
### 매 ISR vs SSR vs SSG
- **SSG**: build-time only, content change → rebuild.
- **SSR**: every request, fresh but slow + costly.
- **ISR**: prerendered + revalidate window, near-CDN speed + freshness.
- **PPR (Partial Prerendering, Next.js 15)**: static shell + dynamic holes — ISR 의 evolution.
### 매 응용
1. Marketing/blog (수십만 page).
2. E-commerce product page (price/stock 의 stale OK seconds).
3. Docs site (authored content, low write rate).
## 💻 패턴
### App Router — Time-Based Revalidate
```typescript
// app/blog/[slug]/page.tsx
export const revalidate = 60; // seconds
export default async function Post({ params }: { params: { slug: string } }) {
const post = await fetch(`https://cms.example.com/posts/${params.slug}`, {
next: { revalidate: 60, tags: [`post:${params.slug}`] },
}).then(r => r.json());
return <article>{post.title}</article>;
}
export async function generateStaticParams() {
const posts = await fetch('https://cms.example.com/posts').then(r => r.json());
return posts.map((p: any) => ({ slug: p.slug }));
}
```
### On-Demand — `revalidateTag`
```typescript
// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache';
import { NextRequest } from 'next/server';
export async function POST(req: NextRequest) {
const secret = req.headers.get('x-webhook-secret');
if (secret !== process.env.WEBHOOK_SECRET) {
return new Response('forbidden', { status: 403 });
}
const { slug } = await req.json();
revalidateTag(`post:${slug}`);
return Response.json({ revalidated: true, slug });
}
```
### `revalidatePath` (entire route)
```typescript
import { revalidatePath } from 'next/cache';
export async function publishPost(slug: string) {
await db.posts.update({ where: { slug }, data: { published: true } });
revalidatePath(`/blog/${slug}`);
revalidatePath('/blog');
}
```
### Pages Router (legacy `getStaticProps`)
```typescript
// pages/products/[id].tsx
export async function getStaticProps({ params }) {
const product = await fetch(`/api/products/${params.id}`).then(r => r.json());
return { props: { product }, revalidate: 30 };
}
export async function getStaticPaths() {
const top100 = await fetch('/api/products?top=100').then(r => r.json());
return {
paths: top100.map((p: any) => ({ params: { id: p.id } })),
fallback: 'blocking', // first request 의 SSR-then-cache
};
}
```
### CMS Webhook → ISR
```typescript
// Sanity / Contentful / Strapi webhook
{
"url": "https://app.example.com/api/revalidate",
"headers": { "x-webhook-secret": "..." },
"events": ["entry.publish", "entry.update"]
}
```
### Partial Prerendering (Next.js 15)
```typescript
// next.config.ts
export default { experimental: { ppr: 'incremental' } };
// app/page.tsx
export const experimental_ppr = true;
import { Suspense } from 'react';
export default function Page() {
return (
<>
<StaticHero /> {/* prerendered */}
<Suspense fallback={<Skel/>}>
<DynamicCart /> {/* streamed at request time */}
</Suspense>
</>
);
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Content-heavy, low write | ISR + on-demand revalidate |
| Per-user dashboard | SSR / Server Components (no ISR) |
| Pure static (마케팅 사이트) | SSG, no revalidate |
| Real-time (stock ticker) | Streaming / WebSocket |
| Mixed page (static + dynamic) | PPR (Next.js 15+) |
**기본값**: 매 content site — App Router + tag-based on-demand revalidation, 매 fallback 의 time-based 60s.
## 🔗 Graph
- 부모: [[Web-Rendering-Strategies]]
- 변형: [[Stale-While-Revalidate]] · [[Edge-SSR]]
- 응용: [[Next.js]]
- Adjacent: [[CDN]] · [[React-Server-Components]] · [[Island Architecture]]
## 🤖 LLM 활용
**언제**: revalidate strategy 의 design, webhook handler 의 generate, cache tag 의 schema 의 propose.
**언제 X**: 매 personalized content 의 cache key 의 design (PII leak risk — human review 필수).
## ❌ 안티패턴
- **Per-user ISR**: cookie/auth-dependent page 의 ISR → cross-user data leak.
- **Tag explosion**: 매 query 의 unique tag → 매 cache 의 fragmentation.
- **No fallback**: `fallback: false` + dynamic params → 404 의 surprise.
- **Webhook 의 unsecured**: secret 의 X → revalidate 의 abuse 의 origin DoS.
- **Long `revalidate`**: 1-day window 의 stale price → 매 revenue loss.
## 🧪 검증 / 중복
- Verified (Next.js 15 docs, Vercel ISR blog 2020-2025).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Next.js ISR 의 full content |
@@ -0,0 +1,148 @@
---
id: wiki-2026-0508-incremental-marking
title: Incremental Marking
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Incremental GC, Tri-color Marking]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, gc, runtime, performance, memory]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: cpp
framework: v8-go-jvm
---
# Incremental Marking
## 매 한 줄
> **"매 GC mark phase 의 small slice 의 mutator 의 interleave 의 통한 pause time 의 reduction"**. 매 Dijkstra 의 1978 tri-color abstraction 의 origin, 매 V8 (2011), Go (2015 concurrent), ZGC/Shenandoah (sub-millisecond) 의 modern 의 ubiquity — 매 stop-the-world 의 long pause 의 avoid.
## 매 핵심
### 매 Tri-Color Abstraction
- **White**: 매 unvisited / unreachable candidate.
- **Gray**: 매 visited 의 children 의 X.
- **Black**: 매 fully scanned (children 의 gray/black).
- **Invariant**: 매 black → white edge 의 X (strong invariant) 의 violation 의 fix → write barrier.
### 매 Write Barrier 종류
- **Dijkstra (insertion)**: black → white 의 store 의 시 white 의 gray 로 promote.
- **Yuasa (deletion / SATB)**: gray pointer 의 overwrite 시 old target 의 gray 로 (snapshot-at-the-beginning).
- **Hybrid**: Go 1.8+ 의 hybrid barrier (stack 의 black 의 가정).
### 매 응용
1. V8 (Chrome/Node) — incremental + concurrent + lazy sweep.
2. Go — concurrent tri-color mark, sub-ms STW.
3. JVM ZGC / Shenandoah — colored pointers / load barriers.
## 💻 패턴
### Dijkstra Write Barrier (Pseudo-C)
```c
void write_barrier(Object** slot, Object* new_val) {
if (gc_phase == MARKING && new_val != NULL && new_val->color == WHITE) {
new_val->color = GRAY;
mark_stack_push(new_val);
}
*slot = new_val;
}
```
### Tri-Color Marking Loop
```cpp
void incremental_mark_step(size_t budget_bytes) {
size_t scanned = 0;
while (scanned < budget_bytes && !mark_stack.empty()) {
Object* obj = mark_stack.pop(); // gray
for (Object* child : obj->refs()) {
if (child->color == WHITE) {
child->color = GRAY;
mark_stack.push(child);
}
}
obj->color = BLACK;
scanned += obj->size();
}
}
```
### V8-Style Step Scheduling
```cpp
// Allocation 의 통한 mark step 의 trigger
void* allocate(size_t n) {
void* p = bump_alloc(n);
marking_progress_ += n;
if (marking_progress_ >= step_threshold_) {
incremental_mark_step(/*budget=*/n * 2); // pay-as-you-go
marking_progress_ = 0;
}
return p;
}
```
### Go-Style SATB-ish Hybrid Barrier
```go
// runtime/mbarrier.go (simplified)
//go:nowritebarrierrec
func gcWriteBarrier(slot *unsafe.Pointer, ptr unsafe.Pointer) {
if writeBarrier.enabled {
// Shade ptr (Dijkstra) AND shade *slot (Yuasa)
shade(ptr)
shade(*slot)
}
*slot = ptr
}
```
### Concurrent Mark Termination
```cpp
void mark_termination() {
stop_the_world(); // brief STW
drain_remaining_mark_stack(); // flush per-thread buffers
weak_ref_processing();
start_concurrent_sweep();
resume_world();
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Latency-critical (game, trading) | ZGC / Shenandoah (sub-ms) |
| Throughput-critical (batch) | Parallel STW collector |
| Mid-size heap, mixed | G1, V8 incremental |
| Tiny heap (embedded) | Reference counting / simple mark-sweep |
**기본값**: 매 modern runtime 의 기본 (V8, Go, JVM G1) — explicit tuning 없이 incremental marking 의 enabled.
## 🔗 Graph
- 부모: [[Garbage-Collection]] · [[Memory-Management]]
- 변형: [[Concurrent-Marking]]
- 응용: [[V8]]
- Adjacent: [[Write-Barrier]] · [[Reference-Counting]]
## 🤖 LLM 활용
**언제**: GC pause 의 root cause 의 analysis, write barrier 의 correctness 의 reasoning, GC log 의 parse.
**언제 X**: production GC tuning 의 final decision (workload-specific benchmark 필수).
## ❌ 안티패턴
- **Missing write barrier**: black → white 의 invariant 의 violation 의 → premature reclamation 의 use-after-free.
- **Unbounded step**: incremental step 의 budget 의 X → STW-equivalent pause.
- **Floating garbage 의 ignore**: SATB 의 dead 가 mark, 매 cycle 의 retain — frequent collection 의 통한 mitigation.
- **Allocator 의 black allocation 의 fail**: marking 중 allocate 의 white → 매 next cycle 까지 reachable 의 보장 의 X.
## 🧪 검증 / 중복
- Verified (Dijkstra "On-the-fly Garbage Collection" 1978, V8 blog, Go GC design doc, Hudson "A Unified Theory of GC").
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — incremental GC marking 의 full content |
@@ -0,0 +1,143 @@
---
id: wiki-2026-0508-indian-innovation-models
title: Indian Innovation Models
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Indian Innovation Models, Jugaad, Frugal Innovation, Gandhian Engineering]
duplicate_of: none
source_trust_level: A
confidence_score: 0.85
verification_status: applied
tags: [innovation, frugal, jugaad, india, design-philosophy, constraint-driven]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: n/a
framework: design-philosophy
---
# Indian Innovation Models
## 매 한 줄
> **"매 do more with less, for more"**. Indian innovation models — 매 jugaad, frugal engineering, Gandhian engineering, "more from less for more" (Mashelkar) — 매 severe resource constraint 매 mass affordability 의 결합 매 design philosophy. Tata Nano, Aravind Eye Care, Mitticool fridge 매 canonical example. 2026 매 climate-tech, off-grid, Global South 의 default playbook.
## 매 핵심
### 매 Three overlapping models
- **Jugaad**: 매 informal, improvisational, "hack-it-together" — 매 individual/small-business level.
- **Frugal innovation**: 매 systematic 매 cost-radical product redesign — 매 corporate (GE Healthcare ECG, Tata).
- **Gandhian engineering**: 매 ethical frame — 매 affordability + sustainability + bottom-of-pyramid.
### 매 Design principles (Mashelkar's "MLM": More from Less for More)
1. **Affordable excellence** (not low-end inferior).
2. **Resource frugality** (energy, materials, time).
3. **Sustainability** (long life, repairability, local material).
4. **Inclusivity** (for the 4 billion BOP).
### 매 응용
1. **Tata Nano**: $2,500 car — modular, simplified.
2. **Aravind Eye Care**: $30 cataract surgery via assembly-line surgical workflow.
3. **GE MAC 400 ECG**: $800 portable, battery-powered.
4. **Mitticool**: 매 clay, 매 zero-electricity refrigerator.
5. **JioPhone**: $20 4G feature phone, mass internet access.
6. **Aadhaar / UPI / DPI stack**: 매 nation-scale frugal digital infrastructure.
## 💻 패턴
### Frugal product checklist
```python
def frugal_score(product: Product) -> Score:
return Score(
cost_vs_incumbent = product.price / incumbent.price, # target < 0.3
bom_part_count = len(product.parts), # target: minimize
local_sourcing = product.local_parts / product.total,# target > 0.7
repair_index = product.user_repairable_pct, # target > 0.8
energy_per_use = product.kwh_per_use, # target: minimize
)
```
### Aravind-style throughput design
```
Assembly-line surgery:
- Surgeon does only 1 step (cataract extraction) per patient
- Parallel ORs share staff, equipment
- Result: 1 surgeon = 2,000+ surgeries/year (vs ~250 US average)
- Cost: $30 vs $3,000 — same outcome quality
```
### Jugaad heuristic
```
1. Constraint -> opportunity: scarcity is a design input, not blocker.
2. Reuse what exists: bicycle pump -> water pump.
3. Good enough > perfect: ship fast, iterate.
4. Local materials: clay, bamboo, scrap metal.
5. Bottom-up users: design WITH them, not FOR them.
```
### Tata Nano BoM compression
```
Standard car: ~30,000 parts, ~$15K
Nano approach:
- 21% fewer parts (30,000 -> ~24,000)
- Plastic body panels glued, not welded (no expensive welding line)
- Single windshield wiper
- 2-cylinder engine (vs 4)
- Outsource design to suppliers (co-development)
- Result: $2,500 retail
```
### India Stack DPI pattern
```
Identity (Aadhaar, biometric, free)
Payments (UPI, real-time, near-zero fee)
Data (DigiLocker, account aggregator, consent layer)
Open APIs → 1B+ users, 100B+ tx/year
Frugal lesson: PUBLIC infrastructure, PRIVATE innovation on top.
```
### Reverse innovation flow
```
Traditional: US/EU R&D -> developing markets (cost-down)
Reverse: Emerging-market design -> developed market (cost-radical)
Example: GE MAC 400 (designed for India) -> sold in US rural clinics
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 BOP/emerging market product | 매 frugal innovation framework |
| 매 high-margin premium | 매 traditional R&D (frugal 의 wrong framing) |
| 매 climate/sustainability constraint | 매 Gandhian engineering principles |
| 매 individual/SME hack | 매 jugaad mindset OK |
| 매 corporate scale-up of frugal | 매 systematize jugaad → frugal innovation |
**기본값**: 매 affordability constraint + sustainability constraint 의 동시 design input 으로.
## 🔗 Graph
- 변형: [[Frugal-Innovation]] · [[Jugaad]] · [[Gandhian-Engineering]]
- Adjacent: [[Lean-Startup]]
## 🤖 LLM 활용
**언제**: 매 emerging-market product design; 매 climate-tech affordability; 매 BOP strategy.
**언제 X**: 매 luxury/premium positioning; 매 deep-tech R&D (다른 framework).
## ❌ 안티패턴
- **Cheap = inferior**: 매 frugal 매 quality 매 sacrifice 의 의미 X — 매 affordable excellence.
- **Romanticizing jugaad**: 매 unsafe shortcut 매 system level 의 risk.
- **Copy-paste to West**: 매 context 다름 — 매 reverse innovation 매 careful adaptation 필요.
- **Cost-down only**: 매 frugal innovation 매 redesign — 매 cost-down 의 incremental 다름.
## 🧪 검증 / 중복
- Verified (Mashelkar "Reinventing India", Radjou/Prabhu/Ahuja "Jugaad Innovation" 2012, Govindarajan "Reverse Innovation" 2012, Aravind/Tata Nano case studies).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content (jugaad, frugal innovation, India Stack) |
@@ -0,0 +1,198 @@
---
id: wiki-2026-0508-instancedmesh
title: InstancedMesh
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [InstancedMesh, GPU Instancing, three.js InstancedMesh]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [threejs, webgl, gpu-instancing, rendering, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript/TypeScript
framework: three.js
---
# InstancedMesh
## 매 한 줄
> **"매 thousands of meshes 매 single draw call"**. `THREE.InstancedMesh` 매 same-geometry+material 매 N copies 매 GPU instancing 매 single draw — 매 forest, crowd, particle, voxel 의 standard pattern. 2026 매 r170+ 매 BatchedMesh (multi-geometry instancing) 매 추가됨.
## 매 핵심
### 매 InstancedMesh vs alternatives
- **Mesh × N**: 매 N draw calls. 매 simple, 매 slow at >100.
- **InstancedMesh**: 매 1 draw call, 매 same geom/material, 매 per-instance matrix + color.
- **BatchedMesh** (r150+): 매 1 draw call, 매 different geom 가능, 매 same material.
- **Custom shader InstancedBufferGeometry**: 매 full control, 매 boilerplate.
### 매 Per-instance attributes
- **`setMatrixAt(i, matrix)`** — 매 position/rotation/scale.
- **`setColorAt(i, color)`** — 매 per-instance tint (requires instanceColor).
- **Custom `InstancedBufferAttribute`** — 매 임의 per-instance data (HP, age, type).
### 매 응용
1. **Forest/foliage**: 10k 매 trees 매 60fps.
2. **Crowd simulation**: 매 NPCs 매 unique pose 매 transform.
3. **Voxel terrain**: 매 cube instance 매 chunk.
4. **Particle system**: 매 GPU-driven particle.
5. **Bullet patterns**: 매 bullet hell 매 thousands of bullets.
## 💻 패턴
### Basic InstancedMesh
```javascript
import * as THREE from 'three';
const count = 10000;
const geom = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshStandardMaterial({ color: 0x44aa88 });
const mesh = new THREE.InstancedMesh(geom, mat, count);
const m = new THREE.Matrix4();
for (let i = 0; i < count; i++) {
m.setPosition(
(Math.random() - 0.5) * 100,
(Math.random() - 0.5) * 100,
(Math.random() - 0.5) * 100
);
mesh.setMatrixAt(i, m);
}
mesh.instanceMatrix.needsUpdate = true;
scene.add(mesh);
```
### Per-instance color
```javascript
mesh.instanceColor = new THREE.InstancedBufferAttribute(
new Float32Array(count * 3), 3
);
const c = new THREE.Color();
for (let i = 0; i < count; i++) {
c.setHSL(i / count, 0.7, 0.5);
mesh.setColorAt(i, c);
}
mesh.instanceColor.needsUpdate = true;
```
### Dynamic update (animated swarm)
```javascript
const dummy = new THREE.Object3D();
function tick(time) {
for (let i = 0; i < count; i++) {
dummy.position.set(
Math.sin(time + i) * 10,
Math.cos(time * 0.5 + i * 0.3) * 5,
Math.sin(time * 0.3 + i) * 10
);
dummy.rotation.y = time + i;
dummy.updateMatrix();
mesh.setMatrixAt(i, dummy.matrix);
}
mesh.instanceMatrix.needsUpdate = true;
}
```
### Custom per-instance attribute (shader)
```javascript
const hpAttr = new THREE.InstancedBufferAttribute(new Float32Array(count), 1);
geom.setAttribute('aHp', hpAttr);
mat.onBeforeCompile = (shader) => {
shader.vertexShader = shader.vertexShader
.replace('#include <common>', `
#include <common>
attribute float aHp;
varying float vHp;
`)
.replace('#include <begin_vertex>', `
#include <begin_vertex>
vHp = aHp;
`);
shader.fragmentShader = shader.fragmentShader
.replace('#include <common>', `
#include <common>
varying float vHp;
`)
.replace('#include <dithering_fragment>', `
gl_FragColor.rgb = mix(vec3(1,0,0), gl_FragColor.rgb, vHp);
#include <dithering_fragment>
`);
};
```
### Frustum culling per instance (CPU side)
```javascript
const frustum = new THREE.Frustum().setFromProjectionMatrix(
new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)
);
let visible = 0;
for (let i = 0; i < total; i++) {
if (frustum.containsPoint(positions[i])) {
visibleMesh.setMatrixAt(visible++, matrices[i]);
}
}
visibleMesh.count = visible;
visibleMesh.instanceMatrix.needsUpdate = true;
```
### BatchedMesh (r150+, multi-geometry)
```javascript
const batch = new THREE.BatchedMesh(maxInstances, maxVerts, maxIndices, mat);
const treeId = batch.addGeometry(treeGeom);
const rockId = batch.addGeometry(rockGeom);
for (let i = 0; i < 5000; i++) batch.addInstance(i % 2 === 0 ? treeId : rockId);
```
### Raycasting against InstancedMesh
```javascript
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
const hits = raycaster.intersectObject(mesh);
if (hits.length) {
const i = hits[0].instanceId;
console.log('Hit instance', i);
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 same geom/material × N (>100) | InstancedMesh |
| 매 different geom × N | BatchedMesh (r150+) |
| 매 fully GPU-driven (compute-style) | InstancedBufferGeometry + WebGPU |
| 매 N < 50 | regular Mesh OK |
| 매 LOD per instance | InstancedMesh × LOD level + custom culling |
**기본값**: 매 N ≥ 100 → InstancedMesh.
## 🔗 Graph
- 부모: [[three.js]] · [[GPU-Instancing]]
- 변형: [[BatchedMesh]]
- 응용: [[Crowd-Simulation]]
- Adjacent: [[WebGPU]] · [[Frustum-Culling]] · [[LOD]]
## 🤖 LLM 활용
**언제**: 매 three.js 매 thousands of repeated objects; 매 WebGL 매 draw call optimization.
**언제 X**: 매 단일 unique mesh; 매 Unity (different API); 매 native C++ engine (use API-specific instancing).
## ❌ 안티패턴
- **Per-frame full rebuild**: 매 모든 matrix 매 update — 매 변하지 않는 instance 매 skip.
- **Forgetting `needsUpdate`**: 매 setMatrixAt 후 매 GPU 매 stale.
- **InstancedMesh × different materials**: 매 불가능 — BatchedMesh or 분리.
- **Raycast against 100k instances every frame**: 매 BVH (three-mesh-bvh) 사용.
## 🧪 검증 / 중복
- Verified (three.js docs r170, official examples webgl_instancing_*, BatchedMesh PR #25556).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content (instancing patterns + BatchedMesh) |
@@ -0,0 +1,191 @@
---
id: wiki-2026-0508-integration-architecture-diagram
title: Integration Architecture Diagrams
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Integration Diagrams, System Integration Diagram, Context Diagram]
duplicate_of: none
source_trust_level: A
confidence_score: 0.85
verification_status: applied
tags: [architecture, diagrams, integration, c4, documentation]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: mermaid
framework: c4-plantuml
---
# Integration Architecture Diagrams
## 매 한 줄
> **"매 system 의 external collaborators (services, APIs, queues, DBs) 의 visual mapping 의 통한 boundary + flow 의 communication"**. 매 Brown 의 C4 model (2018) 의 Context/Container level, 매 ArchiMate 의 application/technology layer, 매 modern 의 diagrams-as-code (Mermaid, Structurizr, D2) 의 dominant.
## 매 핵심
### 매 Diagram 종류
- **System Context** (C4 L1): 매 system + users + external systems.
- **Container** (C4 L2): 매 deployable units (web, api, db, queue).
- **Component** (C4 L3): 매 container 내부 의 logical block.
- **Sequence**: 매 time-ordered 의 message flow.
- **Data Flow Diagram (DFD)**: 매 process / store / external entity / flow.
- **Deployment**: 매 infra topology (regions, VPCs, nodes).
### 매 Notation
- C4 (simple, opinionated).
- ArchiMate (enterprise, exhaustive).
- UML deployment / component (legacy but valid).
- Custom (Mermaid + emoji label).
### 매 응용
1. Onboarding doc — 매 new hire 의 system map.
2. ADR 의 visual aid.
3. Threat modeling (STRIDE) 의 trust boundary 의 mark.
## 💻 패턴
### C4 System Context (Mermaid)
```mermaid
C4Context
title System Context — Order Platform
Person(customer, "Customer", "Buys products")
System(order, "Order Platform", "Handles order lifecycle")
System_Ext(stripe, "Stripe", "Payment processor")
System_Ext(shipping, "ShipEngine", "Shipping carrier API")
System_Ext(email, "SendGrid", "Transactional email")
Rel(customer, order, "Places order", "HTTPS")
Rel(order, stripe, "Charges card", "REST")
Rel(order, shipping, "Creates shipment", "REST")
Rel(order, email, "Sends confirmation", "SMTP API")
```
### C4 Container (Structurizr DSL)
```dsl
workspace {
model {
user = person "Customer"
order = softwareSystem "Order Platform" {
web = container "Web App" "Next.js 15"
api = container "API" "Node.js / Fastify"
db = container "Postgres" "RDS" "Database"
cache = container "Redis" "ElastiCache"
queue = container "Kafka" "MSK"
}
user -> web "Uses" "HTTPS"
web -> api "JSON/HTTPS"
api -> db "SQL"
api -> cache "RESP"
api -> queue "produces"
}
views { container order { include * autolayout lr } }
}
```
### Sequence — Distributed Transaction (Mermaid)
```mermaid
sequenceDiagram
participant C as Client
participant O as Order API
participant P as Payment
participant I as Inventory
participant K as Kafka
C->>O: POST /orders
O->>I: Reserve stock
I-->>O: OK (reservation_id)
O->>P: Charge card
P-->>O: success
O->>K: publish OrderCreated
O-->>C: 201 Created
Note over K: Async fanout to Shipping, Email, Analytics
```
### Data Flow Diagram (D2)
```d2
direction: right
customer: Customer { shape: person }
api: Order API
db: Postgres { shape: cylinder }
queue: Kafka { shape: queue }
analytics: Analytics WH { shape: cylinder }
customer -> api: POST /order
api -> db: INSERT
api -> queue: OrderCreated
queue -> analytics: stream
```
### Deployment (PlantUML)
```plantuml
@startuml
!include <C4/C4_Deployment>
Deployment_Node(aws, "AWS us-east-1") {
Deployment_Node(eks, "EKS cluster") {
Container(api, "Order API", "Node.js")
}
Deployment_Node(rds, "RDS Multi-AZ") {
ContainerDb(db, "Postgres 16")
}
}
Rel(api, db, "TLS")
@enduml
```
### Trust Boundary (Threat Model overlay)
```mermaid
flowchart LR
subgraph Public[Public Internet]
U[User]
end
subgraph DMZ
LB[ALB / WAF]
end
subgraph Private[Private VPC]
API[Order API]
DB[(Postgres)]
end
U -- TLS 1.3 --> LB
LB -- mTLS --> API
API --> DB
classDef boundary stroke-dasharray: 5 5
class Public,DMZ,Private boundary
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Quick wiki diagram | Mermaid (GitHub renders inline) |
| Versioned + reviewed | Structurizr DSL or PlantUML in repo |
| Enterprise governance | ArchiMate (Archi tool) |
| Generated from code | terraform-graph, kroki, arkade |
| Threat modeling | DFD + trust boundaries (Microsoft TMT) |
**기본값**: 매 C4 model — Context + Container 의 minimum, diagrams-as-code 의 (Mermaid / Structurizr).
## 🔗 Graph
- 부모: [[Software-Architecture]]
- 변형: [[C4-Model]]
- 응용: [[Mermaid]] · [[Structurizr]] · [[PlantUML]] · [[D2]]
- Adjacent: [[ADR]] · [[Threat-Modeling]]
## 🤖 LLM 활용
**언제**: diagram 의 Mermaid/D2 source 의 generate, existing diagram 의 explanation, missing actor 의 detect.
**언제 X**: 매 enterprise architecture 의 governance decision (human + tool standard 필요).
## ❌ 안티패턴
- **PowerPoint architecture**: PNG screenshot 의 stale, source 의 X.
- **Box-and-line soup**: 매 label 없이 arrow 의 multitude.
- **Mixing levels**: Context 의 component-level detail 의 cram.
- **No legend**: 매 reader 의 notation 의 guess.
- **Aspirational diagram**: actual deployment 의 mismatch — 매 onboarding 의 misleading.
## 🧪 검증 / 중복
- Verified (Brown "Software Architecture for Developers", c4model.com, ArchiMate 3.2 spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — integration architecture diagrams 의 full content |
@@ -0,0 +1,175 @@
---
id: wiki-2026-0508-island-architecture
title: Island Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Islands Architecture, Partial Hydration, Selective Hydration]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, web, frontend, hydration, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: astro-fresh
---
# Island Architecture
## 매 한 줄
> **"매 mostly-static HTML 의 sea 의 isolated interactive 'island' 의 selective hydration 의 통한 ship-less-JS"**. 매 Katie Sylor-Miller (2019) 의 term, Jason Miller (2020) 의 popularization, 매 Astro (2021) / Fresh (Deno) / Marko / Qwik 의 implementation — 매 SPA-everything 의 over-hydration 의 backlash.
## 매 핵심
### 매 핵심 idea
- Server 의 HTML 의 render (default).
- 매 interactive component (island) 의 isolated hydration boundary.
- 매 island 의 own JS bundle, 매 nothing else 의 ship.
- 매 island 간 의 share state 의 X (or framework-specific signal).
### 매 Hydration directive (Astro)
- `client:load` — 매 page load 의 즉시.
- `client:idle``requestIdleCallback`.
- `client:visible` — IntersectionObserver.
- `client:media="(min-width: 768px)"` — viewport conditional.
- `client:only="react"` — server render skip, client only.
### 매 응용
1. Content sites (blog, docs, marketing).
2. E-commerce (정적 product page + interactive cart island).
3. News / publishing (정적 article + comment island).
## 💻 패턴
### Astro — React Island
```astro
---
// src/pages/index.astro
import Counter from '../components/Counter.tsx';
import Newsletter from '../components/Newsletter.tsx';
const posts = await fetch(import.meta.env.CMS_URL).then(r => r.json());
---
<html>
<body>
<h1>Blog</h1>
<ul>{posts.map(p => <li>{p.title}</li>)}</ul>
<Counter client:visible /> <!-- island, lazy hydrate -->
<Newsletter client:idle /> <!-- island, idle hydrate -->
</body>
</html>
```
### Astro — Mixed Frameworks (one page, multiple)
```astro
---
import VueWidget from './Widget.vue';
import SvelteChart from './Chart.svelte';
import SolidSearch from './Search.tsx';
---
<VueWidget client:load />
<SvelteChart client:visible />
<SolidSearch client:idle />
```
### Fresh (Deno) — Island
```tsx
// islands/Counter.tsx
import { useSignal } from '@preact/signals';
export default function Counter() {
const count = useSignal(0);
return <button onClick={() => count.value++}>{count.value}</button>;
}
// routes/index.tsx
import Counter from '../islands/Counter.tsx';
export default function Home() {
return <main><h1>Home</h1><Counter /></main>;
}
```
### Qwik — Resumability (zero hydration)
```tsx
// src/routes/index.tsx
import { component$, useSignal } from '@builder.io/qwik';
export default component$(() => {
const count = useSignal(0);
return (
<button onClick$={() => count.value++}>
Clicks: {count.value}
</button>
);
});
// 매 click 의 시 의 only 의 download — true progressive
```
### Marko 5 — Streaming Islands
```marko
<!doctype html>
<html>
<body>
<h1>Products</h1>
<await(productPromise)>
<@then|products|>
<for|p| of=products>
<product-card p=p/>
</for>
</@then>
</await>
</body>
</html>
```
### Performance Budget Check
```yaml
# .lighthouserc.yml
ci:
collect: { url: ['https://example.com/'] }
assert:
assertions:
total-byte-weight: ['error', { maxNumericValue: 200000 }]
total-blocking-time: ['error', { maxNumericValue: 200 }]
interaction-to-next-paint: ['error', { maxNumericValue: 200 }]
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Content-heavy, low interactivity | Astro (default) |
| Per-route framework choice | Astro multi-framework |
| Edge / Deno preference | Fresh |
| App-shell SPA feel | Next.js / Remix (RSC + Suspense) |
| Zero-hydration target | Qwik |
**기본값**: 매 marketing/blog/docs — Astro + island per interactive component. 매 dashboard-y app — Next.js RSC.
## 🔗 Graph
- 부모: [[Web-Rendering-Strategies]] · [[프론트엔드_및_UIUX_표준|Frontend-Architecture]]
- 변형: [[Partial-Hydration]] · [[Resumability]] · [[Streaming-SSR]]
- 응용: [[Astro]] · [[Qwik]]
- Adjacent: [[React-Server-Components]] · [[Incremental-Static-Regeneration-ISR]] · [[MPA]]
## 🤖 LLM 활용
**언제**: page 의 island boundary 의 propose, hydration directive 의 select, JS bundle 의 reduction 의 suggest.
**언제 X**: 매 framework 의 final choice (team skill, ecosystem fit 의 human decision).
## ❌ 안티패턴
- **Island sprawl**: 매 component 의 `client:load` → SPA equivalent.
- **Cross-island state**: 매 island 의 shared store 의 hack — 매 framework boundary 의 violation.
- **Server-only data 의 island leak**: secret/PII 의 client island prop 의 pass.
- **`client:only` overuse**: server render 의 skip → SEO 의 hurt + LCP 의 regress.
- **Wrong tool**: 매 highly interactive app (Figma-like) 의 Astro 의 force-fit.
## 🧪 검증 / 중복
- Verified (Jason Miller "Islands Architecture" 2020, Astro 4 docs, Fresh docs, web.dev).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — island architecture (Astro/Fresh/Qwik) 의 full content |
@@ -0,0 +1,136 @@
---
id: wiki-2026-0508-keeper-of-the-vision
title: Keeper of the Vision
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Keeper of the Vision, Vision Keeper, 비전 수호자, Architect Role]
duplicate_of: none
source_trust_level: A
confidence_score: 0.85
verification_status: applied
tags: [architecture, leadership, role, organization, technical-direction]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: n/a
framework: organizational
---
# Keeper of the Vision
## 매 한 줄
> **"매 architect 의 most-underrated 의무"**. Keeper of the Vision 매 architectural integrity 매 long-term direction 매 day-to-day pressure 의 face 매 protect 매 role — 매 single coherent product/system 의 maintain 매 short-term shortcut 매 technical debt 의 accumulation 의 방지. Brooks ("Mythical Man-Month"), Fowler 매 emphasized.
## 매 핵심
### 매 What the Keeper does
- **Conceptual integrity**: 매 system 매 단일 mind 의 product 처럼 feel 하도록.
- **Veto authority**: 매 vision-violating change 의 block (or escalate).
- **Trade-off articulation**: 매 short-term gain vs long-term cost 의 명확.
- **Mentorship**: 매 team 매 vision 의 internalize 하도록.
- **Public memory**: 매 ADR (Architecture Decision Record) 매 maintain.
### 매 Tensions
- **Speed vs coherence**: 매 PM 매 ship now, 매 keeper 매 do it right.
- **Local vs global**: 매 team A 매 best for them, 매 worst for system.
- **Innovation vs consistency**: 매 new framework 매 cool, 매 다양 ization 매 maintenance burden.
### 매 응용
1. **Tech lead role**: 매 small team 매 lead 의 explicit responsibility.
2. **Staff/Principal engineer**: 매 cross-team 매 keeper.
3. **Game director / Lead designer**: 매 product vision (Miyamoto, Sid Meier model).
4. **Open source BDFL**: 매 Linus, Guido, Matz — 매 codified extreme.
## 💻 패턴
### Architecture Decision Record (ADR)
```markdown
# ADR-0042: Use SQLite for embedded analytics, not Postgres
Status: Accepted
Date: 2026-04-12
Context: Edge devices need local analytics queries...
Decision: SQLite + Litestream replication.
Consequences:
+ zero ops, single binary
- no advanced window functions until SQLite 3.45
Vision alignment: "operate offline-first" pillar #2.
```
### Vision artifact (one-pager)
```markdown
# Product North Star (2026)
1. Offline-first: every feature works without network.
2. Single-binary deploy: no docker required for self-host.
3. Plain-text data: SQLite + JSON, no proprietary blobs.
4. Pluggable AI: vendor-neutral, swap Anthropic ↔ local Llama.
```
### Keeper review checklist (PR template)
```markdown
- [ ] Aligns with North Star pillars (#14)?
- [ ] Introduces new dependency? Justify.
- [ ] Adds DB migration? Reversible?
- [ ] Public API change? ADR required.
- [ ] Latency impact measured?
```
### Conceptual integrity test
```python
def integrity_smell(diff: Diff) -> list[str]:
smells = []
if introduces_new_pattern(diff) and not has_adr(diff):
smells.append("New pattern w/o ADR")
if duplicates_existing(diff):
smells.append(f"Duplicates {diff.similar_to}")
if cross_layer_import(diff):
smells.append("Layer boundary violated")
return smells
```
### Office-hours protocol
```
Weekly architect office hours (1h):
- Anyone bring design Q
- Whiteboard walkthrough
- Output: ADR draft or "go ahead"
Cost: 1h/week. Benefit: prevents 10× cost of misalignment.
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 small team (≤5) | 매 tech lead 매 implicit keeper |
| 매 medium (520) | 매 explicit "architect" role 매 part-time |
| 매 large (>20) | 매 architecture guild + Staff/Principal 매 keeper |
| 매 OSS project | 매 BDFL or 매 core team 매 vote |
| 매 startup early | 매 founder/CTO 매 keeper |
**기본값**: 매 ADR + weekly office hours + 매 명시적 vision document.
## 🔗 Graph
- 부모: [[Conceptual-Integrity]]
- 응용: [[ADR-Architecture-Decision-Record]]
- Adjacent: [[Conways-Law]] · [[Technical_Debt|Technical-Debt]]
## 🤖 LLM 활용
**언제**: 매 architect role responsibilities 의 articulate; 매 ADR template; 매 architecture review checklist.
**언제 X**: 매 individual contributor 의 day-to-day coding (다른 layer); 매 PM/product strategy (overlap 있지만 scope 다름).
## ❌ 안티패턴
- **Ivory tower architect**: 매 코드 매 안 짜고 매 mandate 만 — 매 lose credibility.
- **Veto-only**: 매 block 만 하고 매 alternatives 매 propose 안 함.
- **Vision drift**: 매 6 months 매 vision 매 silent 변경 — 매 team 매 confused.
- **Hero dependency**: 매 keeper 떠나면 매 collapse — 매 succession plan 필요.
## 🧪 검증 / 중복
- Verified (Brooks "Mythical Man-Month" Ch.4 conceptual integrity, Fowler "Who Needs an Architect?", Kruchten ADR origin 2011).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content (architect role, ADR patterns) |
@@ -0,0 +1,191 @@
---
id: wiki-2026-0508-lstm-long-short-term-memory
title: LSTM (Long Short-Term Memory)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [LSTM, Long Short-Term Memory Network]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [neural-network, sequence-modeling, rnn, deep-learning]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: pytorch
---
# LSTM (Long Short-Term Memory)
## 매 한 줄
> **"매 gated cell state 로 vanishing gradient 회피"**. Hochreiter & Schmidhuber (1997) — RNN 의 long-range dependency 학습 문제 의 forget/input/output gate 의 cell state 보호. 2026 에서는 Transformer 가 sequence modeling 의 dominant 이지만 LSTM 은 매 small-data, low-latency, streaming, edge inference 에서 여전히 strong choice (Mamba/SSM 의 부상에도 production 의 niche 유지).
## 매 핵심
### 매 RNN 의 한계
- Vanilla RNN: `h_t = tanh(W·[h_{t-1}, x_t])` 의 매 step 마다 gradient multiplication.
- Vanishing gradient: 매 long sequence 에서 `∂L/∂h_0 ≈ 0` — early step 의 학습 불가.
- Exploding gradient: 반대 방향, gradient clipping 으로 mitigate 가능.
### 매 LSTM cell 구조
- **Cell state C_t**: 매 highway — gradient 가 매 multiplicative interaction 없이 flow.
- **Forget gate f_t**: 매 어떤 information 을 cell state 에서 drop 할지 결정.
- **Input gate i_t**: 매 새로운 information 을 cell state 에 add.
- **Output gate o_t**: 매 cell state 의 어떤 부분을 hidden state 로 expose.
- 매 sigmoid gate (0~1) 의 element-wise gating.
### 매 응용 (2026)
1. Time-series forecasting (small/medium scale, transformer overkill 인 경우).
2. Streaming ASR / speech encoder (low-latency causal).
3. Edge device inference (TinyML, mobile keyboard prediction).
4. Anomaly detection on sensor streams.
5. Reinforcement learning policy network (recurrent baselines).
## 💻 패턴
### 1. PyTorch LSTM (basic)
```python
import torch
import torch.nn as nn
class LSTMTagger(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim, num_tags):
super().__init__()
self.embed = nn.Embedding(vocab_size, embed_dim)
self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, num_tags)
def forward(self, x):
# x: [B, T]
e = self.embed(x) # [B, T, E]
out, (h, c) = self.lstm(e) # out: [B, T, H]
return self.fc(out) # [B, T, num_tags]
model = LSTMTagger(vocab_size=10000, embed_dim=128, hidden_dim=256, num_tags=10)
```
### 2. Bidirectional + multi-layer
```python
self.lstm = nn.LSTM(
input_size=128,
hidden_size=256,
num_layers=2,
bidirectional=True,
dropout=0.3,
batch_first=True,
)
# Output: [B, T, 2*256]
```
### 3. Manual LSTM cell (understand internals)
```python
class LSTMCellManual(nn.Module):
def __init__(self, input_dim, hidden_dim):
super().__init__()
self.W = nn.Linear(input_dim + hidden_dim, 4 * hidden_dim)
self.hidden_dim = hidden_dim
def forward(self, x, state):
h, c = state
z = self.W(torch.cat([x, h], dim=-1))
i, f, g, o = z.chunk(4, dim=-1)
i, f, o = torch.sigmoid(i), torch.sigmoid(f), torch.sigmoid(o)
g = torch.tanh(g)
c_new = f * c + i * g # cell state update
h_new = o * torch.tanh(c_new) # hidden output
return h_new, c_new
```
### 4. Streaming inference (stateful)
```python
class StreamingLSTM:
def __init__(self, model):
self.model = model
self.state = None
def step(self, x_t):
# x_t: [1, 1, E]
out, self.state = self.model.lstm(x_t, self.state)
return self.model.fc(out)
def reset(self):
self.state = None
```
### 5. Time-series forecasting
```python
class Forecaster(nn.Module):
def __init__(self, n_features, hidden=128, horizon=24):
super().__init__()
self.lstm = nn.LSTM(n_features, hidden, num_layers=2, batch_first=True)
self.head = nn.Linear(hidden, horizon)
def forward(self, x):
# x: [B, T, F]
_, (h, _) = self.lstm(x)
return self.head(h[-1]) # [B, horizon]
# Train with MSE on next-N-step prediction
```
### 6. Gradient clipping (essential for LSTM)
```python
optimizer.zero_grad()
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
```
### 7. ONNX export for edge
```python
dummy = torch.randn(1, 100, 128)
torch.onnx.export(
model, dummy, "lstm.onnx",
input_names=["x"], output_names=["y"],
dynamic_axes={"x": {0: "batch", 1: "time"}},
opset_version=17,
)
# Deploy to mobile via ONNX Runtime / Core ML
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Long context (>1k tokens), large data | Transformer (attention). |
| Streaming, causal, low-latency | LSTM 또는 Mamba/SSM. |
| Small data (<10k samples) sequence | LSTM (transformer overfits). |
| Edge / mobile inference | LSTM (small footprint). |
| Multi-modal long-form generation | Transformer / Diffusion. |
| State-space modeling, very long seq | Mamba / S4 (post-2023 alternative). |
**기본값**: 2026 에서 새 sequence task 는 매 Transformer 부터. LSTM 은 매 streaming + edge + small-data 의 specific niche.
## 🔗 Graph
- 부모: [[Sequence Modeling]]
- 변형: [[데이터_사이언스_및_ML_엔지니어링|GRU]]
- 응용: [[Anomaly Detection]]
- Adjacent: [[Transformer]] · [[Transformer_Architecture_and_LLM_Foundations|Attention Mechanism]]
## 🤖 LLM 활용
**언제**: streaming inference design, edge deployment, small-data baseline, recurrent RL agent.
**언제 X**: large-scale language modeling, long-context (>4k) tasks, 매 modern foundation model approach.
## ❌ 안티패턴
- **No gradient clipping**: 매 exploding gradient 의 NaN loss. 매 clip_grad_norm 필수.
- **Wrong batch_first**: PyTorch default 는 `[T, B, H]`. `batch_first=True` 안 쓰면 매 shape 혼란.
- **Frozen state across batches**: 매 stateful LSTM 에서 batch boundary detach 안 하면 BPTT 가 매 entire history 까지 backprop — OOM.
- **LSTM for long context**: 매 >1k token 의 long-range dependency 는 매 attention 으로.
- **No layer norm**: 매 deep LSTM 의 training instability — LayerNorm-LSTM variant 권장.
## 🧪 검증 / 중복
- Verified (Hochreiter & Schmidhuber 1997, *Neural Computation*; PyTorch nn.LSTM docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — LSTM cell internals + 2026 niche positioning vs Transformer/Mamba |
@@ -0,0 +1,182 @@
---
id: wiki-2026-0508-modern-review-workflow
title: Modern Review Workflow
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [AI Code Review, PR Review 2026, Augmented Review]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [code-review, ci-cd, ai-augmented, pr-workflow]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: github-actions
---
# Modern Review Workflow
## 매 한 줄
> **"매 review = human judgment + AI scaffolding"**. 2026년 PR review 매 single-reviewer linting → multi-agent triage 의 진화. Claude Opus 4.7 / Codex 가 매 first-pass (style, security, regression) 를 처리, human 의 매 architectural / product 판단에 집중.
## 매 핵심
### 매 단계
- **Pre-PR**: 매 author-side `claude review` local 의 self-check.
- **CI gate**: 매 automated agent 의 매 diff scan — security, perf, test coverage.
- **Human review**: 매 design intent / API contract / UX trade-off 의 deep dive.
- **Post-merge**: 매 deploy preview + canary metrics 의 watch.
### 매 agent layer
- **Linter agent**: style, type, dead code.
- **Security agent**: secret scan, OWASP, dependency CVE.
- **Test agent**: coverage delta, flaky detect, mutation score.
- **Review agent**: 매 prose summary + risk flag (Claude Opus 4.7).
### 매 응용
1. Solo dev: 매 CI agent 만 = 매 reviewer 효과.
2. 팀 (10+): tiered — agent gate → senior architect.
3. OSS: 매 maintainer triage 의 cost 감소.
## 💻 패턴
### GitHub Actions: Claude review hook
```yaml
name: ai-review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: anthropics/claude-code-action@v1
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-opus-4-7
mode: review
target-base: ${{ github.base_ref }}
comment-style: inline
```
### Inline comment poster
```typescript
import Anthropic from "@anthropic-ai/sdk";
import { Octokit } from "@octokit/rest";
const a = new Anthropic();
const gh = new Octokit({ auth: process.env.GH_TOKEN });
export async function reviewDiff(owner: string, repo: string, pr: number) {
const { data: files } = await gh.pulls.listFiles({ owner, repo, pull_number: pr });
const diff = files.map((f) => `### ${f.filename}\n${f.patch ?? ""}`).join("\n\n");
const res = await a.messages.create({
model: "claude-opus-4-7",
max_tokens: 4096,
system: "You are a senior reviewer. Output JSON: {comments: [{path, line, body, severity}]}.",
messages: [{ role: "user", content: diff }],
});
const { comments } = JSON.parse((res.content[0] as any).text);
for (const c of comments) {
await gh.pulls.createReviewComment({
owner, repo, pull_number: pr, ...c,
commit_id: process.env.HEAD_SHA!,
});
}
}
```
### Local pre-PR self-check
```bash
# .git/hooks/pre-push
#!/usr/bin/env bash
set -e
git diff origin/main...HEAD | claude -p "Review this diff. Flag bugs, security, perf only. No style." --model claude-opus-4-7
```
### Risk-tiered routing
```typescript
type Risk = "low" | "medium" | "high";
function classify(diff: string): Risk {
if (/migrations\/|schema\./.test(diff)) return "high";
if (/auth|payment|crypto/i.test(diff)) return "high";
if (diff.split("\n").length > 500) return "medium";
return "low";
}
function reviewers(r: Risk): string[] {
return {
low: ["ai-bot"],
medium: ["ai-bot", "@team-lead"],
high: ["ai-bot", "@security", "@architect"],
}[r];
}
```
### Mutation-test gate
```yaml
- name: stryker
run: npx stryker run --threshold.break 70
```
### Coverage delta comment
```typescript
const before = await coverage("main");
const after = await coverage("HEAD");
const delta = after.lines - before.lines;
if (delta < -1) await gh.issues.createComment({
...ctx, body: `⚠️ Coverage dropped ${delta.toFixed(1)}%`,
});
```
### Auto-merge on green + AI ack
```yaml
- if: ${{ steps.ai-review.outputs.severity == 'none' && steps.tests.outcome == 'success' }}
run: gh pr merge ${{ github.event.pull_request.number }} --squash --auto
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Solo / OSS | AI agent only, human spot-check |
| Small team | AI gate + 1 human (rotating) |
| Regulated (fin/health) | AI + 2 humans + audit log |
| Hot path / migrations | Mandatory architect review |
**기본값**: AI first-pass + 1 human reviewer + risk-tiered escalation.
## 🔗 Graph
- 부모: [[CI-CD]]
- 변형: [[Pair-Programming]] · [[Mob-Programming]]
- 응용: [[Trunk-Based-Development]]
- Adjacent: [[Static-Analysis]] · [[Mutation-Testing]]
## 🤖 LLM 활용
**언제**: 매 diff scan, security triage, coverage summary, prose explanation 의 PR description.
**언제 X**: 매 architectural decision, API contract negotiation, domain-specific business rule — human 의 judgment.
## ❌ 안티패턴
- **AI rubber-stamp**: 매 agent approve = 매 human 의 skip. 매 critical path 의 review 누락.
- **Comment flood**: agent 의 매 nitpick → noise. Severity threshold 의 setting.
- **No risk tiering**: schema migration 매 typo fix 와 동급 review → bottleneck.
- **Secrets in prompt**: diff 의 secret 의 leak. Pre-scan + redact.
## 🧪 검증 / 중복
- Verified (GitHub blog 2025, Anthropic Claude Code docs 2026, Google Eng Practices).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — AI-augmented PR review workflow with Claude Opus 4.7 patterns |
@@ -0,0 +1,208 @@
---
id: wiki-2026-0508-modern-website-architecture
title: Modern Website Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Web Architecture 2026, RSC Architecture, Islands Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [web, architecture, rsc, astro, nextjs, edge]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: nextjs-astro
---
# Modern Website Architecture
## 매 한 줄
> **"매 page = static shell + streamed server components + minimal islands"**. 2020 SPA → 2024 SSR → 2026 RSC + edge 의 진화. Next.js 16 / Astro 5 / Remix 의 매 default = server-first, JS 의 ship 매 minimum.
## 매 핵심
### 매 layer
- **Edge runtime**: 매 request 의 region-local. Vercel/Cloudflare Workers, sub-50ms.
- **Server components**: 매 default render = server. Zero JS 의 ship.
- **Client islands**: 매 interactivity 의 hydrate 만.
- **CDN**: 매 static asset + ISR cache.
### 매 trade-off
- **SSG**: 매 build-time, fastest, stale data.
- **SSR**: 매 request-time, fresh, slower TTFB.
- **ISR**: 매 hybrid — stale-while-revalidate.
- **CSR**: 매 SPA, JS-heavy, slow first paint.
### 매 응용
1. Marketing site: SSG + Astro islands.
2. Dashboard: RSC + streaming + Suspense.
3. E-commerce: ISR + edge personalization.
## 💻 패턴
### Next.js 16 RSC
```tsx
// app/products/[id]/page.tsx — server component (default)
import { db } from "@/lib/db";
import { AddToCart } from "./add-to-cart"; // client island
export default async function Page({ params }: { params: { id: string } }) {
const product = await db.product.findUnique({ where: { id: params.id } });
if (!product) return <NotFound />;
return (
<article>
<h1>{product.name}</h1>
<p>{product.description}</p>
<AddToCart productId={product.id} />
</article>
);
}
```
### Client island
```tsx
// app/products/[id]/add-to-cart.tsx
"use client";
import { useState } from "react";
export function AddToCart({ productId }: { productId: string }) {
const [pending, setPending] = useState(false);
return (
<button
disabled={pending}
onClick={async () => {
setPending(true);
await fetch("/api/cart", { method: "POST", body: JSON.stringify({ productId }) });
setPending(false);
}}
>Add</button>
);
}
```
### Streaming with Suspense
```tsx
import { Suspense } from "react";
export default function Page() {
return (
<>
<Header />
<Suspense fallback={<Skeleton />}>
<SlowProductList /> {/* awaits DB */}
</Suspense>
<Suspense fallback={<Skeleton />}>
<SlowReviews />
</Suspense>
</>
);
}
```
### Astro islands
```astro
---
// src/pages/index.astro
import Counter from "../components/Counter.svelte";
const products = await fetch("https://api.shop/products").then(r => r.json());
---
<html>
<body>
{products.map(p => <article>{p.name}</article>)}
<Counter client:visible />
</body>
</html>
```
### Edge middleware (Vercel)
```typescript
// middleware.ts
import { NextResponse } from "next/server";
import { geolocation } from "@vercel/functions";
export function middleware(req: Request) {
const { country } = geolocation(req);
const res = NextResponse.next();
res.cookies.set("country", country ?? "US");
return res;
}
export const config = { matcher: "/((?!_next).*)" };
```
### ISR + tag revalidation
```tsx
// fetch with cache tags
const data = await fetch("https://api.shop/products", {
next: { revalidate: 3600, tags: ["products"] },
});
// trigger revalidation on update
import { revalidateTag } from "next/cache";
revalidateTag("products");
```
### Server actions
```tsx
// app/contact/page.tsx
export default function Page() {
async function submit(form: FormData) {
"use server";
await db.message.create({ data: { body: form.get("body") as string } });
}
return (
<form action={submit}>
<textarea name="body" />
<button>Send</button>
</form>
);
}
```
### View transitions
```tsx
"use client";
import { unstable_ViewTransition as ViewTransition } from "react";
<ViewTransition><ProductCard /></ViewTransition>
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Content site (blog, docs) | Astro SSG + minimal islands |
| App with auth | Next.js RSC + server actions |
| Personalized e-commerce | Next.js ISR + edge middleware |
| Realtime dashboard | RSC + Suspense streaming + SSE |
**기본값**: Next.js 16 RSC for apps, Astro 5 for content.
## 🔗 Graph
- 부모: [[Web-Architecture]] · [[프론트엔드_및_UIUX_표준|Frontend-Architecture]]
- 변형: [[Single-Page-Application]] · [[MPA]]
- 응용: [[Next-js-and-Modern-Web]] · [[Edge Computing|Edge-Computing]]
- Adjacent: [[CDN]] · [[Server-Components]] · [[Hydration]]
## 🤖 LLM 활용
**언제**: 매 server vs client component 의 split-suggest, Suspense boundary 의 propose, cache strategy 의 review.
**언제 X**: 매 design system, brand identity, accessibility audit (manual + tooling).
## ❌ 안티패턴
- **Everything client**: 매 100KB JS 의 marketing page = 매 LCP regression.
- **No streaming**: 매 await 의 block, blank screen 5s.
- **Cache everywhere**: 매 personalized data 의 stale = 매 wrong-user bug.
- **Edge for DB-heavy**: 매 cold start + DB latency = slower than serverful.
## 🧪 검증 / 중복
- Verified (Next.js 16 docs, Astro 5 docs, Vercel architecture guides 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — RSC + islands + edge web architecture |
@@ -0,0 +1,181 @@
---
id: wiki-2026-0508-modular-programming
title: Modular Programming
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Modularity, Module System, Separation of Concerns]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [modularity, architecture, software-design, decoupling]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: any
---
# Modular Programming
## 매 한 줄
> **"매 module = 1 concern, 1 contract, 1 owner"**. Parnas 1972 의 information hiding 매 origin. 2026 modular 의 매 form: ES modules, Rust crates, Python packages, Bazel targets — 매 boundary 의 explicit dependency graph.
## 매 핵심
### 매 원칙
- **High cohesion**: 매 module 의 single responsibility.
- **Low coupling**: 매 inter-module 의 narrow interface.
- **Information hiding**: 매 implementation detail 의 hide. Public surface 의 minimize.
- **Acyclic dependency**: 매 graph 의 DAG. Cycle = refactor signal.
### 매 boundary type
- **Logical**: namespace / package.
- **Physical**: separate compile unit / artifact.
- **Process**: separate deployable (microservice).
- **Trust**: separate security domain.
### 매 응용
1. Library author: 매 stable public API + private internals.
2. App architect: 매 feature module + shared kernel.
3. Platform team: 매 plugin host + extension points.
## 💻 패턴
### ES Module barrel + private
```typescript
// src/auth/index.ts (public surface)
export { signIn, signOut } from "./session";
export type { User } from "./types";
// src/auth/_internal/hash.ts (convention: _ prefix = private)
export function hashPassword(p: string) { /* ... */ }
// consumer
import { signIn } from "@/auth"; // ✅
import { hashPassword } from "@/auth/_internal/hash"; // ❌ lint rule
```
### ESLint boundary rule
```json
{
"rules": {
"no-restricted-imports": ["error", {
"patterns": [{
"group": ["**/_internal/**"],
"message": "Internal module — import via public barrel."
}]
}]
}
}
```
### Hexagonal port/adapter
```typescript
// port (module boundary)
export interface UserRepo {
find(id: string): Promise<User | null>;
save(u: User): Promise<void>;
}
// adapter (Postgres impl)
export class PgUserRepo implements UserRepo {
constructor(private db: Pool) {}
async find(id: string) { /* ... */ }
async save(u: User) { /* ... */ }
}
// core (depends on port only)
export class UserService {
constructor(private repo: UserRepo) {}
async promote(id: string) {
const u = await this.repo.find(id);
if (!u) throw new Error("not found");
u.role = "admin";
await this.repo.save(u);
}
}
```
### Dependency injection
```typescript
const repo = new PgUserRepo(pool);
const svc = new UserService(repo);
// test: swap impl
const fake: UserRepo = { find: async () => mockUser, save: async () => {} };
new UserService(fake);
```
### Rust crate boundary
```toml
# Cargo.toml
[workspace]
members = ["crates/core", "crates/api", "crates/db"]
[workspace.dependencies]
core = { path = "crates/core" }
```
### Python namespace package
```python
# myapp/auth/__init__.py
from .session import sign_in, sign_out
from .types import User
__all__ = ["sign_in", "sign_out", "User"]
```
### Acyclic check
```bash
npx madge --circular --extensions ts src/
# Or: nx graph --focus=auth
```
### Module facade
```typescript
// payments/index.ts — single entry point
export const payments = {
charge: (amt: number) => /* ... */,
refund: (id: string) => /* ... */,
webhook: (req: Request) => /* ... */,
};
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Small app (<10k LOC) | Logical modules (folders) |
| Medium (10k-100k) | Package boundary + barrel exports |
| Large (>100k) | Bazel/Nx targets + enforced graph |
| Multi-team | Process boundary (services) |
**기본값**: 매 logical module + barrel + ESLint boundary rule.
## 🔗 Graph
- 부모: [[Software-Architecture]] · [[Information-Hiding]]
- 변형: [[Microservices]] · [[Hexagonal-Architecture]] · [[Clean-Architecture]]
- 응용: [[Monorepo]] · [[Library-Design]]
- Adjacent: [[Domain-Driven-Design]] · [[SOLID]]
## 🤖 LLM 활용
**언제**: 매 module boundary 의 propose, dependency graph 의 visualize, refactor 의 split-suggest.
**언제 X**: 매 domain ownership decision, team org boundary — Conway's law 의 human judgment.
## ❌ 안티패턴
- **God module**: 매 utils.ts 의 1000+ exports. Cohesion = 0.
- **Circular dependency**: A → B → A. Test 의 hard, build 의 slow.
- **Leaky abstraction**: public surface 의 internal type 의 expose.
- **Premature modularization**: 100 LOC 매 5개 module = over-engineering.
## 🧪 검증 / 중복
- Verified (Parnas 1972 "On the Criteria...", Clean Architecture by Martin, Software Engineering at Google).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — modular programming principles + boundary patterns |
@@ -0,0 +1,186 @@
---
id: wiki-2026-0508-multi-threaded-architecture
title: Multi-threaded Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Multithreading, Concurrent Architecture, MT Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, concurrency, threading, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: cpp
framework: stdthread-tbb-rayon
---
# Multi-threaded Architecture
## 매 한 줄
> **"매 work를 multiple threads에 분산하여 throughput · responsiveness를 동시에 확보."**. 1990s SMP era에서 출발하여 2026 현재 manycore (Apple M4 Max 16-core, AMD Threadripper 96-core), GPU offload, async/await coroutine model이 주류. Game engine · server · ML inference · browser engine 모두 multi-threaded 설계가 default.
## 매 핵심
### 매 thread model 종류
- **OS thread (1:1)**: pthread, std::thread — kernel-scheduled, expensive context switch.
- **Green thread / fiber**: Go goroutine, Java 21 virtual thread — userland scheduler, M:N mapping.
- **Coroutine / async task**: C++20 coroutine, Rust async, Kotlin coroutine — stackless, await-resume.
- **Task-based**: Intel TBB, .NET TPL, Apple GCD — work-stealing scheduler, no thread management.
### 매 architectural pattern
- **Producer-consumer**: bounded queue로 backpressure.
- **Pipeline**: stage별 thread, ring buffer로 연결 (LMAX Disruptor).
- **Fork-join**: divide & conquer, work-stealing.
- **Actor**: 매 message passing (Akka, Erlang, Pony) — no shared state.
- **Data parallelism**: SIMD + thread pool — Rayon `par_iter()`, OpenMP `#pragma omp parallel for`.
### 매 응용
1. Game engine — render thread + game thread + audio thread + IO thread.
2. Browser — process-per-tab + GPU process + utility processes.
3. Database — connection pool + worker threads + background flush.
## 💻 패턴
### Thread pool with work queue (C++20)
```cpp
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
class ThreadPool {
std::vector<std::jthread> workers;
std::queue<std::function<void()>> tasks;
std::mutex mtx;
std::condition_variable cv;
bool stop = false;
public:
explicit ThreadPool(size_t n) {
for (size_t i = 0; i < n; ++i)
workers.emplace_back([this](std::stop_token st) {
while (!st.stop_requested()) {
std::function<void()> task;
{
std::unique_lock lk(mtx);
cv.wait(lk, [&]{ return stop || !tasks.empty(); });
if (stop && tasks.empty()) return;
task = std::move(tasks.front()); tasks.pop();
}
task();
}
});
}
template<class F> void submit(F&& f) {
{ std::lock_guard lk(mtx); tasks.emplace(std::forward<F>(f)); }
cv.notify_one();
}
};
```
### Rust Rayon data parallelism
```rust
use rayon::prelude::*;
fn process_batch(items: &[Item]) -> Vec<Result> {
items.par_iter()
.filter(|i| i.valid())
.map(|i| expensive_compute(i))
.collect()
}
// auto: work-stealing across all cores
```
### Go goroutine + channel (fan-out / fan-in)
```go
func pipeline(input <-chan Job) <-chan Result {
out := make(chan Result, 100)
var wg sync.WaitGroup
for i := 0; i < runtime.NumCPU(); i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range input {
out <- process(job)
}
}()
}
go func() { wg.Wait(); close(out) }()
return out
}
```
### Lock-free SPSC ring buffer
```cpp
template<typename T, size_t N>
class SPSCQueue {
alignas(64) std::atomic<size_t> head{0};
alignas(64) std::atomic<size_t> tail{0};
T buffer[N];
public:
bool push(T v) {
auto t = tail.load(std::memory_order_relaxed);
auto next = (t + 1) % N;
if (next == head.load(std::memory_order_acquire)) return false;
buffer[t] = std::move(v);
tail.store(next, std::memory_order_release);
return true;
}
};
```
### Game engine 3-thread architecture
```cpp
// Main thread: input + game logic
// Render thread: GPU command buffer
// IO thread: asset streaming
struct FrameSync {
std::atomic<uint64_t> game_frame{0};
std::atomic<uint64_t> render_frame{0};
std::counting_semaphore<2> render_ready{0};
};
// double-buffer scene state to allow N+1 game tick parallel with N render
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| CPU-bound, divisible work | Rayon / OpenMP / TBB |
| IO-heavy (10k+ connections) | async/await (Tokio, asyncio, Node) |
| Real-time game loop | dedicated threads + lock-free queue |
| Mixed workload | task-based (TBB, GCD) |
| Simple parallel-for | thread pool + work queue |
| Distributed across machines | actor (Akka) or message queue |
**기본값**: task-based scheduler (TBB/Rayon/Tokio) — manual thread management 회피.
## 🔗 Graph
- 부모: [[Concurrent_Rendering]] · [[Distributed-Systems|Distributed_Computing]]
- 변형: [[Fiber_Architecture]]
- 응용: [[Game_Loop]] · [[V8_엔진_힙_아키텍처|V8 Heap Architecture]] · [[Browser]]
- Adjacent: [[SharedArrayBuffer_보안_이슈와_Cross-Origin_Isolation]] · [[Memory_Leaks]]
## 🤖 LLM 활용
**언제**: throughput-critical workload, multi-core utilization, real-time game/server, ML inference batching.
**언제 X**: simple sequential script, IO-light short-lived task, single-core embedded — 매 overhead 큼.
## ❌ 안티패턴
- **Shared mutable state without sync**: data race · UB.
- **Coarse global lock**: 매 single-thread보다 느림 (lock contention).
- **Thread per request (10k+)**: stack memory 폭발 — async 또는 thread pool 사용.
- **busy-wait spin**: CPU 100% 소모 — condition variable / semaphore.
- **False sharing**: 같은 cache line의 다른 atomic — alignas(64) cache padding.
## 🧪 검증 / 중복
- Verified (Herb Sutter "The Free Lunch Is Over" 2005, Intel TBB docs, Rust async book 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content (thread models, patterns, decision matrix) |
@@ -0,0 +1,188 @@
---
id: wiki-2026-0508-netflix-마이크로서비스-전환
title: Netflix 마이크로서비스 전환
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Netflix Microservices, Netflix Cloud Migration, Netflix Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [microservices, netflix, case-study, cloud-migration, resilience]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: java
framework: spring-boot-spinnaker
---
# Netflix 마이크로서비스 전환
## 매 한 줄
> **"매 monolith → 매 1000+ microservice, 매 7년 의 journey"**. 2008 DB 손상 outage → 2009 AWS migration 시작 → 2016 완전 전환. 매 Chaos Engineering, Spinnaker, Hystrix, Eureka 의 birthplace. 매 modern microservice playbook 의 reference.
## 매 핵심
### 매 timeline
- **2008.08**: DVD shipping DB corruption — 3-day outage. Monolith fragility 의 trigger.
- **2009-2012**: Cassandra adoption, Edge service split, AWS migration 시작.
- **2013-2015**: Hystrix, Eureka, Ribbon, Zuul OSS 공개.
- **2016.01**: 마지막 datacenter 종료. 100% AWS.
- **2020+**: Service mesh (Envoy), gRPC migration, GraphQL federation.
### 매 driver
- **Scale**: 매 30M (2008) → 200M+ (2020) subscribers.
- **Velocity**: 매 daily deploy 의 thousands.
- **Resilience**: 매 region failure 의 graceful degrade.
- **Polyglot**: 매 service 의 own stack 의 freedom.
### 매 응용
1. Stream startup: 매 Netflix OSS 의 reuse (Eureka, Spinnaker).
2. Enterprise migration: strangler pattern + edge first.
3. Resilience: Chaos Monkey 의 culture adoption.
## 💻 패턴
### Strangler Fig migration
```java
// API Gateway routes — gradual cutover
@Component
public class FeatureRouter {
@Value("${migration.user-service.percent}") int migrationPercent;
public Route route(Request req) {
if (req.path().startsWith("/users")
&& ThreadLocalRandom.current().nextInt(100) < migrationPercent) {
return Route.NEW_MICROSERVICE;
}
return Route.LEGACY_MONOLITH;
}
}
```
### Circuit breaker (Resilience4j, Hystrix successor)
```java
import io.github.resilience4j.circuitbreaker.*;
CircuitBreakerConfig cfg = CircuitBreakerConfig.custom()
.failureRateThreshold(50)
.waitDurationInOpenState(Duration.ofSeconds(30))
.slidingWindowSize(20)
.build();
CircuitBreaker cb = CircuitBreaker.of("recommendations", cfg);
Supplier<Recommendations> call = CircuitBreaker.decorateSupplier(
cb, () -> recoClient.fetch(userId));
Recommendations result = Try.ofSupplier(call)
.recover(t -> Recommendations.fallback()) // degraded UX
.get();
```
### Eureka service discovery (client)
```java
@SpringBootApplication
@EnableDiscoveryClient
public class RecommendationServiceApp { }
// caller
@Autowired DiscoveryClient discovery;
List<ServiceInstance> instances = discovery.getInstances("user-service");
```
### Chaos Monkey schedule
```yaml
# spinnaker chaos-monkey config
chaos:
enabled: true
schedule: "MON-FRI 09:00-15:00 PT"
meanTimeBetweenKillsInWorkDays: 2
exceptions:
- { account: prod, region: us-east-1, stack: critical-payment }
```
### Spinnaker pipeline (deploy)
```json
{
"stages": [
{ "type": "bake", "package": "user-service", "baseOs": "bionic" },
{ "type": "deploy",
"clusters": [{ "account": "prod", "region": "us-east-1",
"strategy": "redblack", "capacity": { "min": 6, "max": 60 } }] },
{ "type": "wait", "waitTime": 600 },
{ "type": "checkPreconditions",
"preconditions": [{ "type": "expression", "context": "kayentaPass" }] }
]
}
```
### Bulkhead isolation
```java
ThreadPoolBulkheadConfig bulkhead = ThreadPoolBulkheadConfig.custom()
.maxThreadPoolSize(10)
.coreThreadPoolSize(5)
.queueCapacity(20)
.build();
```
### Backpressure with reactive
```java
// Spring WebFlux
public Flux<Movie> stream(String userId) {
return userClient.getProfile(userId)
.timeout(Duration.ofMillis(200))
.flatMapMany(p -> recoClient.recommend(p))
.onBackpressureBuffer(1000, BufferOverflowStrategy.DROP_OLDEST);
}
```
### Canary analysis (Kayenta)
```yaml
canaryConfig:
metrics:
- name: error-rate
query: "avg(error_count) / avg(request_count)"
criticality: critical
direction: increase
- name: latency-p99
criticality: high
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Startup pre-PMF | Monolith. Don't copy Netflix yet. |
| Growing (50+ eng) | Extract edge services first |
| Scale (Netflix-class) | Full microservices + service mesh |
| Resilience-critical | Chaos engineering + canary mandatory |
**기본값**: Modular monolith → strangler extraction when team/load demands.
## 🔗 Graph
- 부모: [[Microservices]]
- 변형: [[Service-Oriented-Architecture]] · [[Service-Mesh]]
- 응용: [[Chaos-Engineering]] · [[Spinnaker]]
- Adjacent: [[Strangler-Pattern]] · [[Circuit-Breaker]]
## 🤖 LLM 활용
**언제**: 매 case study 의 summarize, OSS Netflix tool 의 explain, migration sequence 의 propose.
**언제 X**: 매 own org 의 readiness 판단 — team maturity, ops capacity 의 honest assessment.
## ❌ 안티패턴
- **Cargo cult**: 매 5-person startup 의 microservices = 매 distributed monolith hell.
- **No observability first**: 매 100 services + no tracing = debug 의 impossible.
- **Big bang migration**: 매 monolith 의 1 day 의 split = outage.
- **Skip chaos**: 매 production failure mode 의 unknown until customer hits it.
## 🧪 검증 / 중복
- Verified (Netflix Tech Blog 2009-2024, "Building Microservices" by Newman, AWS re:Invent Netflix talks).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Netflix microservices migration case study + patterns |
@@ -0,0 +1,234 @@
---
id: wiki-2026-0508-next-js-and-modern-web
title: Next.js and Modern Web
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Next.js, Next 16, Modern React]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [nextjs, react, rsc, server-actions, web]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: nextjs-16
---
# Next.js and Modern Web
## 매 한 줄
> **"매 Next.js 16 = React 19 + RSC + Turbopack + edge-first"**. 2016 SSR helper → 2024 App Router → 2026 RSC default. 매 React 의 fullstack-y reference impl. Vercel runtime 외 의 self-host (Node, Docker, Cloudflare) 의 mature.
## 매 핵심
### 매 capability
- **App Router**: file-based routing + RSC + nested layouts.
- **Server Components**: zero JS by default.
- **Server Actions**: form/mutation 의 RPC.
- **Streaming**: Suspense boundary 의 progressive render.
- **Turbopack**: Rust bundler, prod build 5x faster.
- **Edge runtime**: V8 isolates, sub-50ms cold start.
### 매 rendering mode
- **Static (SSG)**: build-time, default for no-data routes.
- **Dynamic (SSR)**: per-request.
- **ISR**: stale-while-revalidate.
- **PPR (Partial Pre-rendering)**: 매 static shell + dynamic streamed (16+ stable).
### 매 응용
1. Marketing + dashboard combo: PPR.
2. E-commerce: ISR + edge personalize.
3. AI chat app: Server Actions + streaming response.
## 💻 패턴
### App Router file structure
```
app/
layout.tsx # root layout (server)
page.tsx # /
products/
page.tsx # /products
[id]/
page.tsx # /products/123
loading.tsx # Suspense fallback
error.tsx # error boundary
api/
cart/
route.ts # /api/cart
```
### Server component data fetch
```tsx
// app/products/[id]/page.tsx
import { db } from "@/lib/db";
import { notFound } from "next/navigation";
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const product = await db.product.findUnique({ where: { id } });
if (!product) notFound();
return <article>{product.name}</article>;
}
export async function generateStaticParams() {
const products = await db.product.findMany({ select: { id: true } });
return products.map((p) => ({ id: p.id }));
}
```
### Server Action
```tsx
// app/contact/actions.ts
"use server";
import { revalidatePath } from "next/cache";
import { z } from "zod";
const Schema = z.object({ email: z.string().email(), body: z.string().min(1) });
export async function sendMessage(_: unknown, form: FormData) {
const parsed = Schema.safeParse(Object.fromEntries(form));
if (!parsed.success) return { error: parsed.error.flatten() };
await db.message.create({ data: parsed.data });
revalidatePath("/contact");
return { ok: true };
}
```
```tsx
// app/contact/page.tsx
"use client";
import { useActionState } from "react";
import { sendMessage } from "./actions";
export default function Page() {
const [state, action, pending] = useActionState(sendMessage, null);
return (
<form action={action}>
<input name="email" type="email" />
<textarea name="body" />
<button disabled={pending}>{pending ? "..." : "Send"}</button>
{state?.ok && <p>Sent</p>}
</form>
);
}
```
### Streaming + Suspense
```tsx
import { Suspense } from "react";
export default function Page() {
return (
<>
<h1>Dashboard</h1>
<Suspense fallback={<Sk />}>
<Sales /> {/* slow server fetch */}
</Suspense>
<Suspense fallback={<Sk />}>
<Inventory />
</Suspense>
</>
);
}
```
### Partial Prerendering (Next 16)
```tsx
// next.config.ts
export default { experimental: { ppr: "incremental" } };
// app/products/[id]/page.tsx
export const experimental_ppr = true;
export default function Page() {
return (
<>
<ProductHeader /> {/* static, prerendered */}
<Suspense fallback={<PriceSkeleton />}>
<DynamicPrice /> {/* streamed at request-time */}
</Suspense>
</>
);
}
```
### Cache directives
```tsx
// fine-grained cache (Next 16)
import { unstable_cache } from "next/cache";
export const getProducts = unstable_cache(
async () => db.product.findMany(),
["products"],
{ revalidate: 3600, tags: ["products"] }
);
```
### Route handler (API)
```typescript
// app/api/cart/route.ts
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest) {
const body = await req.json();
await addToCart(body);
return NextResponse.json({ ok: true });
}
export const runtime = "edge";
```
### Middleware
```typescript
// middleware.ts
import { NextResponse, type NextRequest } from "next/server";
export function middleware(req: NextRequest) {
if (!req.cookies.has("session") && req.nextUrl.pathname.startsWith("/app")) {
return NextResponse.redirect(new URL("/login", req.url));
}
}
export const config = { matcher: "/app/:path*" };
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Content-heavy site | Astro (lighter) > Next |
| Fullstack app | Next.js 16 App Router |
| API only | Hono / Elysia (lighter) > Next |
| Static export | Next `output: "export"` or Astro |
**기본값**: Next.js 16 + App Router + RSC + Server Actions + Turbopack.
## 🔗 Graph
- 부모: [[Modern-Website-Architecture]] · [[React]]
- 변형: [[Remix]] · [[SvelteKit]] · [[Astro]]
- 응용: [[Server-Components]] · [[Edge Computing|Edge-Computing]]
- Adjacent: [[Turbopack]]
## 🤖 LLM 활용
**언제**: 매 boilerplate (route, action, layout) 의 generate, server/client split 의 propose, migration 의 plan.
**언제 X**: 매 design system, brand UX, perf budget 의 final call — human/team judgment.
## ❌ 안티패턴
- **All client components**: 매 "use client" 의 root = SSR benefit lose.
- **No Suspense boundary**: 매 single slow fetch 의 entire page block.
- **Server action 의 secret leak**: 매 closure 의 sensitive data 의 client bundle inclusion.
- **Cache without tags**: 매 stale forever or 매 manual purge hell.
## 🧪 검증 / 중복
- Verified (Next.js 16 docs, Vercel blog 2026, React 19 release notes).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Next.js 16 App Router + RSC + Server Actions patterns |
@@ -0,0 +1,230 @@
---
id: wiki-2026-0508-nosql-databases-in-ai
title: NoSQL Databases in AI
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [NoSQL for AI, Vector DB, Document Store AI]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [nosql, ai, vector-db, mongodb, redis, rag]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: mongodb-redis-pinecone
---
# NoSQL Databases in AI
## 매 한 줄
> **"매 AI workload = embedding + metadata + cache; 매 NoSQL 의 each layer 의 fit"**. 2026 RAG / agent stack 의 매 standard: vector DB (Pinecone/Qdrant/pgvector) + document store (MongoDB) + KV cache (Redis). 매 schema flexibility + horizontal scale 의 LLM-era natural fit.
## 매 핵심
### 매 NoSQL family + AI role
- **Vector**: embedding similarity (RAG, recommendation). Pinecone, Qdrant, Weaviate, Milvus.
- **Document**: chat history, agent state, structured output. MongoDB, CouchDB.
- **KV / Cache**: prompt cache, semantic cache, session. Redis, DragonflyDB.
- **Graph**: knowledge graph, entity link. Neo4j, ArangoDB.
- **Wide-column**: time-series telemetry, traces. Cassandra, ScyllaDB.
### 매 access pattern
- **Embed + ANN search**: HNSW / IVF index, top-k cosine.
- **Metadata filter + vector**: hybrid search.
- **TTL cache**: prompt → response 의 24h cache.
- **Append-only chat log**: doc store + per-user shard.
### 매 응용
1. RAG: vector + document hybrid.
2. Agent memory: document (short) + vector (long-term).
3. Personalization: KV (recent) + graph (relations).
## 💻 패턴
### Pinecone (managed vector)
```python
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key=os.environ["PINECONE_API_KEY"])
pc.create_index(
name="docs",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(cloud="aws", region="us-east-1"),
)
idx = pc.Index("docs")
idx.upsert(vectors=[
{"id": "doc1", "values": embed("Hello world"),
"metadata": {"source": "intro.md", "section": "overview"}},
])
res = idx.query(
vector=embed("greeting example"),
top_k=5,
filter={"source": {"$eq": "intro.md"}},
include_metadata=True,
)
```
### Qdrant (self-host)
```python
from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance, PointStruct
client = QdrantClient("localhost", port=6333)
client.recreate_collection(
"docs",
vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
)
client.upsert("docs", points=[
PointStruct(id=1, vector=embed(text), payload={"text": text, "source": "x.md"}),
])
hits = client.search("docs", query_vector=embed(q), limit=5,
query_filter={"must": [{"key": "source", "match": {"value": "x.md"}}]})
```
### pgvector (Postgres + vector)
```sql
CREATE EXTENSION vector;
CREATE TABLE docs (
id BIGSERIAL PRIMARY KEY,
text TEXT,
source TEXT,
embedding vector(1536)
);
CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops);
-- hybrid query
SELECT id, text FROM docs
WHERE source = 'intro.md'
ORDER BY embedding <=> $1::vector
LIMIT 5;
```
### MongoDB Atlas Vector Search
```javascript
import { MongoClient } from "mongodb";
const col = new MongoClient(uri).db("ai").collection("docs");
await col.aggregate([
{ $vectorSearch: {
index: "doc_embedding",
path: "embedding",
queryVector: await embed(q),
numCandidates: 100,
limit: 5,
filter: { source: "intro.md" },
}},
{ $project: { text: 1, score: { $meta: "vectorSearchScore" } } },
]).toArray();
```
### Redis semantic cache
```python
import redis, hashlib, json
r = redis.Redis()
def cached_completion(prompt: str, ttl=3600):
key = "ai:" + hashlib.sha256(prompt.encode()).hexdigest()
if v := r.get(key): return json.loads(v)
out = anthropic.messages.create(
model="claude-opus-4-7",
messages=[{"role":"user","content":prompt}],
max_tokens=1024,
)
r.setex(key, ttl, json.dumps({"text": out.content[0].text}))
return {"text": out.content[0].text}
```
### Redis Vector (semantic cache, near-match)
```python
# RediSearch + HNSW
from redis.commands.search.field import VectorField, TextField
from redis.commands.search.indexDefinition import IndexDefinition
r.ft("ai_cache").create_index(
[TextField("prompt"),
VectorField("v", "HNSW", {"TYPE":"FLOAT32","DIM":1536,"DISTANCE_METRIC":"COSINE"})],
definition=IndexDefinition(prefix=["cache:"]),
)
```
### Agent state (MongoDB)
```python
from pymongo import MongoClient
c = MongoClient(uri).agents.runs
run_id = c.insert_one({
"user_id": "u1",
"messages": [{"role":"system","content":"..."}],
"tool_calls": [],
"status": "running",
"created_at": datetime.utcnow(),
}).inserted_id
c.update_one({"_id": run_id}, {"$push": {"messages": new_msg}})
```
### Knowledge graph (Neo4j)
```cypher
MERGE (a:Person {name: 'Alice'})
MERGE (c:Company {name: 'Acme'})
MERGE (a)-[:WORKS_AT {since: 2020}]->(c)
```
```python
# answer "who at Acme works with Alice's manager?"
session.run("""
MATCH (a:Person {name: $n})-[:WORKS_AT]->(c)<-[:WORKS_AT]-(p)
RETURN p.name LIMIT 10
""", n="Alice")
```
### Hybrid retrieval (BM25 + vector)
```python
keyword_hits = es.search(index="docs", query={"match": {"text": q}})
vector_hits = idx.query(vector=embed(q), top_k=10).matches
fused = reciprocal_rank_fusion([keyword_hits, vector_hits], k=60)
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Small RAG (<1M docs) | pgvector (single Postgres) |
| Medium RAG (1M-100M) | Qdrant / Weaviate self-host |
| Large / managed | Pinecone / MongoDB Atlas |
| Agent state + chat | MongoDB document store |
| Prompt cache | Redis (exact + semantic) |
| Entity reasoning | Neo4j |
**기본값**: pgvector (start) → Qdrant (scale) + Redis cache + MongoDB for agent state.
## 🔗 Graph
- 응용: [[RAG]] · [[Semantic Search|Semantic-Search]] · [[Agent-Memory]]
- Adjacent: [[Embeddings]] · [[Hybrid-Search]] · [[pgvector]]
## 🤖 LLM 활용
**언제**: 매 schema design 의 propose, query construction 의 boilerplate, hybrid-search blend 의 tune.
**언제 X**: 매 capacity / cost projection, ANN index parameter (M, efConstruction) tuning — measure on real workload.
## ❌ 안티패턴
- **Vector DB only**: 매 metadata filter 의 ignore = 매 irrelevant top-k.
- **No re-ranker**: top-50 vector hits 의 직접 LLM 의 feed = noise. Cohere Rerank or cross-encoder.
- **Cache prompt verbatim**: 매 1-char diff = 매 cache miss. Use semantic cache.
- **Mixing OLTP + vector**: 매 single Postgres 의 both = 매 index bloat. Separate.
## 🧪 검증 / 중복
- Verified (Pinecone docs, Qdrant docs, MongoDB Atlas Vector Search 2025, "Designing Data-Intensive Applications", LangChain RAG cookbook).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — NoSQL families mapped to AI/RAG/agent workloads |
@@ -0,0 +1,149 @@
---
id: wiki-2026-0508-nudge-theory
title: Nudge Theory
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Nudge, Choice Architecture, Behavioral Nudge, 넛지]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [behavioral-economics, ux, design, psychology, choice-architecture]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: ux-design
---
# Nudge Theory
## 매 한 줄
> **"매 choice architecture를 미세 조정하여 freedom of choice를 보존한 채 predictable한 방향으로 행동을 유도."**. Richard Thaler · Cass Sunstein의 *Nudge* (2008) — 2017 Thaler 노벨경제학상. 2026 현재 UX design · public policy · health intervention · LLM safety의 기반 framework.
## 매 핵심
### 매 nudge 정의 (Thaler/Sunstein)
- 매 small change in choice architecture
- 매 predictable behavior change 유도
- 매 옵션을 금지하지 않음 (libertarian paternalism)
- 매 economic incentive 거의 없음 (cheap)
### 매 mechanism
- **Default**: 매 default option 압도적 영향 (organ donation opt-in vs opt-out — 12% vs 99%).
- **Salience**: 매 정보 visibility 증가.
- **Framing**: 매 동일 정보, 다른 표현 (90% lean vs 10% fat).
- **Social proof**: 매 "X% of users do Y".
- **Friction**: 매 desired action은 쉽게, undesired는 hard.
### 매 응용
1. UK Behavioral Insights Team — tax letter "9 of 10 pay on time" → 5% 회수율 증가.
2. Spotify "Discover Weekly" → 매 default playlist으로 engagement 증가.
3. Apple Health — 매 default 7000 step goal로 average +500 step.
## 💻 패턴
### Default opt-in for desired behavior
```tsx
// BAD: opt-in for 2FA
<Checkbox label="Enable 2FA (recommended)" defaultChecked={false} />
// GOOD: default-on with easy opt-out
<Checkbox
label="Enable 2FA"
defaultChecked={true}
helperText="Recommended. You can disable in Settings."
/>
```
### Friction: confirm destructive action
```tsx
function DeleteAccountButton() {
return (
<ConfirmDialog
title="Delete account?"
requireType="DELETE my-username" // typed friction
cooldownSeconds={5}
>
<Button variant="danger">Delete</Button>
</ConfirmDialog>
);
}
```
### Social proof nudge
```tsx
<PricingCard plan="pro" badge="Most popular — 73% of teams choose this" />
```
### Framing — loss aversion
```tsx
// BAD (gain frame, weaker)
<p>Save $120/year with annual billing</p>
// GOOD (loss frame, stronger; Tversky/Kahneman)
<p>Stop paying $10/mo extra switch to annual</p>
```
### Salience — progress nudge
```tsx
function ProfileCompletion({ percent }: { percent: number }) {
return (
<Banner show={percent < 100}>
Profile {percent}% complete add a photo to reach 100%
<ProgressBar value={percent} />
</Banner>
);
}
```
### Implementation intention prompt
```tsx
// "When X happens, I will do Y" — proven habit formation
<Onboarding>
<p>When will you exercise?</p>
<Select options={["Morning", "Lunch", "Evening"]} />
<p>Where?</p>
<Input placeholder="Living room, gym..." />
</Onboarding>
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| User benefits from default | opt-out default |
| User must consciously choose | opt-in, no default |
| Discourage harm | friction (confirm, delay) |
| Encourage rare valuable action | salience + reminder |
| Group conformity helpful | social proof |
**기본값**: transparent default + easy opt-out — 매 dark pattern과의 차별점.
## 🔗 Graph
- 부모: [[Behavioral_Economics]] · [[Cognitive_Bias]]
- 변형: [[Choice_Architecture]] · [[Habit_Loop]]
- 응용: [[Micro-interactions]] · [[Gamification]]
- Adjacent: [[FOMO (Fear of Missing Out)]] · [[Progressive-Disclosure]] · [[매몰_비용_오류_(Sunk_Cost_Fallacy)]]
## 🤖 LLM 활용
**언제**: UX flow 설계, public health/policy, habit-forming product, opt-in/opt-out 결정.
**언제 X**: high-stakes informed consent (의료, 금융 — 매 explicit choice 필수), regulated decision (legal contract).
## ❌ 안티패턴
- **Dark pattern (sludge)**: 매 친 user가 아닌 친 vendor — Sunstein 본인이 *Sludge* (2021)로 비판.
- **Hidden default**: 매 user 모르게 enable — opt-in의 transparency 무시.
- **Manipulation > nudge**: 매 deception (e.g. fake countdown) — ethics 위반.
- **Over-nudging**: 매 모든 화면에 nudge — banner blindness.
- **No measurement**: 매 A/B test 없이 nudge — direction 불명.
## 🧪 검증 / 중복
- Verified (Thaler/Sunstein *Nudge* 2008 / 2021 final ed., UK BIT trial reports, Sunstein *Sludge* 2021).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Nudge theory (Thaler/Sunstein) + UX patterns |
@@ -0,0 +1,160 @@
---
id: wiki-2026-0508-old-space
title: Old Space (V8)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Old Generation, Tenured Space, V8 Old Space, Major GC heap]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [v8, gc, memory, javascript, runtime]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: javascript
framework: v8
---
# Old Space (V8)
## 매 한 줄
> **"매 V8 heap의 long-lived object 영역 — Young Gen에서 2번 생존 후 promote, Major GC (Mark-Compact / Mark-Sweep / Concurrent Marking) 대상."**. Generational hypothesis 기반 (Ungar 1984). 2026 현재 V8 13.x · Node 24 · Chrome 130+에서 Orinoco의 concurrent / parallel / incremental marking + Pointer Compression으로 pause time <1ms.
## 매 핵심
### 매 V8 heap 구조
- **New Space (Young Gen)**: 1-8MB, semi-space (Cheney scavenger), allocation 빠름.
- **Old Space (Old Gen)**: 매 default unbounded (--max-old-space-size 제한), promote target.
- **Code Space**: JIT compiled code.
- **Map Space**: Hidden class (V8 maps).
- **Large Object Space**: ≥ ~256KB single object.
- **Read-Only Space**: immutable roots.
### 매 promotion 규칙
- 매 Young Gen에서 minor GC 2번 survive → Old Space promote.
- Large object (≥ kMaxRegularHeapObjectSize, ~256KB) → 직접 Old Space (LOS).
### 매 Major GC (Old Space) 알고리즘
- **Mark-Compact**: full pause, fragmentation 제거.
- **Concurrent Marking** (Orinoco): worker thread가 mark, main thread continue.
- **Incremental Marking**: chunk별 mark, 사이사이 mutator 실행.
- **Lazy Sweeping**: page별로 sweep on demand.
### 매 응용
1. Node.js server — heap profiling으로 leak 추적 (`--inspect`, heapdump).
2. Chrome — DevTools Memory tab의 retained size 분석.
3. Performance tuning — `--max-old-space-size=4096`로 limit 조정.
## 💻 패턴
### Heap snapshot 생성 (Node.js)
```javascript
import { writeHeapSnapshot } from 'node:v8';
import { performance } from 'node:perf_hooks';
process.on('SIGUSR2', () => {
const file = `/tmp/heap-${Date.now()}.heapsnapshot`;
writeHeapSnapshot(file);
console.log('snapshot:', file);
});
// kill -USR2 <pid>
```
### Inspect heap stats
```javascript
import v8 from 'node:v8';
console.log(v8.getHeapSpaceStatistics());
// [ { space_name: 'old_space', space_size, space_used_size, ... } ]
console.log(v8.getHeapStatistics());
// { total_heap_size, used_heap_size, heap_size_limit, ... }
```
### Force GC for measurement (--expose-gc)
```javascript
// node --expose-gc app.js
function measureRetained(fn) {
global.gc(); global.gc();
const before = process.memoryUsage().heapUsed;
const ref = fn();
global.gc(); global.gc();
const after = process.memoryUsage().heapUsed;
return { ref, retained: after - before };
}
```
### Trace GC events
```bash
node --trace-gc --trace-gc-verbose app.js
# [12345:0x...] [GC] 100ms: 50.0 (60.0) -> 30.0 (60.0) MB (Mark-Sweep) ...
```
### Monitor old space in production (Prometheus)
```javascript
import client from 'prom-client';
import v8 from 'node:v8';
const oldSpaceUsed = new client.Gauge({
name: 'nodejs_v8_old_space_used_bytes',
help: 'V8 old space used',
});
setInterval(() => {
const old = v8.getHeapSpaceStatistics()
.find(s => s.space_name === 'old_space');
oldSpaceUsed.set(old.space_used_size);
}, 5000);
```
### Avoid old-space leak — WeakRef / WeakMap for cache
```javascript
const cache = new WeakMap(); // key not retained
function compute(obj) {
if (cache.has(obj)) return cache.get(obj);
const v = expensive(obj);
cache.set(obj, v);
return v;
}
// obj GC'd → cache entry auto-removed
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Suspected memory leak | heap snapshot diff |
| OOM under load | `--max-old-space-size=` increase + investigate |
| Frequent major GC pause | reduce promotion rate (avoid long-lived churn) |
| Cache growing forever | WeakMap / LRU bound |
| Need pre-prod heap profile | `--inspect` + DevTools |
**기본값**: 매 default V8 settings — limit 변경은 측정 후.
## 🔗 Graph
- 부모: [[V8_엔진_힙_아키텍처|V8 Heap Architecture]] · [[Garbage_Collection]]
- 변형: [[Mark-Sweep]] · [[Incremental_Marking]] · [[Generational_Hypothesis]]
- 응용: [[Orinoco]] · [[Pointer_Compression]] · [[Memory_Leaks]]
- Adjacent: [[Write Barrier|Write_Barrier]] · [[Snapshots]] · [[Reachability_Analysis]]
## 🤖 LLM 활용
**언제**: Node.js memory issue 분석, heap profiling, V8 internals 학습, GC tuning.
**언제 X**: non-V8 runtime (Bun-JSC, Deno-V8 다르지만 비슷, Hermes는 별도), browser-only DOM leak (different territory).
## ❌ 안티패턴
- **Forgotten timer/listener**: 매 closure가 old space에 retain.
- **Global cache without bound**: 매 monotonic growth → OOM.
- **Large allocation in hot loop**: Young → Old promotion 폭증, frequent major GC.
- **String concat in loop without builder**: 매 intermediate retained.
- **`--max-old-space-size` blindly raised**: 매 leak hide, root cause 회피.
## 🧪 검증 / 중복
- Verified (V8 source `v8/src/heap/`, V8 blog Orinoco posts, Node.js v8 module docs 2026).
- 신뢰도 A.
- Duplicates: `Old_Space(Old_Generation).md` redirects here.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — canonical V8 Old Space doc + heap profiling patterns |
@@ -0,0 +1,140 @@
---
id: wiki-2026-0508-orinoco
title: Orinoco (V8 GC project)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [V8 Orinoco, Orinoco GC, Concurrent V8 GC]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [v8, gc, performance, concurrent-marking, runtime]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: cpp
framework: v8
---
# Orinoco
## 매 한 줄
> **"매 V8의 GC를 stop-the-world에서 incremental · concurrent · parallel multi-threaded GC로 전환한 multi-year 프로젝트."**. 2016년 시작, 2017-2019 Concurrent Marking · Parallel Scavenger · Lazy Sweeping 차례 도입. 2026 현재 V8 13.x base GC architecture가 Orinoco — pause time을 100ms+ → <1ms로 감소.
## 매 핵심
### 매 핵심 기법
- **Parallel Scavenger** (Young Gen): 매 multiple worker가 semi-space copy 병렬화.
- **Concurrent Marking** (Old Gen): 매 worker thread가 mutator와 병행 mark — main thread는 거의 미 pause.
- **Incremental Marking**: 매 mark phase를 여러 작은 chunk로 나눔.
- **Parallel/Concurrent Compaction**: page별 evacuation 병렬화.
- **Lazy Sweeping**: 매 sweep을 allocation 시점까지 지연.
- **Black Allocation**: 매 marking 중 새 alloc은 black (skip).
### 매 write barrier 역할
- 매 mutator가 마크된 object → 비마크 object 참조 추가 시 dirty card 표시.
- 매 concurrent marker가 stale graph 처리.
### 매 응용
1. Chrome — main thread jank 감소, smooth 60fps scroll.
2. Node.js — large heap server에서 long pause 제거.
3. Electron/VSCode — GUI responsiveness 유지.
## 💻 패턴
### Orinoco effect 측정 (Node.js)
```bash
# Major GC pause 분포
node --trace-gc --trace-gc-verbose app.js 2>&1 \
| grep "Mark-" | awk '{print $5}' \
| sort -n | uniq -c
# 2026 V8: 대부분 < 1ms, occasional 5ms
```
### Disable concurrent marking (compare)
```bash
node --no-concurrent-marking --trace-gc app.js
# pause time 명백히 증가 (10-50ms 종종)
```
### Per-isolate GC stats
```javascript
import { getHeapStatistics } from 'node:v8';
const before = getHeapStatistics();
heavyWorkload();
const after = getHeapStatistics();
console.log('major_gc count:', after.number_of_native_contexts);
console.log('used:', (after.used_heap_size - before.used_heap_size) / 1e6, 'MB');
```
### Performance.measureUserAgentSpecificMemory (Chrome)
```javascript
// In Chrome with COOP+COEP
if (performance.measureUserAgentSpecificMemory) {
const result = await performance.measureUserAgentSpecificMemory();
console.log(result.bytes, result.breakdown);
}
```
### Reduce concurrent-marking pressure
```javascript
// Avoid: huge graph mutation in tight loop
function reseat(arr, n) {
for (let i = 0; i < n; i++) arr[i] = { ref: arr[(i+1) % n] };
// many write barriers → marker work spike
}
// Prefer: build once, freeze
const frozen = Object.freeze(buildGraph());
```
### Inspect GC marking phase via perf_hooks
```javascript
import { PerformanceObserver } from 'node:perf_hooks';
const obs = new PerformanceObserver(list => {
for (const e of list.getEntriesByType('gc')) {
if (e.detail.kind === 2 /* MARK_SWEEP_COMPACT */)
console.log('major GC:', e.duration.toFixed(2), 'ms');
}
});
obs.observe({ entryTypes: ['gc'] });
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Long pause complaint (UI jank) | check Orinoco enabled (default), profile |
| Embedded V8 (custom flags) | enable concurrent + incremental marking |
| Constrained memory (IoT) | might disable concurrent (extra worker thread) |
| Benchmarking | report w/ default flags + GC trace |
**기본값**: 매 default flags (Orinoco on) — 매 manual disable 회피.
## 🔗 Graph
- 부모: [[Garbage_Collection]] · [[V8_엔진_힙_아키텍처|V8 Heap Architecture]]
- 변형: [[Incremental_Marking]] · [[Concurrent_Marking]] · [[Mark-Sweep]]
- 응용: [[Old_Space]] · [[Pointer_Compression]] · [[Write Barrier|Write_Barrier]]
- Adjacent: [[Generational_Hypothesis]] · [[Snapshots]] · [[Multi-threaded Architecture]]
## 🤖 LLM 활용
**언제**: V8 GC internals 학습, Node.js/Chrome perf 분석, GC pause 회귀 추적.
**언제 X**: non-V8 runtime (Hermes는 별도 GC), Java/Go GC (G1/ZGC/Shenandoah는 다른 design).
## ❌ 안티패턴
- **Disabling concurrent marking blindly**: 매 measurement 없이 — 보통 perf 악화.
- **Huge mutation in hot loop**: 매 write barrier overload.
- **Forcing `global.gc()` 빈번**: 매 production 절대 X — Orinoco가 알아서 함.
- **Confusing minor (scavenge) and major (mark-sweep)**: 매 trace 해석 오류.
## 🧪 검증 / 중복
- Verified (V8 blog "Orinoco" series 2016-2019, V8 source `src/heap/`, Mathias Bynens & Benedikt Meurer talks 2017-2020).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Orinoco GC project (concurrent/parallel/incremental) |
@@ -0,0 +1,146 @@
---
id: wiki-2026-0508-polymorphism-다형성
title: Polymorphism (다형성)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Polymorphism, 다형성, Polymorphism in Engine Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [oop, type-system, design, architecture]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python-cpp-rust
framework: oop
---
# Polymorphism (다형성)
## 매 한 줄
> **"매 same interface, 매 different behavior"**. Polymorphism은 매 하나의 symbol/call-site가 매 runtime 또는 compile-time에 매 여러 type에 대해 매 적절히 dispatch되는 매 type-system property. 매 1967 Strachey 분류 (parametric / ad-hoc) 이후 매 OOP / functional / trait-based 모든 paradigm의 매 backbone.
## 매 핵심
### 매 4가지 form
- **매 Subtype (inclusion)**: 매 `Animal a = new Dog()` — 매 Liskov Substitution.
- **매 Parametric (generic)**: 매 `List<T>`, 매 `fn id<T>(x: T) -> T`.
- **매 Ad-hoc (overloading)**: 매 `f(int)` vs 매 `f(string)` — 매 compile-time dispatch.
- **매 Coercion**: 매 `int → float` 매 implicit conversion.
### 매 Dispatch 축
- **Single dispatch**: 매 receiver type 하나로 결정 (Java, Python).
- **Multiple dispatch**: 매 모든 argument type으로 결정 (Julia, CLOS).
- **Static**: 매 compile-time (templates, traits with monomorphization).
- **Dynamic**: 매 runtime (vtable, duck typing).
### 매 응용
1. Engine architecture: `Renderer` interface → `VulkanRenderer` / `MetalRenderer`.
2. Generic containers: `Vec<T>` / `HashMap<K,V>`.
3. Strategy pattern: `Sorter` 매 inject 다른 algorithm.
## 💻 패턴
### Subtype polymorphism (Python)
```python
from abc import ABC, abstractmethod
class Renderer(ABC):
@abstractmethod
def draw(self, scene): ...
class VulkanRenderer(Renderer):
def draw(self, scene): scene.submit_vulkan()
class MetalRenderer(Renderer):
def draw(self, scene): scene.submit_metal()
def render(r: Renderer, s): r.draw(s)
```
### Parametric (Rust generics + monomorphization)
```rust
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list { if item > largest { largest = item; } }
largest
}
// Compiler emits largest_i32, largest_f64, ... — zero-cost.
```
### Ad-hoc (C++ overloading)
```cpp
int f(int x) { return x * 2; }
auto f(double x) { return x + 0.5; }
auto f(std::string s){ return s + "!"; }
```
### Multiple dispatch (Julia)
```julia
collide(a::Asteroid, b::Asteroid) = "rock-rock"
collide(a::Asteroid, b::Ship) = "ship dies"
collide(a::Ship, b::Ship) = "fleet battle"
collide(Asteroid(), Ship()) # → "ship dies"
```
### Trait objects (Rust dynamic dispatch)
```rust
trait Draw { fn draw(&self); }
let shapes: Vec<Box<dyn Draw>> = vec![Box::new(Circle), Box::new(Square)];
for s in &shapes { s.draw(); } // vtable lookup
```
### Duck typing (Python)
```python
class File: def read(self): return "file"
class Network: def read(self): return "net"
def consume(src): print(src.read()) # 매 .read() 있으면 OK
```
### Type class (Haskell)
```haskell
class Eq a where
(==) :: a -> a -> Bool
instance Eq Int where x == y = ...
instance Eq String where x == y = ...
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 hot loop, 매 known types | Parametric (monomorphized) |
| 매 plugin / extension point | Subtype (dyn / interface) |
| 매 numeric tower, 매 binary op | Multiple dispatch |
| 매 internal lib | Duck typing / structural |
**기본값**: Parametric for libraries, subtype for extension points.
## 🔗 Graph
- 부모: [[TypeScript 타입 시스템 (TypeScript Type System)|Type-System]] · [[OOP]]
- 변형: [[Parametric-Polymorphism]]
- Adjacent: [[Duck-Typing]]
## 🤖 LLM 활용
**언제**: API 설계, refactoring 시 dispatch 선택, 매 generic vs interface 결정.
**언제 X**: 매 단일 type의 simple script (overengineering).
## ❌ 안티패턴
- **매 Type-checking ladder**: 매 `if isinstance(x, A): ... elif isinstance(x, B):` 매 dispatch 회피.
- **매 Deep inheritance**: 매 5+ level subtype tree → composition 으로 대체.
- **매 dyn 남용**: 매 hot path 매 vtable 매 overhead.
- **매 Yo-yo problem**: 매 method override가 매 subclass-superclass 매 ping-pong.
## 🧪 검증 / 중복
- Verified (Cardelli & Wegner 1985, Pierce "Types and Programming Languages" 2002).
- 신뢰도 A.
- 중복: [[Polymorphism (다형성)|Polymorphism-in-Engine-Architecture]] redirects here.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 4 forms + dispatch axes + working examples |
@@ -0,0 +1,136 @@
---
id: wiki-2026-0508-problem-solving-skills
title: Problem Solving Skills
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Problem Solving, 문제 해결 능력, debugging skills]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [meta, debugging, engineering, methodology]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: meta
framework: methodology
---
# Problem Solving Skills
## 매 한 줄
> **"매 problem 정의가 매 solution의 매 절반"**. Problem solving은 매 ill-defined situation을 매 well-defined sub-problems으로 매 decompose하고 매 hypothesis-test loop으로 매 narrow down하는 매 transferable skill set. Polya (1945) 4-step부터 매 modern debugging 까지 매 동일한 backbone.
## 매 핵심
### 매 Polya 4-step (1945)
1. **Understand**: 매 input/output/constraint 매 명시.
2. **Plan**: 매 known similar problem과 매 mapping.
3. **Execute**: 매 plan 매 step-by-step.
4. **Review**: 매 result verify, 매 generalize.
### 매 Debugging 전용 loop
- **매 Reproduce**: 매 minimal repro case.
- **매 Bisect**: 매 git bisect / binary search.
- **매 Hypothesize**: 매 1개 변수만 매 변경.
- **매 Verify**: 매 test 매 추가.
- **매 Postmortem**: 매 root cause + prevention.
### 매 응용
1. Production incident response (5-why).
2. Algorithm design (decomposition + invariants).
3. LLM prompt debugging (delta isolation).
## 💻 패턴
### Minimal repro extraction
```python
# Bisect a failing input down to minimal case
def minimal_repro(input_list, fails):
while True:
for i in range(len(input_list)):
candidate = input_list[:i] + input_list[i+1:]
if fails(candidate):
input_list = candidate
break
else:
return input_list
```
### Git bisect automation
```bash
git bisect start HEAD v1.0.0
git bisect run pytest tests/test_regression.py::test_bug
# 매 Bisect 자동 종료 → first-bad-commit 매 출력
```
### 5-why root cause
```yaml
# postmortem.yaml
incident: api 500 spike
why_1: db connections exhausted
why_2: connection leak in /search handler
why_3: exception bypassed `with` cleanup
why_4: custom context manager swallowed asyncio.CancelledError
why_5: copy-pasted snippet from Stack Overflow without review
fix: replace with asynccontextmanager + add lint rule
```
### Hypothesis-driven test
```python
# Change ONE variable per iteration
import time
def measure(config):
t = time.time(); run(config); return time.time() - t
base = {"batch": 32, "workers": 4, "cache": True}
for k in base:
cfg = {**base, k: not base[k] if isinstance(base[k], bool) else base[k]*2}
print(k, measure(cfg))
```
### Rubber-duck logger
```python
def trace_state(label, **vars):
print(f"[{label}]", " | ".join(f"{k}={v!r}" for k, v in vars.items()))
trace_state("before-loop", i=0, total=len(data), seen=set())
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Bug 매 reproducible | Bisect + minimal repro |
| Bug 매 intermittent | Logging + statistical test |
| Algorithm 매 unknown | Polya + analogy from known |
| Production incident | 5-why + postmortem |
**기본값**: Reproduce → Bisect → Hypothesize → Verify → Document.
## 🔗 Graph
- 부모: [[Debugging]]
- 변형: [[Polya-Method]] · [[Bisect]]
- 응용: [[Postmortem]]
- Adjacent: [[Scientific-Method]]
## 🤖 LLM 활용
**언제**: 매 ill-defined task decomposition, 매 stuck-state escape, 매 LLM prompt 디버깅.
**언제 X**: 매 trivial 1-line typo (overhead).
## ❌ 안티패턴
- **매 Shotgun debugging**: 매 random 변경 후 매 동작하면 commit.
- **매 Symptom-only fix**: 매 root cause 무시.
- **매 No repro**: 매 "내 환경에선 됨".
- **매 Heisenbug 회피**: 매 logging 추가하면 매 사라지는 bug 매 무시.
## 🧪 검증 / 중복
- Verified (Polya "How to Solve It" 1945, Zeller "Why Programs Fail" 2nd ed.).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Polya + debugging loop + repro/bisect patterns |
@@ -0,0 +1,181 @@
---
id: wiki-2026-0508-publish-subscribe-model
title: Publish-Subscribe Model
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Pub-Sub, Pub/Sub, Topic-Based Messaging]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [messaging, eda, distributed-systems, pattern]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: kafka-redis-nats
---
# Publish-Subscribe Model
## 매 한 줄
> **"매 publisher 매 subscribers 매 모름 — 매 topic / channel 매 통해 매 decoupled broadcast"**. 1987 ISIS Toolkit 매 origin, 매 today Kafka / Redis Pub/Sub / NATS / Google Pub/Sub / AWS SNS 매 ubiquitous backbone.
## 매 핵심
### 매 model variants
- **Topic-based**: 매 logical channel name (e.g. `orders.created`).
- **Content-based**: 매 message attributes 매 filter — 매 RabbitMQ headers exchange.
- **Type-based**: 매 message class hierarchy.
- **Hybrid**: 매 topic + filter (NATS subject wildcards `orders.*.created`).
### 매 delivery semantics
- **At-most-once**: fire-and-forget (Redis Pub/Sub).
- **At-least-once**: ack required (Kafka, SQS).
- **Exactly-once**: 매 idempotent + transactional (Kafka EOS, Pulsar).
### 매 응용
1. Event-driven microservices (orders → fulfillment, billing, notifications).
2. Real-time dashboards (Grafana Live, websocket fanout).
3. CDC (Debezium → Kafka → consumers).
4. IoT telemetry (MQTT — pub-sub variant).
## 💻 패턴
### In-process pub-sub (Python)
```python
from collections import defaultdict
from typing import Callable
class Bus:
def __init__(self):
self.subs: dict[str, list[Callable]] = defaultdict(list)
def subscribe(self, topic, fn): self.subs[topic].append(fn)
def publish(self, topic, msg):
for fn in self.subs[topic]:
fn(msg)
bus = Bus()
bus.subscribe("user.created", lambda u: print(f"welcome {u}"))
bus.publish("user.created", "alice")
```
### Redis Pub/Sub
```python
import redis, json
r = redis.Redis()
# Publisher
r.publish("orders.created", json.dumps({"id": 42, "total": 99}))
# Subscriber
ps = r.pubsub()
ps.subscribe("orders.*")
for msg in ps.listen():
if msg["type"] == "pmessage":
handle(json.loads(msg["data"]))
```
### Kafka producer/consumer (Python)
```python
from confluent_kafka import Producer, Consumer
p = Producer({"bootstrap.servers": "localhost:9092"})
p.produce("orders", key="42", value=b'{"total":99}')
p.flush()
c = Consumer({
"bootstrap.servers": "localhost:9092",
"group.id": "fulfillment",
"auto.offset.reset": "earliest",
})
c.subscribe(["orders"])
while True:
msg = c.poll(1.0)
if msg and not msg.error():
process(msg.value())
c.commit(msg)
```
### NATS with subject wildcards
```python
import nats, asyncio
async def main():
nc = await nats.connect("nats://localhost:4222")
async def cb(msg): print(msg.subject, msg.data)
await nc.subscribe("orders.*.created", cb=cb)
await nc.publish("orders.US.created", b'{"id":42}')
await asyncio.sleep(1)
asyncio.run(main())
```
### Google Cloud Pub/Sub
```python
from google.cloud import pubsub_v1
publisher = pubsub_v1.PublisherClient()
topic = publisher.topic_path("proj", "orders")
publisher.publish(topic, b'{"id":42}', region="us-east1")
sub = pubsub_v1.SubscriberClient()
sub_path = sub.subscription_path("proj", "fulfillment-sub")
def cb(msg): handle(msg.data); msg.ack()
sub.subscribe(sub_path, callback=cb).result()
```
### AsyncAPI schema (governance, 2026)
```yaml
asyncapi: 3.0.0
channels:
ordersCreated:
address: orders.created
messages:
OrderCreated:
payload:
type: object
properties:
id: {type: integer}
total: {type: number}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 in-process | Bus / EventEmitter |
| 매 ephemeral, low-latency | Redis Pub/Sub / NATS |
| 매 durable, replay 필요 | Kafka / Pulsar |
| 매 cloud-native, managed | Google Pub/Sub / AWS SNS+SQS |
| 매 IoT / mobile | MQTT |
| 매 fan-in-out, transform | Kafka Streams / Pulsar Functions |
**기본값**: 매 production EDA — Kafka. 매 simple/ephemeral — NATS.
## 🔗 Graph
- 부모: [[Event Driven Architecture]]
- 변형: [[Observer Pattern]] · [[Event Bus]]
- 응용: [[Event Sourcing]] · [[CQRS]] · [[CDC]]
- Adjacent: [[Kafka]] · [[NATS]] · [[Redis]] · [[MQTT]]
## 🤖 LLM 활용
**언제**: 매 schema design (AsyncAPI generation), 매 consumer code scaffolding, 매 dead-letter analysis.
**언제 X**: 매 broker selection 매 trust 의 X — workload metrics 직접 측정.
## ❌ 안티패턴
- **Sync pub-sub**: 매 publisher block on slow subscriber — 매 async / queue 사용.
- **No schema**: 매 consumer breakage — Avro/Protobuf + registry 필수.
- **Topic explosion**: 매 user-per-topic — 매 millions of topics, broker 죽음. 매 partition / filter 사용.
- **Duplicate semantics**: 매 at-least-once 인데 매 idempotency 없음 — duplicate processing.
## 🧪 검증 / 중복
- Verified (Eugster et al. — "The Many Faces of Publish/Subscribe" 2003; Kafka docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full pub-sub pattern entry |
@@ -0,0 +1,183 @@
---
id: wiki-2026-0508-real-time-data-streaming
title: Real-time Data Streaming
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Stream Processing, Event Streaming, Real-time Pipelines]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [streaming, kafka, pulsar, flink, data-engineering]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: kafka-flink-pulsar
---
# Real-time Data Streaming
## 매 한 줄
> **"매 batch ETL 의 X — 매 unbounded events 매 milliseconds latency 매 process"**. Kafka (LinkedIn 2010) → Flink / Spark Structured Streaming / Pulsar / Materialize / RisingWave 매 modern stack. 매 2026 매 sub-second analytics 매 default.
## 매 핵심
### 매 layers
- **Ingest**: Kafka, Pulsar, Kinesis, Redpanda — 매 durable log.
- **Process**: Flink, Spark Streaming, Kafka Streams, Bytewax, Arroyo.
- **Serve**: Materialize, RisingWave, Pinot, Druid, ClickHouse.
### 매 windowing
- **Tumbling**: fixed, non-overlapping (1-min buckets).
- **Sliding**: overlapping (5-min, slide 1-min).
- **Session**: gap-based (user activity until 30s inactivity).
- **Hopping**: same as sliding (different name).
### 매 time semantics
- **Event time**: 매 actual occurrence — 매 correctness 위해 default.
- **Processing time**: 매 broker arrival — 매 latency 측정.
- **Ingestion time**: 매 broker append.
- **Watermarks**: 매 lateness threshold — Flink/Beam 핵심.
### 매 응용
1. Fraud detection — 매 payment stream + ML inference.
2. Real-time dashboards — Materialize + Grafana.
3. CDC pipelines — Debezium → Kafka → warehouse.
4. IoT telemetry — MQTT → Kafka → anomaly detection.
5. Personalization — clickstream → feature store → model.
## 💻 패턴
### Kafka Streams (Python via Faust / Bytewax)
```python
import bytewax.operators as op
from bytewax.dataflow import Dataflow
from bytewax.connectors.kafka import KafkaSource, KafkaSink
flow = Dataflow("fraud")
src = op.input("in", flow, KafkaSource(["localhost:9092"], ["payments"]))
parsed = op.map("parse", src, lambda kv: json.loads(kv.value))
flagged = op.filter("flag", parsed, lambda p: p["amount"] > 10000)
op.output("out", flagged, KafkaSink(["localhost:9092"], "alerts"))
```
### Flink SQL (windowed aggregation)
```sql
CREATE TABLE clicks (
user_id STRING, ts TIMESTAMP(3),
WATERMARK FOR ts AS ts - INTERVAL '5' SECOND
) WITH ('connector' = 'kafka', ...);
SELECT
user_id,
TUMBLE_START(ts, INTERVAL '1' MINUTE) AS w_start,
COUNT(*) AS clicks
FROM clicks
GROUP BY user_id, TUMBLE(ts, INTERVAL '1' MINUTE);
```
### Materialize (streaming SQL view)
```sql
CREATE SOURCE orders FROM KAFKA BROKER 'kafka:9092' TOPIC 'orders'
FORMAT AVRO USING SCHEMA REGISTRY 'http://sr:8081';
CREATE MATERIALIZED VIEW revenue_5min AS
SELECT
date_trunc('minute', ts) AS minute,
SUM(amount) AS revenue
FROM orders
WHERE ts > now() - INTERVAL '5 minutes'
GROUP BY 1;
-- Subscribe to changes
SUBSCRIBE TO revenue_5min;
```
### Spark Structured Streaming
```python
df = (spark.readStream.format("kafka")
.option("subscribe", "events")
.load())
agg = (df.selectExpr("CAST(value AS STRING) as json")
.select(from_json("json", schema).alias("e"))
.withWatermark("e.ts", "10 minutes")
.groupBy(window("e.ts", "1 minute"), "e.user")
.count())
agg.writeStream.format("delta").outputMode("append").start("/lake/agg")
```
### Pulsar Functions (lightweight processing)
```python
from pulsar import Function
class EnrichOrder(Function):
def process(self, msg, ctx):
order = json.loads(msg)
order["region"] = lookup_region(order["zip"])
ctx.publish("orders.enriched", json.dumps(order))
```
### Exactly-once with Kafka transactions
```python
producer = KafkaProducer(transactional_id="tx-1", enable_idempotence=True)
producer.init_transactions()
try:
producer.begin_transaction()
producer.send("out", value=processed)
producer.send_offsets_to_transaction(offsets, group_id)
producer.commit_transaction()
except:
producer.abort_transaction()
```
### CDC with Debezium
```yaml
# connector config
connector.class: io.debezium.connector.postgresql.PostgresConnector
database.hostname: pg
table.include.list: public.orders
plugin.name: pgoutput
# emits CDC events to Kafka topic "pg.public.orders"
```
## 매 결정 기준
| 상황 | Stack |
|---|---|
| 매 simple transform | Kafka Streams / Bytewax |
| 매 complex windowing, joins | Flink |
| 매 SQL-first analytics | Materialize / RisingWave |
| 매 batch+stream unified | Spark Structured / Beam |
| 매 lightweight, serverless | Pulsar Functions / AWS Lambda |
| 매 OLAP serving | Pinot / Druid / ClickHouse |
**기본값**: 매 2026 매 SQL-on-streams (Materialize/RisingWave) 매 default — DX 압도적.
## 🔗 Graph
- 부모: [[Data Engineering]] · [[Event Driven Architecture]]
- 변형: [[Stream-Processing-Architectures|Stream Processing]] · [[CEP]]
- 응용: [[CDC]]
- Adjacent: [[Kafka]] · [[Materialize]]
## 🤖 LLM 활용
**언제**: 매 SQL DDL/query generation, 매 schema evolution analysis, 매 anomaly investigation summarization.
**언제 X**: 매 latency-critical hot path — LLM inference 매 too slow. 매 trained ML model 사용.
## ❌ 안티패턴
- **Processing time everywhere**: 매 out-of-order events 매 wrong results — event time + watermarks 사용.
- **Unbounded state**: 매 keyed state 매 grows forever — TTL / windows 필수.
- **Tiny files**: 매 1 record / file → S3 explosion. 매 batching + compaction.
- **Sync external calls in pipeline**: 매 backpressure 폭발. 매 async + bulkhead.
- **No replay strategy**: 매 bad code → poisoned downstream. 매 reset offset + idempotent sinks.
## 🧪 검증 / 중복
- Verified (Akidau — "Streaming 101/102"; Kafka docs; Flink docs 1.18+).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full streaming entry with Materialize/RisingWave |
@@ -0,0 +1,205 @@
---
id: wiki-2026-0508-render-props
title: Render Props
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Function as Child, Children as Function, FaCC]
duplicate_of: none
source_trust_level: A
confidence_score: 0.88
verification_status: applied
tags: [react, pattern, component, composition, frontend]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: React 19
---
# Render Props
## 매 한 줄
> **"매 component 가 prop 으로 받은 function 을 호출해 무엇을 render 할지 결정"**. Michael Jackson 이 popularize 한 React 합성 패턴 (2017). 2018 Hooks 등장 후 매 logic-sharing 용도는 대부분 custom hook 으로 대체되었지만, 매 *render-time data injection* (animation, virtualization, headless UI) 에서는 매 2026 까지도 first-class 도구.
## 매 핵심
### 매 정의
- 매 component 가 호출자에게 *어떻게 render 할지* 의 control 을 위임.
- Function-typed prop (`children` 또는 `render`) 이 state/computation 을 인자로 받아 ReactNode 반환.
- 매 inversion of control — provider 는 logic, consumer 는 view.
### 매 Hooks 와 의 관계
- 매 logic reuse 의 90%: custom hook 이 우월 (no nesting, easier types).
- 매 render-time slot 패턴: render props 가 여전히 적합 — Framer Motion, react-virtual, Radix UI 등.
- 매 headless UI (Headless UI, Radix, Ariakit) 는 render props + compound component 혼합.
### 매 응용
1. Animation: Framer Motion `<AnimatePresence>` children function.
2. Virtualization: TanStack Virtual `<Virtualizer>` row renderer.
3. Form: react-hook-form `<Controller render={...}>`.
4. Headless: Headless UI `<Menu.Item>{({active}) => ...}</Menu.Item>`.
## 💻 패턴
### Basic render prop
```tsx
type MouseTrackerProps = {
render: (state: { x: number; y: number }) => React.ReactNode;
};
function MouseTracker({ render }: MouseTrackerProps) {
const [pos, setPos] = useState({ x: 0, y: 0 });
return (
<div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>
{render(pos)}
</div>
);
}
// usage
<MouseTracker render={({ x, y }) => <p>{x}, {y}</p>} />
```
### Children as function (FaCC)
```tsx
type Props = { children: (state: { x: number; y: number }) => React.ReactNode };
function MouseTracker({ children }: Props) {
const [pos, setPos] = useState({ x: 0, y: 0 });
return <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>{children(pos)}</div>;
}
<MouseTracker>{({ x, y }) => <p>{x}, {y}</p>}</MouseTracker>
```
### TanStack Virtual (real-world 2026)
```tsx
import { useVirtualizer } from '@tanstack/react-virtual';
function List({ items }: { items: string[] }) {
const ref = useRef<HTMLDivElement>(null);
const v = useVirtualizer({
count: items.length,
getScrollElement: () => ref.current,
estimateSize: () => 32,
});
return (
<div ref={ref} style={{ height: 400, overflow: 'auto' }}>
<div style={{ height: v.getTotalSize() }}>
{v.getVirtualItems().map((vi) => (
<div key={vi.key} style={{ transform: `translateY(${vi.start}px)` }}>
{items[vi.index]}
</div>
))}
</div>
</div>
);
}
```
### react-hook-form Controller
```tsx
import { Controller, useForm } from 'react-hook-form';
function Form() {
const { control } = useForm<{ name: string }>();
return (
<Controller
control={control}
name="name"
render={({ field, fieldState }) => (
<input {...field} aria-invalid={!!fieldState.error} />
)}
/>
);
}
```
### Headless UI Menu (compound + render prop)
```tsx
import { Menu } from '@headlessui/react';
<Menu>
<Menu.Button>Options</Menu.Button>
<Menu.Items>
<Menu.Item>
{({ active }) => (
<a className={active ? 'bg-blue-500' : ''} href="/edit">Edit</a>
)}
</Menu.Item>
</Menu.Items>
</Menu>
```
### Generic render prop with typed slot
```tsx
function DataLoader<T>({
url,
children,
}: {
url: string;
children: (s: { data: T | null; loading: boolean; error: Error | null }) => React.ReactNode;
}) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
fetch(url).then(r => r.json()).then(setData).catch(setError).finally(() => setLoading(false));
}, [url]);
return <>{children({ data, loading, error })}</>;
}
```
### Hook equivalent (when to prefer)
```tsx
function useMouse() {
const [pos, setPos] = useState({ x: 0, y: 0 });
const onMouseMove = (e: React.MouseEvent) => setPos({ x: e.clientX, y: e.clientY });
return { pos, onMouseMove };
}
function MyView() {
const { pos, onMouseMove } = useMouse();
return <div onMouseMove={onMouseMove}>{pos.x},{pos.y}</div>;
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Logic 만 공유 | **Custom hook** (default since 2019) |
| DOM/JSX slot 주입 필요 | Render props |
| Generic library (virtualizer, animator) | Render props |
| Headless UI primitive | Render props + compound |
| Class component legacy | Render props (hook 불가) |
**기본값**: 매 hook 우선, 매 render slot 이 진짜 필요할 때만 render props.
## 🔗 Graph
- 부모: [[React Patterns]] · [[Component Composition]]
- 변형: [[Custom Hooks]] · [[Component-Composition|Compound Components]]
- 응용: [[Headless UI]] · [[react-hook-form]]
- Adjacent: [[Inversion of Control]] · [[Slot Pattern]]
## 🤖 LLM 활용
**언제**: 매 library API 설계, 매 generic data-injection slot, 매 animation choreography.
**언제 X**: 매 단순 logic share — hook 으로 충분. 매 callback hell 위험.
## ❌ 안티패턴
- **Render prop hell**: 매 nesting 5단계 — flatten 또는 hook.
- **Inline function in render**: 매 매 render 마다 새 function — child memoization 깨짐, `useCallback` 또는 module-scope.
- **Both `children` and `render`**: 매 ambiguous API — 하나만.
- **Hook 으로 충분한데 render prop**: 매 over-engineering.
- **Type any**: 매 generic slot 의 type erasure — `<T,>` generic 사용.
## 🧪 검증 / 중복
- Verified: React docs (legacy section), TanStack Virtual, react-hook-form, Headless UI 공식 docs (2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — render props vs hooks, real-world 2026 examples |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-rule-of-three-3의-법칙
title: Rule of Three (3의 법칙)
category: 10_Wiki/Topics
status: duplicate
canonical_id: 3의-법칙-rule-of-three
duplicate_of: "[[3의 법칙 (Rule of Three)]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, refactoring, heuristic]
last_reinforced: 2026-05-10
github_commit: pending
---
# Rule of Three (3의 법칙)
> **이 문서는 [[3의 법칙 (Rule of Three)]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- "Three strikes and you refactor" — Don Roberts via Fowler.
- 첫 duplication 은 그대로, 두 번째 는 wince, 세 번째 는 abstract.
- 너무 이른 abstraction (DRY 과잉) 의 antidote — premature generalization 은 wrong abstraction 보다 나쁘다 (Sandi Metz).
## 🔗 Graph
- 부모: [[3의 법칙 (Rule of Three)]] (canonical)
- 인접: [[Refactoring_Best_Practices]] · [[DRY Principle]] · [[Code Smell]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,179 @@
---
id: wiki-2026-0508-spa-라우트-전환-성능-최적화
title: SPA 라우트 전환 성능 최적화
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [SPA route transition perf, route transition optimization, SPA navigation perf]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [frontend, performance, spa, react, routing]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: react
---
# SPA 라우트 전환 성능 최적화
## 매 한 줄
> **"매 route 전환은 매 사용자가 매 가장 자주 만나는 perf moment"**. SPA에서 매 route 전환 latency는 매 INP/Core Web Vitals에 매 직접 영향. 2026년에는 매 React Router 7, TanStack Router, Next 15 App Router가 매 표준이며, 매 streaming + prefetch + view-transitions가 매 키.
## 매 핵심
### 매 병목 분류
- **JS bundle**: 매 새 route chunk download/parse.
- **Data fetch**: 매 loader/query waterfall.
- **Render**: 매 new tree mount cost.
- **Asset**: 매 image/font 신규 load.
### 매 최적화 lever
- **Code-split** (route-level lazy).
- **Prefetch** (hover/viewport/intent).
- **Parallel data load** (loader pattern, no waterfall).
- **View Transitions API** (visual smoothing).
- **RSC streaming** (Next 15 App Router).
### 매 응용
1. 매 e-commerce: product list → detail 매 < 100ms 체감.
2. 매 dashboard: 매 widget data parallel.
3. 매 docs site: 매 instant hover prefetch.
## 💻 패턴
### 매 Route-level code split
```tsx
import { lazy, Suspense } from "react";
const Dashboard = lazy(() => import("./Dashboard"));
<Route path="/dashboard" element={
<Suspense fallback={<Skeleton />}><Dashboard /></Suspense>
} />
```
### 매 Hover prefetch (TanStack Router)
```tsx
import { Link } from "@tanstack/react-router";
<Link to="/products/$id" params={{ id }} preload="intent">
Product
</Link>
// 매 hover/focus → 매 chunk + loader data 미리.
```
### 매 Parallel loaders (waterfall 제거)
```tsx
// X — sequential
const route = createRoute({
loader: async () => {
const user = await fetchUser(); // 매 wait
const orders = await fetchOrders(user.id); // 매 then wait
return { user, orders };
},
});
// O — parallel where possible
const route = createRoute({
loader: async ({ params }) => {
const [user, orders] = await Promise.all([
fetchUser(params.id),
fetchOrdersForId(params.id), // 매 user 의존 X로 변경
]);
return { user, orders };
},
});
```
### 매 View Transitions API
```tsx
// 매 navigation에 매 native cross-fade
import { unstable_ViewTransition as ViewTransition } from "react";
function App() {
return (
<ViewTransition>
<Outlet />
</ViewTransition>
);
}
```
```css
::view-transition-old(root) { animation: fade-out 200ms; }
::view-transition-new(root) { animation: fade-in 200ms; }
```
### 매 RSC streaming (Next 15)
```tsx
// app/products/[id]/page.tsx
export default async function Page({ params }: { params: { id: string } }) {
return (
<>
<ProductHeader id={params.id} /> {/* 매 빠른 part */}
<Suspense fallback={<Skeleton />}>
<ProductReviews id={params.id} /> {/* 매 느린 part stream */}
</Suspense>
</>
);
}
```
### 매 Optimistic navigation
```tsx
// React 19 useOptimistic 응용
const [optimisticPath, setOptimisticPath] = useOptimistic(currentPath);
function navigate(to: string) {
startTransition(() => {
setOptimisticPath(to); // 매 즉시 UI 변경
router.navigate(to);
});
}
```
### 매 Bundle 분석 (rsdoctor / webpack-bundle-analyzer)
```bash
pnpm dlx @rsdoctor/cli analyze
# 매 route chunk 크기 매 visualize → 매 split point 매 결정
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 small SPA | Route-split + hover prefetch. |
| 매 dashboard 다중 widget | Parallel loaders + Suspense streaming. |
| 매 SEO + perf | Next 15 App Router (RSC). |
| 매 highly interactive | TanStack Router + View Transitions. |
| 매 mobile-first | Aggressive prefetch는 매 신중 (data cost). |
**기본값**: Route-split + intent prefetch + parallel loaders. 매 modern routers는 매 default support.
## 🔗 Graph
- 부모: [[SPA]] · [[Web Performance]]
- 변형: [[Islands Architecture]]
- 응용: [[TanStack Router]]
- Adjacent: [[Core Web Vitals Optimization (INP, LCP 개선)|Core Web Vitals]] · [[INP]] · [[View Transitions]] · [[Code Splitting]]
## 🤖 LLM 활용
**언제**: 매 route 전환 매 느릴 때, 매 perf budget 책정, 매 prefetch 전략 설계.
**언제 X**: 매 MPA, 매 first-load 문제 (매 SSR/SSG 별도).
## ❌ 안티패턴
- **매 lazy 모든 component**: 매 too granular → 매 waterfall 악화.
- **매 prefetch 모든 link**: 매 모바일 데이터 burn.
- **매 loader에 매 sequential await**: 매 waterfall.
- **매 Suspense 없이 매 lazy**: 매 blank 화면.
- **매 view-transition 만 적용**: 매 underlying perf 안 고치고 cosmetic만.
## 🧪 검증 / 중복
- Verified (web.dev, React Router 7 docs, TanStack Router docs, Next 15 docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 2026 router stack + View Transitions + RSC streaming |
@@ -0,0 +1,177 @@
---
id: wiki-2026-0508-scalability
title: Scalability
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Scalability, 확장성, scale-out, scale-up]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, distributed-systems, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: yaml
framework: kubernetes
---
# Scalability
## 매 한 줄
> **"매 부하가 늘 때 매 graceful하게 capacity를 키울 수 있는 능력"**. Scalability는 매 단일 dimension(traffic, data, compute)이 아니라 매 multi-axis property. 2026년에는 매 K8s HPA + KEDA, 매 serverless auto-scale, 매 LLM token-throughput scaling이 매 일상.
## 매 핵심
### 매 두 축
- **Vertical (scale-up)**: 매 큰 머신 — 매 limit 빨리.
- **Horizontal (scale-out)**: 매 더 많은 머신 — 매 stateless 필요.
### 매 차원
- **Load**: req/sec.
- **Data**: GB → PB.
- **Geographic**: 매 region.
- **User**: 매 동시 user.
- **Functional**: 매 feature 추가가 매 system을 깨지 않음.
### 매 응용
1. 매 web tier — auto-scale group.
2. 매 DB — sharding / read replica.
3. 매 LLM serving — vLLM tensor parallel + KV cache 분산.
4. 매 event pipeline — Kafka partition scale.
## 💻 패턴
### 매 K8s HPA (CPU 기반)
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata: { name: api-hpa }
spec:
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: api }
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target: { type: Utilization, averageUtilization: 70 }
```
### 매 KEDA (event-driven scale)
```yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata: { name: kafka-consumer }
spec:
scaleTargetRef: { name: consumer }
minReplicaCount: 0
maxReplicaCount: 100
triggers:
- type: kafka
metadata:
bootstrapServers: kafka:9092
consumerGroup: orders
topic: order-events
lagThreshold: "100"
```
### 매 Stateless service (scale-out 가능)
```typescript
// 매 session 매 외부화 (Redis)
import express from "express";
import session from "express-session";
import RedisStore from "connect-redis";
import { createClient } from "redis";
const redis = createClient({ url: "redis://redis:6379" });
await redis.connect();
const app = express();
app.use(session({
store: new RedisStore({ client: redis }),
secret: process.env.SESSION_SECRET!,
resave: false, saveUninitialized: false,
}));
// 매 어느 instance든 매 동일 session.
```
### 매 DB sharding (hash-based)
```typescript
function shardFor(userId: string): string {
const hash = crc32(userId);
return `db-shard-${hash % 8}`;
}
async function getUser(id: string) {
const shard = shardFor(id);
return pool[shard].query("SELECT * FROM users WHERE id=$1", [id]);
}
```
### 매 Read replica
```typescript
const writeDb = postgres({ host: "primary" });
const readDb = postgres({ host: "replica.read" });
async function placeOrder(o: Order) { return writeDb`INSERT INTO orders ...`; }
async function listOrders(uid: string) { return readDb`SELECT * FROM orders WHERE uid=${uid}`; }
```
### 매 LLM tensor-parallel (vLLM 0.7+)
```bash
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--tensor-parallel-size 4 \
--gpu-memory-utilization 0.92 \
--max-num-seqs 256
```
### 매 Cache layer (scale read)
```typescript
async function getProduct(id: string) {
const cached = await redis.get(`p:${id}`);
if (cached) return JSON.parse(cached);
const p = await db.query("SELECT * FROM products WHERE id=$1", [id]);
await redis.setex(`p:${id}`, 60, JSON.stringify(p));
return p;
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 traffic spike (예측 가능) | HPA + capacity planning. |
| 매 burst (predicate X) | Serverless / KEDA scale-to-zero. |
| 매 data > single node | Sharding. |
| 매 read >> write | Replica. |
| 매 global users | Multi-region + edge cache. |
| 매 LLM serving | vLLM TP + KV-cache routing. |
**기본값**: 매 stateless service + HPA + Redis cache + read replica.
## 🔗 Graph
- 부모: [[Distributed Systems]]
- 응용: [[Microservices]] · [[Serverless_Architecture]] · [[Service Mesh]]
- Adjacent: [[CAP Theorem]] · [[Sharding]] · [[Load Balancer]]
## 🤖 LLM 활용
**언제**: 매 capacity 설계, 매 bottleneck 진단, 매 cost-perf trade-off.
**언제 X**: 매 단일 user 매 internal tool (매 over-engineering).
## ❌ 안티패턴
- **매 premature sharding**: 매 single PG로 매 충분한데 매 split.
- **매 stateful pod scale-out**: 매 session 매 일부 instance 만.
- **매 cache stampede 무시**: 매 expiry 동시에.
- **매 N+1 query에서 scale-out 으로 도망**: 매 query 먼저 고칠 것.
- **매 monolith 만 scale-up**: 매 vertical 한계.
## 🧪 검증 / 중복
- Verified (Designing Data-Intensive Applications, K8s docs, vLLM docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — HPA/KEDA/sharding/vLLM patterns |
@@ -0,0 +1,171 @@
---
id: wiki-2026-0508-simple-event-processing
title: Simple Event Processing
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [SEP, Direct Event Handling, 1:1 Event Processing]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [event-driven, architecture, eda, messaging]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: kafka
---
# Simple Event Processing
## 매 한 줄
> **"매 1 event → 1 reaction. No correlation, no aggregation, no temporal pattern."**. 매 EDA 의 simplest tier — notable event 의 detect 후 매 single downstream action 의 trigger. 매 CEP (Complex Event Processing) / ESP (Event Stream Processing) 와 대비되는 매 baseline pattern.
## 매 핵심
### 매 SEP vs ESP vs CEP
- **SEP**: 1 event → 1 action. No state, no correlation.
- **ESP**: stream 의 windowing, aggregation (Flink, Kafka Streams).
- **CEP**: pattern matching across events (Drools Fusion, Esper).
### 매 properties
- Stateless (매 event 의 self-contained).
- Low latency (no buffering / windowing).
- High throughput (parallelize trivially).
- Idempotent handlers preferred (at-least-once delivery).
### 매 응용
1. Order placed → email confirmation.
2. User signup → welcome workflow.
3. Sensor reading → threshold alert.
4. Payment captured → inventory reserve.
5. Log line → metric increment.
## 💻 패턴
### Kafka consumer (TypeScript)
```typescript
import { Kafka } from 'kafkajs';
const kafka = new Kafka({ brokers: ['localhost:9092'] });
const consumer = kafka.consumer({ groupId: 'order-emails' });
await consumer.subscribe({ topic: 'orders.placed' });
await consumer.run({
eachMessage: async ({ message }) => {
const order = JSON.parse(message.value!.toString());
await sendOrderEmail(order.userId, order.id);
},
});
```
### AWS EventBridge rule
```typescript
import { EventBridgeClient, PutRuleCommand } from '@aws-sdk/client-eventbridge';
await client.send(new PutRuleCommand({
Name: 'order-placed-email',
EventPattern: JSON.stringify({
source: ['app.orders'],
'detail-type': ['OrderPlaced'],
}),
Targets: [{ Arn: lambdaArn, Id: 'send-email' }],
}));
```
### NATS subject handler
```typescript
import { connect, StringCodec } from 'nats';
const nc = await connect({ servers: 'nats://localhost:4222' });
const sc = StringCodec();
const sub = nc.subscribe('orders.placed');
for await (const msg of sub) {
const order = JSON.parse(sc.decode(msg.data));
await reserveInventory(order);
}
```
### Idempotent handler
```typescript
async function handleOrderPlaced(event: OrderEvent) {
const seen = await redis.set(`processed:${event.id}`, '1', 'NX', 'EX', 86400);
if (!seen) return; // already handled
await sendEmail(event);
}
```
### Dead-letter handling
```typescript
await consumer.run({
eachMessage: async ({ message }) => {
try {
await handle(message);
} catch (err) {
await producer.send({
topic: 'orders.placed.dlq',
messages: [{ value: message.value, headers: { error: err.message } }],
});
}
},
});
```
### CloudEvents envelope
```typescript
const cloudEvent = {
specversion: '1.0',
type: 'com.example.order.placed',
source: '/orders',
id: crypto.randomUUID(),
time: new Date().toISOString(),
data: { orderId, userId, amount },
};
await producer.send({ topic: 'orders.placed', messages: [{ value: JSON.stringify(cloudEvent) }] });
```
### Webhook fan-out
```typescript
app.post('/webhooks/payment', async (req, res) => {
await eventBus.publish('payment.captured', req.body);
res.status(202).end();
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 1:1 event → action, stateless | SEP |
| Stream aggregation (window sums) | ESP (Flink) |
| Pattern detect (A then B within 5s) | CEP (Esper) |
| Cross-system fan-out | SEP via EventBridge/Kafka |
**기본값**: Kafka or EventBridge + idempotent stateless handlers.
## 🔗 Graph
- 부모: [[Event-Driven-Architecture]]
- 변형: [[Event-Stream-Processing]]
- 응용: [[Webhooks]] · [[Pub-Sub]] · [[Event-Sourcing]]
- Adjacent: [[CQRS]]
## 🤖 LLM 활용
**언제**: stateless 1:1 event handling — webhook, notification, simple workflow trigger.
**언제 X**: pattern correlation 필요 — CEP / ESP 사용.
## ❌ 안티패턴
- **Stateful SEP**: 매 cross-event state 가지면 ESP 로 reframe.
- **No idempotency**: at-least-once delivery 에서 매 duplicate side-effect.
- **Synchronous webhook chain**: 매 cascading failure — async queue 사이로.
## 🧪 검증 / 중복
- Verified (Hohpe Enterprise Integration Patterns, Confluent docs, AWS EventBridge guide).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — SEP vs ESP vs CEP, Kafka/EventBridge/NATS patterns |
@@ -0,0 +1,158 @@
---
id: wiki-2026-0508-single-source-of-truth
title: Single Source of Truth (SSoT)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [SSoT, Single Source of Truth, Authoritative Source]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, data, principle, consistency]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: redux
---
# Single Source of Truth (SSoT)
## 매 한 줄
> **"매 fact 의 1 authoritative location. Everywhere else 의 derive."**. 매 information architecture 의 fundamental principle — duplication 의 minimize 후 매 derived view 의 cache/projection 으로 처리. 매 frontend (Redux), backend (master DB), DevOps (Git as IaC source) 의 cross-cutting pattern.
## 매 핵심
### 매 layers
- **DB layer**: master DB + read replicas (no parallel sources).
- **App state**: Redux store / TanStack Query cache.
- **Config**: Git repo (Infrastructure as Code).
- **Identity**: SCIM-synced IdP (Okta/Entra).
- **Schema**: protobuf / OpenAPI as type-source.
### 매 derived view
- Materialized views (DB).
- Selectors / memoized derive (frontend).
- Search indexes (Elastic) reflecting master.
- Reporting cubes built from master.
### 매 응용
1. Redux Toolkit `createSlice` — 1 store, derived UI.
2. Git → Terraform → Cloud (no console drift).
3. SCIM provisioning — IdP authoritative.
4. CDC (Debezium) — master DB → downstream consumers.
5. Event sourcing — log as SSoT.
## 💻 패턴
### Redux normalize + selector
```typescript
import { createSlice, createSelector } from '@reduxjs/toolkit';
const usersSlice = createSlice({
name: 'users',
initialState: { byId: {} as Record<string, User> },
reducers: { upsert: (state, { payload }) => { state.byId[payload.id] = payload; } },
});
export const selectUser = (id: string) => (state: RootState) => state.users.byId[id];
export const selectActiveUsers = createSelector(
(s: RootState) => Object.values(s.users.byId),
(users) => users.filter(u => u.active),
);
```
### Terraform as IaC SSoT
```hcl
resource "aws_s3_bucket" "logs" {
bucket = "company-logs-prod"
tags = { managed_by = "terraform", repo = "infra" }
}
# Console changes drift-detected via `terraform plan`
```
### Debezium CDC
```yaml
connector.class: io.debezium.connector.postgresql.PostgresConnector
database.hostname: master.db
table.include.list: public.orders
plugin.name: pgoutput
# Master postgres → Kafka → search/analytics consumers
```
### Schema-first (protobuf)
```proto
syntax = "proto3";
message User {
string id = 1;
string email = 2;
bool active = 3;
}
// codegen → TS, Go, Python types — single schema source
```
### Materialized view (Postgres)
```sql
CREATE MATERIALIZED VIEW user_stats AS
SELECT user_id, COUNT(*) AS orders, SUM(total) AS revenue
FROM orders GROUP BY user_id;
REFRESH MATERIALIZED VIEW CONCURRENTLY user_stats;
```
### SCIM provisioning
```typescript
// IdP (Okta) → /scim/v2/Users — app receives, never originates user identity
app.put('/scim/v2/Users/:id', (req, res) => {
await db.upsertUser(req.params.id, req.body);
res.status(200).json(req.body);
});
```
### TanStack Query cache as derived
```typescript
const { data: user } = useQuery({
queryKey: ['user', id],
queryFn: () => api.getUser(id),
staleTime: 60_000,
});
// Server is SSoT — cache is derived view with TTL
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Cross-system data sync | CDC from master DB |
| Cloud config | Git + Terraform |
| User identity | IdP + SCIM |
| Frontend state | Normalized Redux + selectors |
| Analytics | Reflect master via warehouse |
**기본값**: master + derived projections — never multi-master unless conflict-resolution strategy defined.
## 🔗 Graph
- 부모: [[Data-Modeling]]
- 변형: [[Event-Sourcing]] · [[CQRS]]
- 응용: [[Redux-Toolkit]] · [[Terraform]] · [[CDC]] · [[GitOps]]
- Adjacent: [[Eventual-Consistency]]
## 🤖 LLM 활용
**언제**: design-time data flow review, drift audit, cache invalidation strategy.
**언제 X**: distributed systems with offline-first requirement — CRDT 가 적합.
## ❌ 안티패턴
- **Dual-write**: 매 app writes both DB and search — drift inevitable. CDC 사용.
- **Console drift**: cloud console change without IaC update.
- **Cached as authoritative**: TTL stale → cache mistakenly trusted.
## 🧪 검증 / 중복
- Verified (Fowler, Kleppmann DDIA, Redux docs, Terraform best practices).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — SSoT principle, master + derived patterns, CDC/IaC/SCIM |
@@ -0,0 +1,157 @@
---
id: wiki-2026-0508-snapshots
title: Snapshots
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [State Snapshot, V8 Snapshot, GC Snapshot, Heap Snapshot]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [runtime, performance, debugging, memory, state]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: javascript
framework: v8
---
# Snapshots
## 매 한 줄
> **"매 point-in-time 의 state freeze — 매 startup 의 accelerate, 매 leak 의 hunt, 매 recovery 의 enable."**. 매 V8 startup snapshot, heap snapshot, filesystem snapshot (ZFS/Btrfs), DB snapshot, state snapshot (Redux time-travel) — 매 same primitive 의 different domain. 매 modern runtime 의 cold-start optimization 의 default tool.
## 매 핵심
### 매 종류
- **V8 startup snapshot**: serialize heap → fast Node.js cold start.
- **Heap snapshot** (`.heapsnapshot`): debug memory leak, retainer graph.
- **GC snapshot**: generational scan checkpoint.
- **Filesystem snapshot**: ZFS/Btrfs/LVM copy-on-write point-in-time.
- **DB snapshot**: PITR base, transactional checkpoint.
- **State snapshot**: Redux DevTools time-travel, game save.
### 매 properties
- Copy-on-write (efficient diff storage).
- Atomic (consistent point-in-time).
- Restorable (full state reconstruction).
- Immutable (snapshot itself never mutated).
### 매 응용
1. Node.js bootup `--snapshot-blob` (200ms → 30ms startup).
2. Chrome DevTools heap profiler — leak hunt.
3. ZFS rollback before risky deploy.
4. Postgres PITR base + WAL replay.
5. Redux DevTools — time-travel debug.
6. AWS EBS snapshot — disaster recovery.
7. Container checkpoint/restore (CRIU).
## 💻 패턴
### Node.js startup snapshot
```bash
node --snapshot-blob snapshot.blob --build-snapshot snapshot-init.js
node --snapshot-blob snapshot.blob app.js
# Cold start: 200ms → ~30ms
```
### Chrome heap snapshot programmatic
```javascript
const v8 = require('v8');
const fs = require('fs');
const stream = v8.getHeapSnapshot();
stream.pipe(fs.createWriteStream('heap.heapsnapshot'));
// Open in Chrome DevTools → Memory tab
```
### ZFS snapshot + rollback
```bash
zfs snapshot tank/data@before-deploy
# ... risky operation ...
zfs rollback tank/data@before-deploy # if failure
zfs destroy tank/data@before-deploy # if success
```
### Postgres base backup + PITR
```bash
pg_basebackup -D /backup/base -F tar -X stream -P
# Recover to point-in-time
restore_command = 'cp /archive/%f %p'
recovery_target_time = '2026-05-10 14:30:00'
```
### Redux state snapshot
```typescript
import { createStore } from 'redux';
const store = createStore(reducer);
const snapshot = store.getState(); // freeze
// ... actions ...
store.replaceReducer((state = snapshot) => state); // restore
```
### CRIU container checkpoint
```bash
criu dump --tree $PID --images-dir /checkpoints/svc-1 --leave-running
# Later, possibly on different host:
criu restore --images-dir /checkpoints/svc-1
```
### EBS snapshot via AWS SDK
```typescript
import { EC2Client, CreateSnapshotCommand } from '@aws-sdk/client-ec2';
await client.send(new CreateSnapshotCommand({
VolumeId: 'vol-0abc',
Description: 'pre-migration-2026-05-10',
TagSpecifications: [{ ResourceType: 'snapshot', Tags: [{ Key: 'env', Value: 'prod' }] }],
}));
```
### Heap diff analysis
```javascript
// Take 2 snapshots, diff in DevTools to find leak
v8.writeHeapSnapshot('/tmp/before.heapsnapshot');
runSuspectCode();
v8.writeHeapSnapshot('/tmp/after.heapsnapshot');
// Load both → "Comparison" view → growing retainer chains
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Node.js cold start slow | startup snapshot |
| Memory leak hunt | heap snapshot diff |
| Pre-deploy rollback safety | ZFS/EBS snapshot |
| DB recovery to time T | PITR base + WAL |
| Container live migration | CRIU checkpoint |
| Frontend bug repro | Redux time-travel |
**기본값**: heap snapshot for leaks, ZFS/EBS for storage, PITR for DB, CRIU for container.
## 🔗 Graph
- 부모: [[State-Management]]
- 변형: [[Heap-Snapshot]] · [[V8-Snapshot]]
- 응용: [[Disaster-Recovery]]
- Adjacent: [[Event-Sourcing]]
## 🤖 LLM 활용
**언제**: cold-start optim, leak diag, DR planning, time-travel debug strategy.
**언제 X**: write-heavy hot path — snapshot overhead 의 measure 필요.
## ❌ 안티패턴
- **Snapshot as backup**: 매 same disk 의 snapshot 의 disk failure 의 protect X.
- **No retention policy**: 매 snapshot accumulate → storage explode.
- **Heap snapshot in prod under load**: 매 GC pause spike — staging 에서.
## 🧪 검증 / 중복
- Verified (V8 docs, Chrome DevTools docs, ZFS handbook, Postgres PITR docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — snapshot taxonomy, V8/heap/ZFS/PITR/CRIU patterns |
@@ -0,0 +1,149 @@
---
id: wiki-2026-0508-social-engineering
title: Social Engineering
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Social Engineering Attacks, Human-Layer Attack, Phishing Family]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [security, threat-model, phishing, awareness]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: english
framework: security
---
# Social Engineering
## 매 한 줄
> **"매 attack 의 weakest link 의 human 의 exploit. Tech-stack 의 hardening 보다 매 human-layer 의 manipulation 가 cheaper."**. 매 phishing, vishing, pretexting, baiting 의 family — 매 2026 LLM-generated voice clones / deepfake video 가 매 attack vector 의 industrialize 했음. 매 SOC2 / ISO27001 의 awareness training 의 mandate.
## 매 핵심
### 매 attack vectors
- **Phishing** (email) — bulk credential harvest.
- **Spear-phishing** — targeted, OSINT-backed.
- **Vishing** (voice) — 매 LLM voice clone 의 era.
- **Smishing** (SMS) — package delivery, bank scam.
- **Pretexting** — impersonation (CEO fraud, IT helpdesk).
- **Baiting** — USB drop, malicious download.
- **Tailgating** — physical access.
### 매 psychological levers (Cialdini)
- Authority (CEO impersonation).
- Urgency ("account locked, act now").
- Scarcity ("last chance").
- Reciprocity ("free gift").
- Social proof ("colleagues already responded").
- Liking (rapport building).
### 매 응용 (defense)
1. MFA (phishing-resistant — FIDO2/passkey).
2. SPF/DKIM/DMARC for email auth.
3. Awareness training + simulated phishing.
4. Approval workflow for wire transfers (out-of-band verify).
5. Zero-trust + least-privilege blast radius limit.
## 💻 패턴
### DMARC enforce policy
```dns
_dmarc.example.com. TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100"
```
### Phishing simulation framework (gophish API)
```python
import requests
api = "https://gophish.local/api"
headers = {"Authorization": "Bearer TOKEN"}
campaign = {
"name": "Q2 Awareness",
"template": {"name": "Fake-IT-Reset"},
"url": "https://landing.local",
"groups": [{"name": "All-Employees"}],
}
requests.post(f"{api}/campaigns/", json=campaign, headers=headers)
```
### FIDO2 webauthn (phishing-resistant)
```typescript
const credential = await navigator.credentials.create({
publicKey: {
challenge: serverChallenge,
rp: { name: 'example.com' },
user: { id, name: email, displayName: name },
pubKeyCredParams: [{ alg: -7, type: 'public-key' }],
authenticatorSelection: { userVerification: 'required', authenticatorAttachment: 'platform' },
},
});
```
### Wire-transfer out-of-band verify (Slack bot)
```typescript
bot.command('/verify-wire', async ({ command, ack }) => {
await ack();
const challenge = generateOTP();
await sms.send(command.user_phone, `Wire verify code: ${challenge}`);
await db.storeChallenge(command.user_id, challenge);
});
```
### Email header anomaly detection
```python
def is_suspicious(msg):
spf = msg.get('Authentication-Results', '')
if 'spf=fail' in spf or 'dkim=fail' in spf:
return True
if msg['From'] != msg['Reply-To']:
return True # display name spoof
return False
```
### Deepfake voice detection (2026 ML)
```python
from transformers import pipeline
detector = pipeline('audio-classification', model='WavLM-deepfake-2026')
result = detector(audio_path)
# returns: [{'label': 'synthetic', 'score': 0.94}, ...]
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Email account compromise risk | DMARC reject + FIDO2 MFA |
| Wire transfer fraud (BEC) | Out-of-band callback verify |
| Voice impersonation | Codeword + callback to known number |
| USB drop | Endpoint policy block autorun |
| Insider awareness | Quarterly simulated phishing |
**기본값**: FIDO2 passkey + DMARC reject + quarterly training + out-of-band approval for $X+ transfers.
## 🔗 Graph
- 부모: [[Threat-Modeling]] · [[OWASP-Top-10]]
- 변형: [[Phishing]]
- 응용: [[FIDO2]] · [[DMARC]] · [[Zero-Trust-Architecture]]
## 🤖 LLM 활용
**언제**: threat-model human layer, security training content, BEC playbook.
**언제 X**: 매 actual phishing template generation — abuse risk.
## ❌ 안티패턴
- **SMS-only MFA**: SIM-swap vulnerable — FIDO2 prefer.
- **Annual training only**: 매 retention low — quarterly + simulation.
- **Trust caller-ID**: 매 trivially spoof — callback to known number.
## 🧪 검증 / 중복
- Verified (NIST SP 800-50, Mitnick "Art of Deception", Verizon DBIR 2025).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — SE attack vectors, Cialdini levers, FIDO2/DMARC defenses |
@@ -0,0 +1,199 @@
---
id: wiki-2026-0508-software-architecture-documentat
title: Software Architecture Documentation
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [SAD, Architecture Documentation, arc42, C4 Model]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, documentation, arc42, c4, adr]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: markdown
framework: structurizr
---
# Software Architecture Documentation
## 매 한 줄
> **"매 architecture 의 communicate 가능 form 의 capture — 매 stakeholder 의 different view 의 serve."**. 매 arc42 (12-section template), C4 (4-level zoom), 4+1 view (logical/process/dev/physical+scenario), ADR (decision log) 의 4 매 dominant frameworks. 매 2026 modern: Structurizr DSL 의 diagrams-as-code, AsyncAPI 의 event arch documentation.
## 매 핵심
### 매 frameworks
- **arc42** — 12 sections (introduction → goals → context → solution strategy → blocks → runtime → deployment → concepts → decisions → quality → risks → glossary).
- **C4 Model** (Brown) — Context / Containers / Components / Code (zoom levels).
- **4+1 View** (Kruchten) — Logical, Process, Development, Physical, +Scenarios.
- **ADR** (Nygard) — decision log per technical choice.
### 매 audiences
- Executives → context view (C4 L1).
- Developers → containers + components.
- Ops → deployment view + runbook.
- Auditors → cross-cutting concerns + decisions.
### 매 응용
1. New service onboarding doc.
2. M&A architecture due diligence.
3. SOC2 / ISO27001 audit evidence.
4. Pre-rewrite reverse-architecting.
5. Onboarding new engineer (1-week ramp).
## 💻 패턴
### arc42 skeleton (markdown)
```markdown
# Architecture Documentation — Service X
## 1. Introduction & Goals
## 2. Constraints
## 3. Context & Scope
## 4. Solution Strategy
## 5. Building Block View
## 6. Runtime View
## 7. Deployment View
## 8. Crosscutting Concepts
## 9. Architecture Decisions (ADRs)
## 10. Quality Requirements
## 11. Risks & Technical Debt
## 12. Glossary
```
### C4 with Structurizr DSL
```dsl
workspace "Skybound" {
model {
user = person "Customer"
api = softwareSystem "API" {
web = container "Web App" "React"
svc = container "Backend" "Node.js"
db = container "Database" "Postgres"
}
user -> web "uses"
web -> svc "JSON/HTTPS"
svc -> db "SQL"
}
views {
systemContext api { include * autolayout }
container api { include * autolayout }
}
}
```
### ADR template (MADR)
```markdown
# ADR-0042: Use Postgres as Primary Store
## Status
Accepted (2026-05-10)
## Context
Need transactional store with strong consistency, JSON support.
## Decision
Use Postgres 16 with logical replication for read-replicas.
## Consequences
+ ACID, mature ecosystem, JSONB
- Vertical scaling ceiling — sharding plan needed by 2027
## Alternatives
- DynamoDB: rejected (relational queries)
- Mongo: rejected (consistency tradeoffs)
```
### Diagrams-as-code (Mermaid)
```markdown
```mermaid
C4Container
title Container Diagram for Skybound
Person(user, "User")
System_Boundary(api, "Skybound") {
Container(web, "Web App", "React")
Container(svc, "Backend", "Node.js")
ContainerDb(db, "Database", "Postgres")
}
Rel(user, web, "uses")
Rel(web, svc, "JSON/HTTPS")
Rel(svc, db, "SQL")
```
```
### AsyncAPI (event arch)
```yaml
asyncapi: 3.0.0
info: { title: Orders, version: 1.0.0 }
channels:
orderPlaced:
address: orders.placed
messages:
OrderPlaced:
payload:
type: object
properties:
id: { type: string }
amount: { type: number }
```
### Quality attribute scenarios
```markdown
## Performance Scenario
- Source: 10k concurrent users
- Stimulus: checkout submit
- Environment: peak load
- Response: order created, confirmation email queued
- Measure: p99 < 800ms, error rate < 0.1%
```
### Documentation in repo (docs-as-code)
```
/docs
/architecture
arc42.md
/adr
0001-postgres.md
0002-event-bus.md
/diagrams
workspace.dsl
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Quick visual onboarding | C4 Context + Container |
| Comprehensive system doc | arc42 full template |
| Per-decision rationale | ADR (MADR) |
| Event-driven system | AsyncAPI + arc42 ch.6 |
| Audit evidence | arc42 ch.8 + ADRs |
**기본값**: arc42 + C4 (L1-L2) + ADR repo + Structurizr DSL + docs-as-code in monorepo.
## 🔗 Graph
- 부모: [[Software-Architecture]]
- 변형: [[arc42]] · [[C4-Model]]
- 응용: [[ADR]] · [[Structurizr]] · [[Mermaid-Diagrams]]
- Adjacent: [[Architecture Decision Record]] · [[Software-Architecture-Erosion]]
## 🤖 LLM 활용
**언제**: doc gap analysis, ADR drafting, view-completeness review.
**언제 X**: 매 architecture 의 yet 결정 X — 매 decision-making 의 first.
## ❌ 안티패턴
- **Stale Visio**: 매 PDF/image 의 versioned X — diagrams-as-code 사용.
- **Doc-only, no view**: 매 1 PDF 의 dump — view-per-audience 분리.
- **No ADR**: 매 6개월 후 매 "왜 X 선택?" 답 X.
## 🧪 검증 / 중복
- Verified (arc42.org, C4model.com, Brown "Software Architecture for Developers", Nygard ADR).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — arc42, C4, ADR, AsyncAPI, docs-as-code patterns |
@@ -0,0 +1,159 @@
---
id: wiki-2026-0508-software-architecture-recovery
title: Software Architecture Recovery
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Architecture Recovery, Reverse Architecting]
duplicate_of: none
source_trust_level: A
confidence_score: 0.85
verification_status: applied
tags: [architecture, reverse-engineering, legacy, static-analysis]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: networkx
---
# Software Architecture Recovery
## 매 한 줄
> **"매 source code → 매 architectural model 의 inference"**. Documentation 의 lost / outdated 의 legacy system 의 understanding. 2026 현재 매 LLM (Claude Opus 4.7, GPT-5) 의 augmented static-analysis 가 매 dominant — 매 dependency graph + cluster + LLM-named module summary.
## 매 핵심
### 매 phases
1. **Extraction**: 매 source code, build files, config 의 parse → entities (file, class, module).
2. **Abstraction**: 매 dependency graph, call graph, data-flow.
3. **Clustering**: 매 community detection (Louvain, label propagation), 매 LLM semantic grouping.
4. **Presentation**: C4 diagram, dependency matrix, ADR.
### 매 techniques
- **Static**: AST parse, import graph (madge, jdeps, pyan).
- **Dynamic**: trace logs, profilers, distributed tracing (OTel).
- **Hybrid**: 매 static + runtime call data merge.
- **LLM-augmented**: 매 module 별 README/code → 매 LLM summary, 매 architecture description.
### 매 응용
1. Legacy modernization assessment.
2. Microservice decomposition planning.
3. Onboarding new engineers.
## 💻 패턴
### Python — import graph 의 추출
```python
import ast, os, networkx as nx
G = nx.DiGraph()
for root, _, files in os.walk("src"):
for f in files:
if not f.endswith(".py"): continue
path = os.path.join(root, f)
tree = ast.parse(open(path).read())
mod = path.replace("/", ".").removesuffix(".py")
for node in ast.walk(tree):
if isinstance(node, ast.ImportFrom) and node.module:
G.add_edge(mod, node.module)
```
### JavaScript — madge dependency graph
```bash
npx madge --image graph.svg --extensions ts,tsx src/
npx madge --circular src/ # detect cycles
```
### Java — jdeps + GraalVM
```bash
jdeps -verbose:class -recursive app.jar > deps.txt
jdeps --inverse --package com.acme.payment app.jar
```
### Community detection (Louvain)
```python
import networkx as nx
from networkx.algorithms.community import louvain_communities
modules = louvain_communities(G.to_undirected(), resolution=1.2, seed=42)
for i, m in enumerate(modules):
print(f"Module {i}: {sorted(m)[:5]}...")
```
### LLM-augmented module naming (Claude Opus 4.7)
```python
from anthropic import Anthropic
client = Anthropic()
def name_module(files: list[str], code_snippets: list[str]) -> str:
msg = client.messages.create(
model="claude-opus-4-7",
max_tokens=200,
messages=[{"role": "user", "content":
f"Files: {files}\n\nSnippets:\n{code_snippets}\n\n"
"Give a 3-word module name + 1-line responsibility."}],
)
return msg.content[0].text
```
### Runtime trace → architecture (OpenTelemetry)
```python
# Aggregate spans into service-level call graph
from collections import Counter
edges = Counter()
for span in fetch_traces(service="checkout", since="24h"):
if span.parent and span.parent.service != span.service:
edges[(span.parent.service, span.service)] += 1
# Top edges = primary architectural connections
```
### C4 diagram emission (Structurizr DSL)
```dsl
workspace {
model {
user = person "Customer"
sys = softwareSystem "Shop" {
web = container "Web"
api = container "API"
db = container "Postgres"
}
user -> web "uses"
web -> api "REST"
api -> db "JDBC"
}
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Small monolith (<100k LoC) | Static import graph + manual review |
| Microservices distributed | Distributed tracing (OTel) + service map |
| Legacy COBOL/Java enterprise | Lattix / Structure101 commercial tools |
| Quick high-level overview | LLM (Opus 4.7) on README + top-level dirs |
| Decomposition planning | Static + dynamic + LLM hybrid |
**기본값**: 매 static import graph (madge / pyan / jdeps) → Louvain cluster → LLM name → C4 diagram.
## 🔗 Graph
- 부모: [[Software Architecture]]
- 응용: [[Legacy Modernization]]
- Adjacent: [[C4 Model]] · [[Dependency Analysis]] · [[Static Analysis]]
## 🤖 LLM 활용
**언제**: 매 undocumented codebase 의 onboarding, 매 modernization plan, 매 dependency cycle 의 detect.
**언제 X**: 매 well-documented current arch — 매 ADR 의 read 의 충분.
## ❌ 안티패턴
- **Recovered = correct**: 매 inferred architecture 는 매 historical, 매 ideal X. Validate with team.
- **Static only for distributed system**: 매 runtime topology 의 lost.
- **LLM hallucination**: 매 module name 의 plausible 의 X-correct. 매 verify.
## 🧪 검증 / 중복
- Verified (Garlan & Schmerl SAR research, 20022024; SEI architecture reconstruction guides).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — recovery techniques with LLM-augmented analysis |
@@ -0,0 +1,137 @@
---
id: wiki-2026-0508-space-based-architecture
title: Space-Based Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Space-Based Architecture, SBA, Tuple Space Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.85
verification_status: applied
tags: [architecture, scalability, in-memory-data-grid]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: java
framework: hazelcast
---
# Space-Based Architecture
## 매 한 줄
> **"매 database bottleneck 의 제거 — 매 in-memory data grid (tuple space) + 매 processing units 의 horizontal scale"**. Linda tuple space (1985) 의 후예. 매 Gigaspaces, Hazelcast, Apache Ignite 가 매 commercial 구현. 매 high-volume, low-latency 의 trading, gaming, real-time bidding.
## 매 핵심
### 매 components
- **Processing Unit (PU)**: 매 stateless application + 매 local in-memory data partition.
- **Virtualized Middleware**:
- *Messaging Grid*: load balancer.
- *Data Grid*: 매 distributed in-memory cache (replicated/partitioned).
- *Processing Grid*: 매 orchestrate distributed work.
- *Deployment Manager*: 매 PU lifecycle.
- **Data Pumps**: 매 data grid → DB async write-behind.
- **Data Writers / Readers**: 매 eventual persistence.
### 매 trade-off
- **장점**: 매 elastic horizontal scale, 매 DB 의 single point of bottleneck X, 매 sub-ms latency.
- **단점**: 매 eventual consistency, 매 complexity 의 폭발, 매 in-memory cost 의 high, 매 split-brain risk.
### 매 응용
1. Online ticketing (Ticketmaster).
2. Real-time bidding (ad exchange).
3. MMO game state (player position grid).
## 💻 패턴
### Hazelcast IMDG — distributed map (Java 21)
```java
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
IMap<String, Order> orders = hz.getMap("orders");
orders.put("o-123", new Order("sku-1", 99));
Order o = orders.get("o-123"); // 매 local or remote partition
```
### EntryProcessor — 매 data-local computation
```java
orders.executeOnKey("o-123", (EntryProcessor<String, Order, Void>) entry -> {
var o = entry.getValue();
o.markPaid();
entry.setValue(o); // 매 in-place mutation, 매 network round-trip 1회
return null;
});
```
### Write-behind to RDBMS (data pump)
```java
MapConfig cfg = new MapConfig("orders")
.setMapStoreConfig(new MapStoreConfig()
.setClassName("com.acme.OrderMapStore")
.setWriteDelaySeconds(5)
.setWriteBatchSize(100));
hz.getConfig().addMapConfig(cfg);
```
### Apache Ignite — SQL on data grid
```java
IgniteCache<Long, Order> cache = ignite.cache("orders");
SqlFieldsQuery q = new SqlFieldsQuery(
"SELECT customerId, SUM(amount) FROM Order GROUP BY customerId");
cache.query(q).forEach(row -> System.out.println(row));
```
### Affinity colocation — 매 join-friendly partition
```java
@AffinityKeyMapped Long customerId; // 매 same partition 의 customer + orders
```
### Near cache (read-heavy)
```java
NearCacheConfig near = new NearCacheConfig()
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setTimeToLiveSeconds(30);
```
### Continuous query (event subscription)
```java
orders.addEntryListener((EntryAddedListener<String, Order>) e ->
eventBus.publish("order.created", e.getValue()), true);
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Sub-ms read/write @ 100k+ TPS | Space-based (Hazelcast/Ignite) |
| Strong consistency 필요 | Traditional RDBMS / NewSQL (CockroachDB) |
| Read-heavy, eventual OK | CDN + cache-aside (Redis) |
| Stream-first | Kafka + Flink (event-driven) |
**기본값**: 매 default 가 X — SBA 의 specialized. 매 일반 backend → microservices + Postgres + Redis.
## 🔗 Graph
- 부모: [[Software Architecture]] · [[Distributed Systems]]
- 변형: [[Microservices]] · [[Event-Driven Architecture]]
- 응용: [[In-Memory Data Grid]]
- Adjacent: [[CAP Theorem]] · [[Eventual Consistency]] · [[Apache Ignite]]
## 🤖 LLM 활용
**언제**: extreme write throughput, DB bottleneck, latency budget < 10ms.
**언제 X**: 매 일반 CRUD, 매 strong consistency 의 필요, 매 small team — 매 complexity 의 cost 의 huge.
## ❌ 안티패턴
- **SBA for CRUD**: 매 over-engineering. Postgres 의 sufficient.
- **Sync write-through to DB**: 매 SBA 의 point 의 lost — async write-behind 의 의도.
- **Single PU instance**: 매 distributed grid 의 X — 매 SPOF.
- **No backup partitions**: 매 node failure → data loss.
## 🧪 검증 / 중복
- Verified (Mark Richards, *Software Architecture Patterns* O'Reilly; Hazelcast 5.x docs 2025).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full SBA spec with Hazelcast/Ignite patterns |
@@ -0,0 +1,163 @@
---
id: wiki-2026-0508-static-and-dynamic-analysis
title: Static and Dynamic Analysis
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [SAST, DAST, Code Analysis, Program Analysis]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [security, analysis, sast, dast]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: multi
framework: semgrep-zap
---
# Static and Dynamic Analysis
## 매 한 줄
> **"매 코드 의 read 의 SAST, 매 코드 의 run 의 DAST"**. 매 static 의 source/binary 의 inspection — 매 dynamic 의 running app 의 probe. 2026 의 best practice 의 SAST + DAST + IAST 의 layered defense.
## 매 핵심
### 매 SAST (Static Application Security Testing)
- 매 source code / bytecode 의 분석 — 매 execution 의 X.
- 강점: full coverage, early in SDLC, finds hard-to-trigger bugs.
- 약점: false positives, no runtime context, framework-specific FN.
- Tools: Semgrep, CodeQL, SonarQube, Snyk Code.
### 매 DAST (Dynamic Application Security Testing)
- 매 running app 의 black-box probing — 매 HTTP fuzzing.
- 강점: real runtime behavior, env-config bugs, low FP.
- 약점: limited coverage (only reachable paths), late in SDLC.
- Tools: OWASP ZAP, Burp Suite, Nuclei.
### 매 IAST (Interactive)
- 매 instrumented agent 의 runtime data flow tracking.
- Hybrid: static-style precision + dynamic-style validity.
- Tools: Contrast Security, Checkmarx IAST.
### 매 응용
1. CI/CD security gate (SAST on every PR).
2. Pre-prod scan (DAST against staging).
3. Compliance (PCI, SOC2, ISO 27001).
## 💻 패턴
### Semgrep — custom SAST rule
```yaml
rules:
- id: hardcoded-jwt-secret
pattern: jwt.sign($PAYLOAD, "...")
message: Hardcoded JWT secret detected
severity: ERROR
languages: [javascript, typescript]
```
### CodeQL — taint tracking
```ql
import javascript
class XssConfig extends TaintTracking::Configuration {
XssConfig() { this = "Xss" }
override predicate isSource(DataFlow::Node n) {
n instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node n) {
exists(DOM::DomMethodCallNode c | c.getMethodName() = "innerHTML" |
n = c.getArgument(0))
}
}
```
### ZAP — automated DAST scan
```bash
docker run -v $(pwd):/zap/wrk -t zaproxy/zap-stable \
zap-baseline.py -t https://staging.example.com \
-r report.html -J report.json
```
### Nuclei — template-based DAST
```yaml
id: log4shell
info:
name: Apache Log4j RCE
severity: critical
requests:
- method: GET
path: ["{{BaseURL}}"]
headers:
User-Agent: "${jndi:ldap://{{interactsh-url}}/a}"
matchers:
- type: word
part: interactsh_protocol
words: ["dns"]
```
### CI integration — GitHub Actions
```yaml
- uses: returntocorp/semgrep-action@v1
with:
config: p/owasp-top-ten
- uses: github/codeql-action/analyze@v3
- name: ZAP Baseline
uses: zaproxy/action-baseline@v0.10.0
with:
target: 'https://staging.example.com'
```
### Tainted data flow — Java pseudocode
```java
String input = request.getParameter("q"); // SOURCE (tainted)
String sanitized = StringEscapeUtils.escapeHtml4(input); // SANITIZER
response.getWriter().write(sanitized); // SINK (safe)
// SAST tracks: source → sink without sanitizer = vulnerability
```
### SBOM + dependency scanning
```bash
syft dir:. -o cyclonedx-json > sbom.json
grype sbom:sbom.json --fail-on high
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Pre-commit, fast feedback | SAST (Semgrep) |
| Deep semantic analysis | CodeQL |
| Pre-prod runtime check | DAST (ZAP, Burp) |
| Runtime + coverage | IAST (Contrast) |
| Dependency vulns | SCA (Snyk, Grype) |
**기본값**: 매 Semgrep (PR) + ZAP baseline (nightly) + Grype (deps).
## 🔗 Graph
- 부모: [[Application Security]] · [[CI_CD 파이프라인 및 IDE 통합 보안|DevSecOps]]
- 변형: [[SAST]] · [[보안_및_시스템_신뢰성_표준|DAST]] · [[IAST]] · [[SCA_Fundamentals|SCA]]
- Adjacent: [[Fuzzing]] · [[Threat Modeling]] · [[보안_및_시스템_신뢰성_표준|OWASP Top 10]]
## 🤖 LLM 활용
**언제**: code review automation, custom rule generation, false-positive triage.
**언제 X**: full code understanding (LLM hallucinates), security-critical decisions without human review.
## ❌ 안티패턴
- **SAST only**: 매 runtime config bug 의 miss — 매 DAST 의 추가.
- **Ignore false positives**: 매 alert fatigue 의 cause — 매 tuning 의 invest.
- **Scan in prod**: 매 DAST 의 staging — 매 prod 의 X.
- **One-time scan**: 매 continuous 의 — 매 every PR 의 gate.
## 🧪 검증 / 중복
- Verified (OWASP Testing Guide v5, NIST SP 800-218).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — SAST/DAST/IAST patterns, CI integration |
@@ -0,0 +1,174 @@
---
id: wiki-2026-0508-stochastic-gradient-descent
title: Stochastic Gradient Descent
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [SGD, Mini-batch SGD, Stochastic Gradient Descent]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [machine-learning, optimization, deep-learning, gradient-descent]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: python
framework: pytorch
---
# Stochastic Gradient Descent (SGD)
## 매 한 줄
> **"매 한 sample (or mini-batch) 에 대한 gradient 로 매 step — 매 noisy 하지만 매 cheap, 매 escape from local minima"**. Robbins & Monro (1951) 의 stochastic approximation 의 후예. 2026 deep learning 의 foundation — 매 SGD+momentum, AdamW, Lion 가 매 default.
## 매 핵심
### 매 vs full-batch
- **Batch GD**: 매 entire dataset gradient — 매 expensive, deterministic.
- **SGD (online)**: 매 single sample — 매 noisy, fast.
- **Mini-batch SGD**: 매 324096 samples — 매 modern default. 매 GPU 의 vectorize.
### 매 update rule
- Vanilla SGD: `θ ← θ η ∇L(θ; x_i, y_i)`.
- Momentum: `v ← μv + ∇L; θ ← θ − ηv`.
- Nesterov: 매 lookahead momentum.
### 매 modern variants
- **AdamW** (Loshchilov 2019): adaptive lr + decoupled weight decay — 매 LLM/transformer default.
- **Lion** (Chen 2023): sign-based momentum — 매 less memory, comparable.
- **Sophia** (2023): second-order — 매 LLM pretrain.
- **Muon** (Jordan 2024): orthogonalized momentum — 매 emerging.
### 매 응용
1. Neural network training (all of deep learning).
2. Logistic regression, linear regression at scale.
3. Online learning / streaming data.
## 💻 패턴
### PyTorch 2.5 — SGD with momentum
```python
import torch
from torch import nn, optim
model = nn.Linear(784, 10)
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, nesterov=True)
loss_fn = nn.CrossEntropyLoss()
for epoch in range(10):
for x, y in dataloader:
optimizer.zero_grad()
loss = loss_fn(model(x), y)
loss.backward()
optimizer.step()
```
### AdamW (transformer default 2026)
```python
optimizer = optim.AdamW(
model.parameters(),
lr=3e-4,
betas=(0.9, 0.95),
weight_decay=0.1,
fused=True, # 매 GPU fused kernel
)
```
### Cosine LR schedule
```python
from torch.optim.lr_scheduler import CosineAnnealingLR
scheduler = CosineAnnealingLR(optimizer, T_max=num_steps, eta_min=1e-6)
for step in range(num_steps):
train_step()
optimizer.step()
scheduler.step()
```
### Linear warmup + cosine decay (LLM standard)
```python
def lr_lambda(step):
if step < warmup:
return step / warmup
progress = (step - warmup) / (total - warmup)
return 0.5 * (1 + math.cos(math.pi * progress))
scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda)
```
### Gradient clipping (stability)
```python
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
optimizer.step()
```
### Mixed precision SGD (bf16, H100)
```python
scaler = torch.amp.GradScaler("cuda")
with torch.autocast("cuda", dtype=torch.bfloat16):
loss = loss_fn(model(x), y)
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
scaler.step(optimizer)
scaler.update()
```
### Pure NumPy SGD (linear regression)
```python
import numpy as np
def sgd(X, y, lr=0.01, epochs=100, batch=32):
w = np.zeros(X.shape[1])
for _ in range(epochs):
idx = np.random.permutation(len(X))
for i in range(0, len(X), batch):
b = idx[i:i+batch]
grad = X[b].T @ (X[b] @ w - y[b]) / len(b)
w -= lr * grad
return w
```
### Lion optimizer (2026 alt)
```python
# pip install lion-pytorch
from lion_pytorch import Lion
optimizer = Lion(model.parameters(), lr=1e-4, weight_decay=0.01)
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Image classification (ResNet, ViT) | SGD + momentum + cosine |
| LLM / Transformer training | AdamW + linear warmup + cosine |
| Memory-constrained large model | Lion or 8-bit Adam (bitsandbytes) |
| Convex optimization, theoretical guarantee | Vanilla SGD with decreasing lr |
| Online streaming data | Mini-batch SGD, lr ~ 1/sqrt(t) |
**기본값**: 매 transformer/LLM → AdamW 3e-4 + warmup 1k steps + cosine. 매 CNN → SGD 0.1 + momentum 0.9 + cosine.
## 🔗 Graph
- 부모: [[Gradient Descent]] · [[Optimization]]
- 변형: [[Adam]] · [[AdamW]]
- 응용: [[Deep Learning]]
- Adjacent: [[Gradient Clipping]] · [[데이터_사이언스_및_ML_엔지니어링|Backpropagation]]
## 🤖 LLM 활용
**언제**: 매 model training의 default optimizer choice; debug convergence (loss spike, plateau).
**언제 X**: 매 closed-form solution exists (small linear regression — use normal equation); 매 second-order necessary (small classical ML).
## ❌ 안티패턴
- **lr too high**: 매 loss explosion / NaN. 매 warmup + clip.
- **No weight decay**: 매 overfitting.
- **Momentum with lr too high**: 매 oscillation.
- **AdamW lr=1e-3 for LLM**: 매 too high — 1e-4 ~ 3e-4 가 매 standard.
- **Batch size 1 on GPU**: 매 underutilization. 매 32+ 의 사용.
## 🧪 검증 / 중복
- Verified (PyTorch docs 2.5; Goodfellow *Deep Learning* ch.8; Loshchilov AdamW 2019).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — SGD + modern variants (AdamW, Lion, Muon) for 2026 |
@@ -0,0 +1,182 @@
---
id: wiki-2026-0508-styled-components
title: Styled Components
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [styled-components, CSS-in-JS]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [react, css-in-js, frontend, styling]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: react
---
# Styled Components
## 매 한 줄
> **"매 CSS 의 component 의 안에 — 매 tagged template literal 로 매 React component + style 의 atomic unit"**. Glen Maddern, Max Stoiber (2016). 매 CSS-in-JS 의 reference. 2026 매 styled-components v6+ 가 매 React Server Components 의 partial 지원 — 매 RSC native era 에서 매 Tailwind / vanilla-extract / CSS Modules 의 challenge.
## 매 핵심
### 매 mechanic
- 매 tagged template literal: ``styled.button`color: red```.
- 매 runtime 의 unique class name 의 generation, 매 stylesheet 의 inject.
- 매 props-based dynamic styling: ``${props => props.primary ? '#0070f3' : '#fff'}``.
### 매 features
- **Theming**: ThemeProvider context.
- **`as` prop**: 매 polymorphic element.
- **Extending**: ``styled(Button)`...```.
- **Animations**: keyframes helper.
- **Global styles**: createGlobalStyle.
### 매 응용
1. React design system (Material-like component lib).
2. Theme switcher (dark mode).
3. Per-component style isolation.
## 💻 패턴
### Basic styled component (TypeScript)
```tsx
import styled from "styled-components";
const Button = styled.button<{ $primary?: boolean }>`
padding: 8px 16px;
border-radius: 6px;
border: none;
cursor: pointer;
background: ${(p) => (p.$primary ? "#0070f3" : "#eee")};
color: ${(p) => (p.$primary ? "#fff" : "#222")};
&:hover { opacity: 0.9; }
`;
export default function App() {
return <Button $primary>Buy</Button>;
}
```
### Theme + ThemeProvider
```tsx
import { ThemeProvider, DefaultTheme } from "styled-components";
const dark: DefaultTheme = { bg: "#111", fg: "#eee", accent: "#0af" };
const light: DefaultTheme = { bg: "#fff", fg: "#111", accent: "#06c" };
const Card = styled.div`
background: ${(p) => p.theme.bg};
color: ${(p) => p.theme.fg};
padding: 16px;
`;
export default function App() {
const [mode, setMode] = useState<"light" | "dark">("dark");
return (
<ThemeProvider theme={mode === "dark" ? dark : light}>
<Card>Hello</Card>
</ThemeProvider>
);
}
```
### Extending another styled component
```tsx
const Base = styled.button`padding: 8px; border-radius: 4px;`;
const Danger = styled(Base)`background: #e00; color: white;`;
```
### `as` polymorphic prop
```tsx
const Box = styled.div`padding: 16px;`;
<Box as="section" /> // renders <section>
<Box as={Link} to="/x" /> // renders react-router Link
```
### Keyframes animation
```tsx
import styled, { keyframes } from "styled-components";
const pulse = keyframes`
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
`;
const Pulser = styled.div`animation: ${pulse} 1s infinite;`;
```
### Global styles
```tsx
import { createGlobalStyle } from "styled-components";
const Global = createGlobalStyle`
body { margin: 0; font-family: Inter, sans-serif; background: ${(p) => p.theme.bg}; }
`;
```
### css helper for shared mixin
```tsx
import { css } from "styled-components";
const truncate = css`
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
const Title = styled.h2`${truncate} font-size: 24px;`;
```
### Next.js 14+ App Router (RSC) — 매 'use client'
```tsx
"use client";
import styled from "styled-components";
export const Button = styled.button`color: red;`;
```
```tsx
// app/layout.tsx — registry pattern for SSR
import StyledRegistry from "./StyledRegistry";
export default function Root({ children }) {
return <html><body><StyledRegistry>{children}</StyledRegistry></body></html>;
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| React SPA, 매 dynamic theming heavy | styled-components / emotion |
| React Server Components 의 native | vanilla-extract / CSS Modules / Tailwind |
| Utility-first, design system | Tailwind CSS v4 |
| Build-time zero-runtime | vanilla-extract / Linaria |
| Component lib for distribution | CSS Modules + tokens |
**기본값** (2026): 매 새 React project — Tailwind 의 default. styled-components 의 dynamic + theme heavy app 에 still-valid.
## 🔗 Graph
- 부모: [[CSS_Architecture_and_Styling|CSS-in-JS]] · [[React]]
- 변형: [[Vanilla Extract]]
- 응용: [[Design System]] · [[Theme Switching]]
- Adjacent: [[CSS_Architecture_and_Styling|Tailwind CSS]] · [[CSS Modules]] · [[React Server Components]]
## 🤖 LLM 활용
**언제**: dynamic prop-based styles 의 heavy, theme switching 의 first-class, existing CSS-in-JS app.
**언제 X**: 매 RSC-first new app — runtime cost + 'use client' boundary 의 friction. 매 Tailwind / vanilla-extract 의 prefer.
## ❌ 안티패턴
- **Inline style prop interpolation 의 every render**: 매 className thrash 의 perf hit. 매 attrs / static class 의 사용.
- **No `$` prefix on props**: 매 DOM warning (unknown attribute). 매 transient prop 의 사용 — `$primary`.
- **createGlobalStyle 의 multiple instances**: 매 conflict.
- **SSR without registry**: 매 FOUC. Next.js registry 의 setup.
## 🧪 검증 / 중복
- Verified (styled-components.com docs v6, 2025; Next.js 14 App Router CSS-in-JS guide).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — styled-components v6 + RSC era guidance |
@@ -0,0 +1,194 @@
---
id: wiki-2026-0508-technical-architecture
title: Technical Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [System Architecture, Tech Architecture, 기술 아키텍처]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, system-design, structure]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: agnostic
framework: C4/arc42
---
# Technical Architecture
## 매 한 줄
> **"매 system 의 high-level structure + 매 design decision 의 rationale"**. 매 component, 매 boundary, 매 data flow, 매 quality attribute (performance, security, scalability) 의 결정. 매 2026 modern stack 은 C4 model + ADR + arc42 의 combination 으로 documentation.
## 매 핵심
### 매 4+1 view (Kruchten 1995)
- **Logical**: 매 functional decomposition (class, module).
- **Process**: 매 runtime concurrency (thread, service).
- **Development**: 매 source code organization (package, repo).
- **Physical**: 매 deployment topology (node, network).
- **Scenarios**: 매 use case 의 cross-cutting validation.
### 매 C4 model (Brown 2018)
- **L1 Context**: 매 system + 매 external actors.
- **L2 Container**: 매 deployable unit (web app, DB, queue).
- **L3 Component**: 매 container 의 internal module.
- **L4 Code**: 매 class diagram (rarely needed).
### 매 quality attributes (ISO 25010)
- Performance · Scalability · Availability · Security · Maintainability · Testability · Observability.
- 매 trade-off 의 명시 — 매 "all of them" 은 fantasy.
### 매 응용
1. Greenfield project 시 C4 L1+L2 먼저, ADR 로 매 decision 기록.
2. Legacy reverse engineering — 매 dependency graph 추출 후 component view.
3. Architecture review — quality attribute scenario 의 validation.
## 💻 패턴
### C4 diagram (PlantUML)
```plantuml
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(user, "Customer")
System_Boundary(shop, "E-commerce") {
Container(web, "Web App", "Next.js 15")
Container(api, "API", "Node.js / Fastify")
ContainerDb(db, "Database", "Postgres 16")
Container(queue, "Queue", "Redis Streams")
}
System_Ext(stripe, "Stripe")
Rel(user, web, "Browses", "HTTPS")
Rel(web, api, "API calls", "JSON/HTTPS")
Rel(api, db, "Reads/Writes", "SQL")
Rel(api, queue, "Publishes events")
Rel(api, stripe, "Charges", "REST")
@enduml
```
### ADR template
```markdown
# ADR 0007: Choose Postgres over MongoDB
## Status: Accepted (2026-05-10)
## Context
Need primary store for order data. Strong consistency required.
Team has 5 years Postgres experience.
## Decision
Postgres 16 with JSONB for flexible product attributes.
## Consequences
+ ACID transactions for orders.
+ Mature ecosystem (Prisma, pgvector for AI features).
+ Single skill set for ops.
- Less flexible schema evolution.
- Manual sharding if scale > single node.
## Alternatives considered
- MongoDB: rejected — eventual consistency unsuitable for orders.
- DynamoDB: rejected — vendor lock-in, query flexibility.
```
### Hexagonal architecture (ports & adapters)
```typescript
// Domain (port)
interface OrderRepository {
save(order: Order): Promise<void>;
findById(id: string): Promise<Order | null>;
}
// Application
class PlaceOrderUseCase {
constructor(private repo: OrderRepository, private payments: PaymentGateway) {}
async execute(cmd: PlaceOrderCommand) {
const order = Order.create(cmd);
await this.payments.charge(order.total);
await this.repo.save(order);
}
}
// Infrastructure (adapter)
class PostgresOrderRepository implements OrderRepository {
async save(order: Order) { /* SQL */ }
async findById(id: string) { /* SQL */ }
}
```
### Layered architecture
```
┌─ Presentation (controllers, DTOs)
├─ Application (use cases)
├─ Domain (entities, value objects, services)
└─ Infrastructure (DB, HTTP, queue adapters)
```
### Event-driven boundary
```typescript
// Publisher (order service)
await events.publish('OrderPlaced', {
orderId: order.id,
customerId: order.customerId,
total: order.total.amount,
ts: Date.now(),
});
// Subscriber (notification service — independent deploy)
events.subscribe('OrderPlaced', async (e) => {
await emailClient.send(e.customerId, 'order-confirmation', e);
});
```
### Quality attribute scenario
```yaml
attribute: Performance
source: 1000 concurrent users
stimulus: place order
artifact: API
environment: peak load
response: order accepted
measure: p95 latency < 500ms, error rate < 0.1%
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Small team, single domain | Layered monolith |
| Multiple teams, bounded contexts | Microservices |
| Heavy I/O, async workflow | Event-driven |
| Domain-rich, complex rules | Hexagonal + DDD |
| Read-heavy, eventual consistency OK | CQRS + event sourcing |
**기본값**: 매 modular monolith 부터 시작 — 매 microservice 의 premature split 의 regret.
## 🔗 Graph
- 부모: [[Software_Architecture]] · [[System Design]]
- 변형: [[Microservices]] · [[Hexagonal Architecture]] · [[Event-Driven Architecture]]
- 응용: [[C4 Model]] · [[Architecture Decision Record]]
- Adjacent: [[Domain-Driven Design]] · [[Testability_Architecture]] · [[Technical_Debt]]
## 🤖 LLM 활용
**언제**: ADR drafting, C4 generation, quality attribute analysis, architecture review.
**언제 X**: 매 production 의 actual capacity planning — 매 real load test 필요.
## ❌ 안티패턴
- **Big design up front**: 매 waterfall 의 회귀.
- **No documentation**: 매 6개월 후 nobody knows why.
- **Microservices for 3 devs**: distributed monolith 의 distributed pain.
- **Cargo cult architecture**: Netflix scale 의 mimicry without justification.
## 🧪 검증 / 중복
- Verified (Kruchten 4+1 1995; Brown C4 2018; arc42 2024).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 4+1 + C4 + hexagonal patterns |
@@ -0,0 +1,172 @@
---
id: wiki-2026-0508-thought-architecture
title: Thought Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [생각 설계, Architecture of Thought, 사고 아키텍처]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, design-thinking, mental-model]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: conceptual
framework: software-architecture
---
# Thought Architecture
## 매 한 줄
> **"매 architecture 는 thought 의 외화 (externalization)"**. 매 system 의 구조는 매 designer 의 사고 모델을 그대로 반영. 2026 LLM-assisted era 에서도 매 핵심 thought structure 는 인간이 결정 — AI 는 elaboration / pattern matching.
## 매 핵심
### 매 layers of thought
- **What**: 도메인 / 문제 정의.
- **Why**: 매 가치 / 제약 / trade-off.
- **How**: 매 component / boundary / contract.
- **When**: 매 evolution / lifecycle.
### 매 thought-to-architecture mapping
- 매 mental concept → module.
- 매 invariant → contract / type.
- 매 change axis → seam / interface.
- 매 trust boundary → service / process boundary.
### 매 응용
1. Domain-Driven Design — 매 ubiquitous language ⇔ thought architecture.
2. Hexagonal — 매 core thought 는 안쪽, 매 details 는 바깥.
3. C4 model — 매 thought 의 zoom levels.
## 💻 패턴
### Concept-to-Module 매핑
```typescript
// 매 도메인 concept "Order" → module
// src/domain/order/
// order.ts // 매 entity (invariants 의 집)
// order-events.ts // 매 state transitions
// order-policy.ts // 매 business rules
export class Order {
private constructor(
readonly id: OrderId,
private state: OrderState,
private items: LineItem[],
) {}
static create(items: LineItem[]): Order {
if (items.length === 0) throw new Error('Empty order');
return new Order(OrderId.new(), 'pending', items);
}
confirm(): OrderConfirmed {
if (this.state !== 'pending') throw new Error('Bad state');
this.state = 'confirmed';
return { type: 'OrderConfirmed', orderId: this.id };
}
}
```
### Invariant-as-Type
```typescript
// 매 thought: "email 은 항상 valid 한 형식"
// 매 architecture: type 으로 enforce
type Email = string & { readonly __brand: 'Email' };
function parseEmail(raw: string): Email {
if (!/^[^@]+@[^@]+\.[^@]+$/.test(raw)) throw new Error('Invalid');
return raw as Email;
}
// 매 downstream 은 valid email 만 받음 — invariant 가 type 에 새겨짐
function send(to: Email, body: string) { /* ... */ }
```
### Change-axis-as-seam
```typescript
// 매 thought: "결제 provider 는 바뀔 수 있다"
// 매 architecture: interface seam
interface PaymentProvider {
charge(amount: Money, token: string): Promise<ChargeResult>;
}
class StripeProvider implements PaymentProvider { /* ... */ }
class TossProvider implements PaymentProvider { /* ... */ }
// 매 core 는 PaymentProvider 만 알고, 매 concrete 는 wiring 시 결정
```
### Trust-boundary-as-process
```typescript
// 매 thought: "user-supplied data 는 untrusted"
// 매 architecture: validation gateway
// gateway/api.ts
app.post('/orders', async (req, res) => {
const dto = OrderDto.parse(req.body); // 매 zod schema — boundary
const cmd = toCommand(dto);
await commandBus.dispatch(cmd);
res.json({ ok: true });
});
```
### C4-style zoom
```text
L1 Context: [User] → [ShopApp] → [PaymentProvider]
L2 Container: [Web] → [API] → [DB] / [Queue] → [Worker]
L3 Component: API = [Router] + [CommandHandler] + [Repository]
L4 Code: Repository = class with save/find methods
```
### Thought log → ADR
```markdown
# ADR-0042: Use event sourcing for orders
## Context
매 order state 는 audit trail 이 critical.
## Decision
매 event sourcing — state 는 events 의 fold.
## Consequences
- (+) 매 audit / replay 의 free.
- (-) 매 query 는 projection 필요.
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 domain 이 rich | DDD + concept-to-module |
| 매 changes axis 명확 | Hexagonal + seams |
| 매 communication 이 main concern | C4 + ADR |
| 매 thought 가 아직 흐림 | Spike → throw away → rebuild |
**기본값**: 매 concept-to-module mapping + ADR 의 light-weight 사용.
## 🔗 Graph
- 부모: [[Software_Architecture]] · [[Design_Thinking]]
- 변형: [[Domain_Driven_Design]] · [[Hexagonal_Architecture]] · [[C4_Model]]
- 응용: [[ADR]] · [[Ubiquitous_Language]]
- Adjacent: [[Mental_Model]] · [[Conceptual_Integrity]]
## 🤖 LLM 활용
**언제**: 매 ADR draft, 매 concept extraction, 매 module boundary 의 review.
**언제 X**: 매 core thought 의 결정 — 매 human 의 책임. LLM 은 매 elaboration 만.
## ❌ 안티패턴
- **Architecture without thought**: 매 framework 의 default 만 따라가기.
- **Thought without architecture**: 매 brilliant idea 가 매 code 에 reflect 되지 않음.
- **Premature crystallization**: 매 thought 가 흐릴 때 매 architecture 를 fix.
- **Over-abstraction**: 매 thought 보다 더 많은 layer.
## 🧪 검증 / 중복
- Verified (Brooks "Mythical Man-Month" — conceptual integrity, Evans DDD, Simon Brown C4).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content with thought-to-architecture mapping patterns |
@@ -0,0 +1,236 @@
---
id: wiki-2026-0508-threejs
title: Three.js
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Three.js, three, 3D web, WebGL library]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [3d, webgl, webgpu, graphics, threejs]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: three.js-r170
---
# Three.js
## 매 한 줄
> **"매 web 의 de-facto 3D library — WebGL/WebGPU 의 high-level wrapper"**. 매 scene graph + materials + lights + cameras + loaders. 2026 r170+ — WebGPURenderer stable, TSL (Three Shading Language), node-based materials. React 통합은 `@react-three/fiber`.
## 매 핵심
### 매 core entities
- **Scene**: 매 graph root.
- **Camera**: Perspective / Orthographic.
- **Renderer**: WebGLRenderer / WebGPURenderer.
- **Mesh** = Geometry + Material.
- **Light**: Ambient / Directional / Point / Spot.
### 매 render loop
- `requestAnimationFrame` → update → renderer.render(scene, camera).
- 매 r3f 는 자동 loop.
### 매 응용
1. Product configurator (3D customization).
2. Data visualization (graph, scatter).
3. WebXR (VR/AR).
4. Game / interactive art.
## 💻 패턴
### Vanilla minimal
```typescript
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 0.1, 1000,
);
camera.position.z = 5;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
const geo = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshStandardMaterial({ color: 0x6699ff });
const cube = new THREE.Mesh(geo, mat);
scene.add(cube);
scene.add(new THREE.AmbientLight(0xffffff, 0.4));
const dir = new THREE.DirectionalLight(0xffffff, 1);
dir.position.set(5, 5, 5);
scene.add(dir);
renderer.setAnimationLoop(() => {
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
});
```
### WebGPU renderer (r170+)
```typescript
import * as THREE from 'three/webgpu';
import { color, normalLocal } from 'three/tsl';
const renderer = new THREE.WebGPURenderer({ antialias: true });
await renderer.init();
const mat = new THREE.MeshBasicNodeMaterial();
mat.colorNode = color('#6699ff').mul(normalLocal.length());
```
### React Three Fiber
```tsx
import { Canvas, useFrame } from '@react-three/fiber';
import { OrbitControls, Environment } from '@react-three/drei';
import { useRef } from 'react';
import type { Mesh } from 'three';
function Box() {
const ref = useRef<Mesh>(null);
useFrame((_, dt) => {
if (ref.current) ref.current.rotation.y += dt;
});
return (
<mesh ref={ref}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="#6699ff" />
</mesh>
);
}
export default function App() {
return (
<Canvas camera={{ position: [3, 3, 3] }}>
<Environment preset="city" />
<Box />
<OrbitControls />
</Canvas>
);
}
```
### GLTF model loading
```typescript
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
const draco = new DRACOLoader();
draco.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/');
const loader = new GLTFLoader();
loader.setDRACOLoader(draco);
const gltf = await loader.loadAsync('/model.glb');
scene.add(gltf.scene);
```
```tsx
// r3f
import { useGLTF } from '@react-three/drei';
function Model() {
const { scene } = useGLTF('/model.glb');
return <primitive object={scene} />;
}
```
### Postprocessing
```typescript
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
composer.addPass(new UnrealBloomPass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
0.8, 0.4, 0.85,
));
renderer.setAnimationLoop(() => composer.render());
```
### Instanced rendering (10k+ objects)
```typescript
const count = 10_000;
const mesh = new THREE.InstancedMesh(geo, mat, count);
const dummy = new THREE.Object3D();
for (let i = 0; i < count; i++) {
dummy.position.set(
(Math.random() - 0.5) * 100,
(Math.random() - 0.5) * 100,
(Math.random() - 0.5) * 100,
);
dummy.updateMatrix();
mesh.setMatrixAt(i, dummy.matrix);
}
scene.add(mesh);
```
### Disposal (memory)
```typescript
function dispose(obj: THREE.Object3D) {
obj.traverse((child) => {
if ((child as THREE.Mesh).isMesh) {
const m = child as THREE.Mesh;
m.geometry.dispose();
const mats = Array.isArray(m.material) ? m.material : [m.material];
mats.forEach((mat) => mat.dispose());
}
});
}
```
### WebXR (VR)
```typescript
renderer.xr.enabled = true;
import { VRButton } from 'three/addons/webxr/VRButton.js';
document.body.appendChild(VRButton.createButton(renderer));
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 React app | `@react-three/fiber` + drei |
| 매 vanilla / lib | three.js direct |
| 매 GPU compute / advanced shader | WebGPURenderer + TSL |
| 매 game | Babylon.js / PlayCanvas (more game-oriented) |
| 매 declarative UI integration | r3f (preferred) |
**기본값**: 매 React → r3f + drei. 매 그 외 → three.js + addons.
## 🔗 Graph
- 부모: [[3D_Web]] · [[WebGL]]
- 변형: [[Babylon_js]]
- 응용: [[React_Three_Fiber]] · [[drei]] · [[WebXR]]
- Adjacent: [[Shader]] · [[WebGPU]]
## 🤖 LLM 활용
**언제**: 매 scene scaffold, 매 shader translate, 매 r3f component generation.
**언제 X**: 매 production shader optimization — 매 hand-tune 필요.
## ❌ 안티패턴
- **Forgetting dispose**: 매 GPU memory leak.
- **`new THREE.X` in render loop**: 매 GC pressure.
- **No `setPixelRatio`**: 매 retina blurry.
- **Many individual meshes**: 매 instancing 의 사용.
- **Direct DOM rerender on every frame**: 매 r3f 의 자동 loop 무시.
## 🧪 검증 / 중복
- Verified (three.js r170 docs, react-three/fiber docs, mrdoob, 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Three.js r170 with WebGPU, TSL, r3f, instancing |
@@ -0,0 +1,199 @@
---
id: wiki-2026-0508-type-casting
title: Type Casting
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [타입 캐스팅, Type Assertion, as 단언]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, types, casting, assertion]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: typescript-5.6
---
# Type Casting
## 매 한 줄
> **"매 TypeScript 의 'casting' 은 runtime conversion 아님 — 매 compile-time assertion"**. 매 `as` 는 매 'I know more than you, compiler'. 2026 TS 5.6 — `satisfies` + branded types 가 매 unsafe `as` 의 대부분 대체.
## 매 핵심
### 매 종류
- **Type Assertion** (`as T`): compile-time only — runtime no-op.
- **Type Casting** (other languages): runtime conversion.
- **`satisfies T`**: 매 assertion 없이 type check.
- **Type Guard**: runtime check + type narrow.
### 매 종류 비교
-`value as T` — 매 unsafe (TS 가 검증 안함).
-`value satisfies T` — 매 safe (TS 가 검증, 매 narrowing 보존).
-`value as unknown as T` — 매 double assertion (마지막 escape).
-`<T>value` — 매 old syntax, JSX 와 conflict.
### 매 응용
1. 매 JSON parse → typed.
2. 매 narrowed type 의 explicit signal.
3. 매 const assertion (`as const`) — literal type.
## 💻 패턴
### Type assertion
```typescript
const el = document.getElementById('app') as HTMLDivElement;
// 매 unsafe — element 가 div 가 아니면 runtime error 가능
```
### Safer: type guard
```typescript
const el = document.getElementById('app');
if (el instanceof HTMLDivElement) {
el.innerText = 'hi'; // 매 narrowed safely
}
```
### `satisfies` (preferred)
```typescript
type Color = 'red' | 'green' | 'blue';
type Palette = Record<Color, string>;
// 매 satisfies — type check + literal preserve
const palette = {
red: '#ff0000',
green: '#00ff00',
blue: '#0000ff',
} satisfies Palette;
palette.red.toUpperCase(); // ✅ string method 사용 가능
// 매 vs as — narrowing 잃음
const palette2 = {
red: '#ff0000',
green: '#00ff00',
blue: '#0000ff',
} as Palette;
// palette2.red 는 string 으로 widen 됨 — 매 literal 잃음
```
### `as const`
```typescript
const config = {
api: 'https://api.example.com',
retries: 3,
methods: ['GET', 'POST'],
} as const;
// 매 deeply readonly + literal types
// type: { readonly api: 'https://...', readonly retries: 3, readonly methods: readonly ['GET', 'POST'] }
```
### JSON parse with validation (zod)
```typescript
import { z } from 'zod';
const UserSchema = z.object({
id: z.string(),
name: z.string(),
age: z.number().int().min(0),
});
type User = z.infer<typeof UserSchema>;
function parseUser(raw: unknown): User {
return UserSchema.parse(raw); // 매 runtime validation + type
// 매 NOT: return raw as User — unsafe
}
```
### Branded types (nominal)
```typescript
type UserId = string & { readonly __brand: 'UserId' };
type OrderId = string & { readonly __brand: 'OrderId' };
function toUserId(s: string): UserId { return s as UserId; }
function toOrderId(s: string): OrderId { return s as OrderId; }
const u: UserId = toUserId('u_1');
const o: OrderId = toOrderId('o_1');
function getUser(id: UserId) { /* ... */ }
getUser(u); // ✅
// getUser(o); // ❌ — branded mismatch
// getUser('u_1'); // ❌ — bare string
```
### Double assertion (last resort)
```typescript
const fromAny = (someJsValue as unknown) as MyType;
// 매 use only when 매 truly necessary — 매 escape hatch
```
### `unknown` over `any`
```typescript
// ❌ any — type system bypass
function bad(x: any) { x.foo.bar; } // 매 no error
// ✅ unknown — must narrow
function good(x: unknown) {
if (typeof x === 'object' && x !== null && 'foo' in x) {
// 매 narrowed
}
}
```
### Discriminated union narrowing
```typescript
type Shape =
| { kind: 'circle'; r: number }
| { kind: 'square'; s: number };
function area(shape: Shape): number {
switch (shape.kind) {
case 'circle': return Math.PI * shape.r ** 2; // 매 narrowed
case 'square': return shape.s ** 2;
}
}
// 매 NO assertion needed — 매 narrowing 자동
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 external data | zod / valibot — runtime validation |
| 매 config object literal | `satisfies` |
| 매 immutable config | `as const` |
| 매 nominal distinction | branded types |
| 매 DOM element | `instanceof` guard |
| 매 truly impossible to express | `as unknown as T` (last resort) |
**기본값**: 매 `as` 의 회피. 매 satisfies / guard / schema 의 사용.
## 🔗 Graph
- 부모: [[TypeScript]]
- 변형: [[Type_Assertion]] · [[Type_Guard]] · [[Branded_Types]]
- 응용: [[Zod]]
- Adjacent: [[Discriminated_Union]]
## 🤖 LLM 활용
**언제**: 매 `as` 의 alternative 제안, 매 zod schema 생성, 매 brand pattern.
**언제 X**: 매 actual runtime conversion 필요 — 매 TS casting 은 no-op.
## ❌ 안티패턴
- **`as any`**: 매 type system 의 포기.
- **`as` to silence error**: 매 root cause 미해결.
- **`as T` for parsed JSON**: 매 unvalidated trust.
- **Old `<T>` syntax in TSX**: 매 conflict — 매 `as` 사용.
## 🧪 검증 / 중복
- Verified (TS 5.6 handbook, satisfies operator RFC, zod docs, 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — TS type casting with satisfies, branded types, zod |
@@ -0,0 +1,210 @@
---
id: wiki-2026-0508-uber-base-web
title: Uber Base Web
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Base Web, baseui, Uber Base, base-ui (uber)]
duplicate_of: none
source_trust_level: A
confidence_score: 0.85
verification_status: applied
tags: [react, design-system, uber, baseweb, components]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: react-baseweb
---
# Uber Base Web
## 매 한 줄
> **"매 Uber 의 React design system — 매 themeable, 매 accessible, 매 styletron-based"**. 2026 현재 Base Web 은 maintenance mode — 매 active development 는 적음. 매 최신 stack 은 보통 Radix / shadcn / Tailwind 의 선호. 매 historical / 매 enterprise reference.
## 매 핵심
### 매 layers
- **Components**: Button, Input, Modal, DataTable, Picker, etc.
- **Styletron**: CSS-in-JS engine — atomic CSS output.
- **Theme**: tokens (color, typography, spacing, sizing).
- **Overrides API**: deep customization 의 매 unique mechanism.
### 매 Overrides 특징
- 매 component 의 매 sub-part (`Root`, `Label`, `Input`, etc.) 를 매 style/component/props 의 override.
- 매 powerful 하지만 매 verbose.
### 매 응용
1. Uber internal apps (전통적).
2. Enterprise dashboards / data-heavy SaaS.
3. 매 highly-themeable products.
## 💻 패턴
### Setup
```bash
npm i baseui styletron-engine-monolithic styletron-react react react-dom
```
```tsx
import { Provider as StyletronProvider } from 'styletron-react';
import { Client as Styletron } from 'styletron-engine-monolithic';
import { LightTheme, BaseProvider } from 'baseui';
const engine = new Styletron();
export function App({ children }: { children: React.ReactNode }) {
return (
<StyletronProvider value={engine}>
<BaseProvider theme={LightTheme}>
{children}
</BaseProvider>
</StyletronProvider>
);
}
```
### Button
```tsx
import { Button, KIND, SIZE, SHAPE } from 'baseui/button';
<Button kind={KIND.primary} size={SIZE.compact} shape={SHAPE.pill}>
Save
</Button>
```
### Form input
```tsx
import { FormControl } from 'baseui/form-control';
import { Input } from 'baseui/input';
<FormControl label="Email" caption="We never share">
<Input value={email} onChange={(e) => setEmail(e.currentTarget.value)} />
</FormControl>
```
### Modal
```tsx
import { Modal, ModalHeader, ModalBody, ModalFooter, ModalButton } from 'baseui/modal';
<Modal isOpen={open} onClose={() => setOpen(false)}>
<ModalHeader>Confirm</ModalHeader>
<ModalBody>Delete this?</ModalBody>
<ModalFooter>
<ModalButton kind="tertiary" onClick={() => setOpen(false)}>Cancel</ModalButton>
<ModalButton onClick={onConfirm}>Delete</ModalButton>
</ModalFooter>
</Modal>
```
### Overrides API
```tsx
import { Button } from 'baseui/button';
<Button
overrides={{
BaseButton: {
style: ({ $theme }) => ({
borderRadius: '999px',
backgroundColor: $theme.colors.accent,
':hover': { backgroundColor: $theme.colors.accent700 },
}),
},
}}
>
Custom
</Button>
```
### Custom theme
```tsx
import { createTheme, lightThemePrimitives, BaseProvider } from 'baseui';
const primitives = {
...lightThemePrimitives,
primaryFontFamily: 'Inter, system-ui, sans-serif',
};
const overrides = {
colors: {
buttonPrimaryFill: '#0F62FE',
buttonPrimaryHover: '#0353E9',
},
};
const theme = createTheme(primitives, overrides);
<BaseProvider theme={theme}>...</BaseProvider>
```
### DataTable (heavy)
```tsx
import { Unstable_StatefulDataTable as DataTable } from 'baseui/data-table';
import { StringColumn, NumericalColumn } from 'baseui/data-table';
const columns = [
StringColumn({ title: 'Name', mapDataToValue: (d: Row) => d.name }),
NumericalColumn({ title: 'Score', mapDataToValue: (d: Row) => d.score }),
];
<div style={{ height: 500 }}>
<DataTable columns={columns} rows={rows.map(r => ({ id: r.id, data: r }))} />
</div>
```
### Server-side rendering
```tsx
// Next.js _document.tsx
import { Server, Sheet } from 'styletron-engine-monolithic';
const engine = new Server();
// 매 render 후 engine.getStylesheets() → 매 inject to head
```
### Migration off (2026 trend)
```text
Base Web component → 매 Modern alternative
─────────────────────────────────────────────
Button → shadcn/ui Button (Radix Slot + Tailwind)
Modal → Radix Dialog + Tailwind
Input/FormControl → react-hook-form + Radix + Tailwind
DataTable → TanStack Table + Tailwind
Theme → CSS variables / Tailwind tokens
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 existing Uber/Base Web codebase | 유지 — incremental migration |
| 매 new project (2026) | shadcn/ui + Radix + Tailwind 또는 Mantine |
| 매 enterprise / internal tool | Mantine / Ant Design |
| 매 mobile-web heavy | Tamagui / NativeBase |
**기본값**: 매 new project 는 매 Base Web 의 회피. 매 modern stack 사용.
## 🔗 Graph
- 부모: [[Design_System]]
- 변형: [[shadcn_ui]]
- 응용: [[Styletron]]
- Adjacent: [[Radix_UI]] · [[Tailwind_CSS]]
## 🤖 LLM 활용
**언제**: 매 Overrides API debug, 매 theme migration, 매 Base Web → modern stack 변환.
**언제 X**: 매 new greenfield project — 매 더 modern alternative.
## ❌ 안티패턴
- **Overrides everywhere**: 매 verbose + 매 maintenance burden.
- **Mixing styletron + emotion**: 매 dual CSS-in-JS conflict.
- **No SSR setup**: 매 FOUC.
- **Greenfield Base Web in 2026**: 매 ecosystem 가 늙음.
## 🧪 검증 / 중복
- Verified (Base Web docs, Uber Engineering blog, GitHub uber/baseweb, 2026 maintenance status).
- 신뢰도 A-.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Base Web with Overrides API, theming, migration notes |
@@ -0,0 +1,184 @@
---
id: wiki-2026-0508-web-rendering-strategies-csr-vs-
title: Web Rendering Strategies — CSR vs SSR
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [CSR vs SSR, SSG, ISR, Rendering Strategies, Hybrid Rendering]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [rendering, ssr, csr, ssg, isr, frontend, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: nextjs
---
# Web Rendering Strategies — CSR vs SSR
## 매 한 줄
> **"매 어디서 render 매 (server/build/client/edge), 매 언제 (request/build/runtime), 매 무엇 (static/dynamic) — 매 이 3 축 의 매 trade-off"**. 매 2026 매 hybrid (RSC + Streaming SSR + ISR + Edge) 매 default — Next.js / Nuxt / Remix / SvelteKit / Astro 매 모두 mix.
## 매 핵심
### 매 5 가지 strategy
- **CSR (Client-Side Rendering)**: empty HTML + JS bundle → browser 매 render. SPA classic.
- **SSR (Server-Side Rendering)**: per-request HTML on server.
- **SSG (Static Site Generation)**: build-time HTML.
- **ISR (Incremental Static Regeneration)**: SSG + on-demand or time-based revalidate.
- **RSC (React Server Components, 2023~)**: server-only component, zero JS ship for that part.
### 매 핵심 metric
- **TTFB**: server response time.
- **FCP / LCP**: 매 visible content speed.
- **TTI**: 매 interactive — hydration cost.
- **INP**: 매 interaction latency (FID 의 후속, Core Web Vitals 2024+).
- **JS bundle**: 매 작을 수록 hydration fast.
### 매 응용
1. Marketing site → SSG / ISR (Astro, Next).
2. E-commerce → ISR + dynamic SSR for cart.
3. Dashboard / admin → CSR or SSR with auth.
4. Blog → SSG + ISR.
5. Real-time chat → CSR + SSE/WebSocket.
6. News site → ISR (revalidate every 60s).
## 💻 패턴
### Next.js App Router (RSC + streaming)
```tsx
// app/products/[id]/page.tsx — RSC, fetched on server, no JS shipped
export default async function ProductPage({ params }: { params: { id: string } }) {
const product = await db.product.findUnique({ where: { id: params.id } });
return (
<article>
<h1>{product.name}</h1>
<Suspense fallback={<Skeleton />}>
<Reviews productId={params.id} />
</Suspense>
</article>
);
}
```
### ISR with revalidate
```tsx
// Next.js — 매 60s 마다 background regenerate
export const revalidate = 60;
export default async function Posts() {
const posts = await fetch("https://api.example.com/posts").then((r) => r.json());
return <ul>{posts.map((p) => <li key={p.id}>{p.title}</li>)}</ul>;
}
```
### SSG with `generateStaticParams`
```tsx
export async function generateStaticParams() {
const slugs = await getAllSlugs();
return slugs.map((slug) => ({ slug }));
}
```
### CSR via dynamic + ssr:false
```tsx
"use client";
import dynamic from "next/dynamic";
const Chart = dynamic(() => import("./HeavyChart"), { ssr: false });
export default function Page() { return <Chart />; }
```
### Streaming SSR (Suspense)
```tsx
// app/dashboard/page.tsx
export default function Dashboard() {
return (
<>
<Header />
<Suspense fallback={<Skel />}><SlowWidget /></Suspense>
<Suspense fallback={<Skel />}><AnotherSlow /></Suspense>
</>
);
}
// 매 shell 먼저 flush, 매 widget ready 시 stream
```
### Edge runtime (Vercel / Cloudflare Workers)
```ts
// Next.js — Edge 매 cold start 매 0 에 가까움
export const runtime = "edge";
export async function GET(req: Request) {
const country = req.headers.get("x-vercel-ip-country") ?? "US";
return new Response(`Hello from ${country}`);
}
```
### Astro islands
```astro
---
// 매 default static, 매 island 만 hydrate
import Counter from "../components/Counter.tsx";
const posts = await fetch("...").then((r) => r.json());
---
<html>
<body>
{posts.map((p) => <article><h2>{p.title}</h2></article>)}
<Counter client:visible /> <!-- viewport entry 시 hydrate -->
</body>
</html>
```
### On-demand revalidation
```ts
// Next.js — webhook 받으면 매 즉시 invalidate
import { revalidateTag, revalidatePath } from "next/cache";
export async function POST(req: Request) {
const { tag } = await req.json();
revalidateTag(tag);
return Response.json({ ok: true });
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Static marketing | SSG / Astro |
| Blog with comments | SSG + CSR comments |
| News feed (changes hourly) | ISR (revalidate=3600) |
| Product page + cart | RSC + Client island for cart |
| Real-time dashboard | CSR + WebSocket |
| Geo-personalized | Edge SSR |
| Authenticated app | SSR with auth + RSC |
**기본값**: Next.js App Router (RSC default) + Suspense streaming + ISR for content. 매 client component 매 조심히.
## 🔗 Graph
- 부모: [[Large_Frontend_Projects|Frontend Architecture]] · [[Web Performance]]
- 변형: [[CSR]] · [[SSR]] · [[SSG]] · [[ISR]] · [[RSC]]
- 응용: [[Astro]] · [[SvelteKit]] · [[Remix]]
- Adjacent: [[Streaming SSR]] · [[Edge Runtime]] · [[Hydration]] · [[Core Web Vitals Optimization (INP, LCP 개선)|Core Web Vitals]] · [[Islands Architecture]]
## 🤖 LLM 활용
**언제**: Rendering strategy 결정, Next.js / Nuxt / Astro setup, Core Web Vitals tuning.
**언제 X**: Pure native app, internal CLI, embedded device UI.
## ❌ 안티패턴
- **CSR for SEO-critical content**: 매 crawler 매 problem.
- **SSR everywhere without caching**: 매 server CPU 폭발 — ISR / cache 도입.
- **Hydration mismatch**: server HTML ≠ client render — 매 console error + flicker.
- **Massive client bundle**: 매 hydration TTI 늦어짐 — RSC / island 활용.
- **No streaming**: 매 slow API 매 entire page block — Suspense.
- **Misuse of `"use client"`**: 매 RSC tree 의 매 leaf 만 client.
## 🧪 검증 / 중복
- Verified (Next.js 15 docs, Vercel team blog, web.dev rendering guide 2025).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — RSC, streaming, ISR, edge runtime patterns |
@@ -0,0 +1,189 @@
---
id: wiki-2026-0508-webgl
title: WebGL
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [WebGL2, Web Graphics Library]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [graphics, web, gpu, opengl]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript
framework: WebGL2 / WebGPU
---
# WebGL
## 매 한 줄
> **"매 OpenGL ES 의 browser 포팅 — 매 GPU 직접 access 의 web standard."**. 2011 WebGL 1.0 (OpenGL ES 2.0 base), 2017 WebGL 2.0 (ES 3.0 base). 매 2026 modern web 은 WebGPU 로 transition 중이지만, WebGL 은 매 universal compatibility (iOS Safari 포함) 의 fallback 로 여전히 dominant.
## 매 핵심
### 매 architecture
- **Context**: `canvas.getContext('webgl2')` — 매 single global state machine.
- **Pipeline**: vertex shader → rasterization → fragment shader. 매 fixed-function 의 X.
- **Buffers**: VBO (vertex), IBO (index), FBO (framebuffer), UBO (uniform).
- **Shaders**: GLSL ES 3.00 — 매 string 으로 compile, link 후 use.
### 매 vs WebGPU (2026)
- **WebGL**: 매 universally available. 매 single-threaded driver. 매 immediate-mode binding.
- **WebGPU**: 매 modern (Vulkan/Metal/D3D12 mapping). 매 compute shader. 매 explicit pipeline. 매 Chrome/Edge/Firefox stable, Safari 18+ partial.
- **2026 default**: 매 new project 는 WebGPU + WebGL fallback. 매 existing codebase 는 WebGL 유지.
### 매 응용
1. Three.js / Babylon.js — 매 3D engine.
2. Map rendering (Mapbox GL, deck.gl).
3. Data viz (PixiJS, regl).
4. Game (Unity WebGL, Unreal HTML5 export).
## 💻 패턴
### Context creation + 매 capability check
```javascript
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2', {
antialias: true,
alpha: false,
preserveDrawingBuffer: false,
powerPreference: 'high-performance',
});
if (!gl) throw new Error('WebGL2 unsupported');
console.log('Max texture size:', gl.getParameter(gl.MAX_TEXTURE_SIZE));
```
### Shader compile helper
```javascript
function compileShader(gl, src, type) {
const sh = gl.createShader(type);
gl.shaderSource(sh, src);
gl.compileShader(sh);
if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
const log = gl.getShaderInfoLog(sh);
gl.deleteShader(sh);
throw new Error(`Shader compile error: ${log}`);
}
return sh;
}
function linkProgram(gl, vsSrc, fsSrc) {
const p = gl.createProgram();
gl.attachShader(p, compileShader(gl, vsSrc, gl.VERTEX_SHADER));
gl.attachShader(p, compileShader(gl, fsSrc, gl.FRAGMENT_SHADER));
gl.linkProgram(p);
if (!gl.getProgramParameter(p, gl.LINK_STATUS))
throw new Error(gl.getProgramInfoLog(p));
return p;
}
```
### VAO + indexed draw
```javascript
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
const ibo = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
gl.bindVertexArray(null);
// draw
gl.bindVertexArray(vao);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
```
### Instanced rendering (WebGL2)
```javascript
gl.bindBuffer(gl.ARRAY_BUFFER, instanceMatrixBuf);
for (let i = 0; i < 4; i++) {
gl.enableVertexAttribArray(2 + i);
gl.vertexAttribPointer(2 + i, 4, gl.FLOAT, false, 64, i * 16);
gl.vertexAttribDivisor(2 + i, 1); // per-instance
}
gl.drawElementsInstanced(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0, 10000);
```
### Render-to-texture (FBO)
```javascript
const fbo = gl.createFramebuffer();
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 1024, 1024, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE)
throw new Error('FBO incomplete');
```
### Lost context handling
```javascript
canvas.addEventListener('webglcontextlost', (e) => {
e.preventDefault();
cancelAnimationFrame(rafId);
});
canvas.addEventListener('webglcontextrestored', () => {
reinitGLResources(); // 매 mandatory
rafId = requestAnimationFrame(render);
});
```
### Resize 매 DPR aware
```javascript
function resize() {
const dpr = Math.min(window.devicePixelRatio, 2);
const w = Math.floor(canvas.clientWidth * dpr);
const h = Math.floor(canvas.clientHeight * dpr);
if (canvas.width !== w || canvas.height !== h) {
canvas.width = w; canvas.height = h;
gl.viewport(0, 0, w, h);
}
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 new 2026 project, modern browser only | WebGPU |
| 매 universal compat (iOS old) | WebGL2 |
| 매 high-level 3D | Three.js / Babylon |
| 매 low-overhead 2D | regl, PixiJS |
| 매 compute heavy | WebGPU compute shader |
**기본값**: 매 high-level engine (Three.js) — 매 raw WebGL 은 매 specific need.
## 🔗 Graph
- 부모: [[Graphics_Pipeline]]
- 변형: [[WebGPU]] · [[OpenGL_ES]]
- 응용: [[Three.js]] · [[Babylon.js]]
- Adjacent: [[GLSL]]
## 🤖 LLM 활용
**언제**: 매 web 3D, data viz, browser-based game, AR/VR (WebXR).
**언제 X**: 매 native-only performance critical (WebAssembly + WebGPU 도 부족 시 native).
## ❌ 안티패턴
- **매 frame draw call 폭증**: 매 instancing / batching 의 X — 1000+ draw call 은 매 CPU bound.
- **State leak**: 매 bind 후 unbind X — 매 다음 frame state pollute.
- **getError() 매 production loop**: 매 sync stall — 매 dev only.
- **매 lost context 무시**: 매 mobile 에서 흔함, recovery path 매 mandatory.
## 🧪 검증 / 중복
- Verified (Khronos WebGL2 spec, MDN, WebGL Fundamentals).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — WebGL2 patterns + WebGPU transition note |
@@ -0,0 +1,197 @@
---
id: wiki-2026-0508-webgpu
title: WebGPU
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [WebGPU API, WGSL, GPU Web]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [graphics, gpu, web, wgsl, compute]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: webgpu
---
# WebGPU
## 매 한 줄
> **"매 modern explicit GPU API 매 browser 에 — Vulkan / Metal / D3D12 의 매 abstraction"**. 매 WebGL 의 매 후계자, 매 2023 매 Chrome 113 ship, 매 2026 매 Safari 18 / Firefox 130 stable, ML inference (transformers.js, ONNX Runtime Web) 와 high-end browser game 의 standard.
## 매 핵심
### 매 vs WebGL
- WebGL: OpenGL ES 2.0 / 3.0 기반 — implicit state, fixed pipeline parts.
- WebGPU: Vulkan / Metal style — explicit pipeline state object, compute shader native.
- WGSL (WebGPU Shading Language): Rust-like syntax, browser 매 portable.
### 매 핵심 객체
- **Adapter**: physical GPU.
- **Device**: logical handle — buffer, texture, pipeline 만들기 사용.
- **Queue**: command submission.
- **Buffer / Texture**: GPU memory.
- **BindGroup**: shader 매 resource binding.
- **RenderPipeline / ComputePipeline**: compiled shader + state.
- **CommandEncoder → CommandBuffer**: GPU 명령 record + submit.
### 매 응용
1. transformers.js / ONNX Runtime Web: GPU-accelerated LLM in browser.
2. Babylon.js / Three.js (WebGPURenderer): high-end web 3D.
3. Figma / Canva: GPU-accelerated 2D.
4. Stable Diffusion Web (web-stable-diffusion).
5. Real-time particle / fluid sim (GPGPU).
## 💻 패턴
### Init + clear screen
```ts
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) throw new Error("No WebGPU adapter");
const device = await adapter.requestDevice();
const canvas = document.querySelector("canvas")!;
const ctx = canvas.getContext("webgpu")!;
const format = navigator.gpu.getPreferredCanvasFormat();
ctx.configure({ device, format, alphaMode: "premultiplied" });
const enc = device.createCommandEncoder();
const pass = enc.beginRenderPass({
colorAttachments: [{
view: ctx.getCurrentTexture().createView(),
clearValue: { r: 0.1, g: 0.1, b: 0.15, a: 1 },
loadOp: "clear", storeOp: "store",
}],
});
pass.end();
device.queue.submit([enc.finish()]);
```
### Triangle render pipeline
```ts
const shader = device.createShaderModule({ code: `
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
let p = array(vec2f(0,0.5), vec2f(-0.5,-0.5), vec2f(0.5,-0.5));
return vec4f(p[i], 0, 1);
}
@fragment fn fs() -> @location(0) vec4f { return vec4f(1, 0.4, 0.2, 1); }
`});
const pipeline = device.createRenderPipeline({
layout: "auto",
vertex: { module: shader, entryPoint: "vs" },
fragment: { module: shader, entryPoint: "fs", targets: [{ format }] },
primitive: { topology: "triangle-list" },
});
```
### Uniform buffer + bind group
```ts
const uniform = device.createBuffer({
size: 16, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(uniform, 0, new Float32Array([0.5, 0.2, 0.8, 1]));
const bg = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [{ binding: 0, resource: { buffer: uniform } }],
});
```
### Compute shader (vector add)
```ts
const code = `
@group(0) @binding(0) var<storage, read> a: array<f32>;
@group(0) @binding(1) var<storage, read> b: array<f32>;
@group(0) @binding(2) var<storage, read_write> out: array<f32>;
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) id: vec3u) {
let i = id.x;
if (i >= arrayLength(&out)) { return; }
out[i] = a[i] + b[i];
}
`;
const cs = device.createShaderModule({ code });
const cp = device.createComputePipeline({
layout: "auto", compute: { module: cs, entryPoint: "main" },
});
// dispatch: workgroups = ceil(N / 64)
```
### Storage buffer readback
```ts
async function readBuffer(src: GPUBuffer, size: number) {
const staging = device.createBuffer({
size, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
});
const enc = device.createCommandEncoder();
enc.copyBufferToBuffer(src, 0, staging, 0, size);
device.queue.submit([enc.finish()]);
await staging.mapAsync(GPUMapMode.READ);
const data = new Float32Array(staging.getMappedRange().slice(0));
staging.unmap();
return data;
}
```
### Texture upload (ImageBitmap)
```ts
const bmp = await createImageBitmap(await (await fetch("/img.png")).blob());
const tex = device.createTexture({
size: [bmp.width, bmp.height], format: "rgba8unorm",
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
});
device.queue.copyExternalImageToTexture({ source: bmp }, { texture: tex }, [bmp.width, bmp.height]);
```
### Device-lost handling
```ts
device.lost.then((info) => {
console.error("Device lost:", info.message, info.reason);
if (info.reason !== "destroyed") {
// 매 reinit pipeline
}
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 2D canvas, simple chart | Canvas2D / SVG |
| Standard 3D (low-mid) | Three.js (auto WebGL/WebGPU) |
| GPGPU / ML inference | WebGPU + WGSL compute |
| Cutting-edge graphics demo | WebGPU direct |
| Wide compatibility (old Safari, Android Go) | WebGL2 fallback 유지 |
**기본값**: 신규 project 매 WebGPU + WebGL2 fallback (Three.js / Babylon 매 자동).
## 🔗 Graph
- 변형: [[WebGL]] · [[WebGL 20|WebGL2]] · [[Vulkan]] · [[Metal]]
- 응용: [[Three.js WebGPU]] · [[Babylon.js]]
- Adjacent: [[WGSL]] · [[GPGPU]] · [[Compute Shader]]
## 🤖 LLM 활용
**언제**: Browser-side ML, high-end web visualization, GPGPU port to browser.
**언제 X**: Old browser support 필수 (use WebGL2), simple UI animation (CSS / Canvas2D 충분).
## ❌ 안티패턴
- **WebGPU global singleton 매 sync init**: 매 async — `await requestAdapter`.
- **Buffer leak**: `destroy()` 안 부름 — long-running app 매 OOM.
- **Per-frame pipeline create**: 매 expensive — 매 cache.
- **Bind group mismatch**: layout/binding index mismatch 매 silent error 의 매 source.
- **No fallback path**: 매 unsupported environment 매 blank screen — feature detect 필수.
- **Texture without proper usage flags**: 매 runtime validation error.
## 🧪 검증 / 중복
- Verified (W3C WebGPU spec 2024 CR, Chrome 130 release notes, Safari 18 WebGPU enablement).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — pipeline init, compute shader, ML inference patterns |
@@ -0,0 +1,215 @@
---
id: wiki-2026-0508-grpc-and-protocol-buffers
title: gRPC and Protocol Buffers
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [gRPC, Protobuf, protocol-buffers]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [rpc, networking, protobuf, microservices, http2]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Multi (Go, Rust, TS, Python)
framework: gRPC + Protobuf 3 / Edition 2024
---
# gRPC and Protocol Buffers
## 매 한 줄
> **"매 schema-first IDL + HTTP/2 RPC + binary serialization 의 stack."**. Protocol Buffers 는 2008 Google 공개, gRPC 는 2015 OSS — 매 internal Stubby 의 successor. 매 2026 microservice / cross-language API 의 매 default — 매 REST+JSON 보다 5-10× compact, 매 streaming 매 native, 매 contract 강제.
## 매 핵심
### 매 Protocol Buffers
- **Schema**: `.proto` file — 매 message + service 정의.
- **Wire format**: tag-length-value, varint encoding — 매 forward/backward compat (unknown field 보존).
- **Edition 2024**: `proto2` / `proto3` 의 통합 — 매 explicit feature flag.
- **Compiler**: `protoc` + plugin (go, ts-proto, prost, python-betterproto).
### 매 gRPC
- **Transport**: HTTP/2 — 매 multiplexing, header compression (HPACK).
- **4 RPC types**: unary, server-stream, client-stream, bidi-stream.
- **Status codes**: 매 `OK`, `INVALID_ARGUMENT`, `UNAUTHENTICATED`, `DEADLINE_EXCEEDED` (16개 표준).
- **Deadline**: 매 client → server propagate. 매 RPC chain 매 cumulative.
- **Metadata**: 매 trailer/header — auth token, trace.
- **gRPC-Web**: 매 browser support (HTTP/1.1 fallback proxy).
- **Connect / gRPC-Gateway**: 매 REST+gRPC dual.
### 매 응용
1. Microservice internal RPC.
2. Mobile ↔ backend (Square, Netflix).
3. Service mesh (Envoy, Istio).
4. Streaming (live ML inference, IoT).
## 💻 패턴
### .proto schema
```protobuf
edition = "2024";
package shop.v1;
option go_package = "github.com/example/shop/v1;shopv1";
service Catalog {
rpc GetProduct(GetProductRequest) returns (Product);
rpc StreamUpdates(StreamUpdatesRequest) returns (stream ProductUpdate);
rpc UploadImages(stream Image) returns (UploadAck);
rpc Chat(stream ChatMsg) returns (stream ChatMsg);
}
message GetProductRequest {
string id = 1;
}
message Product {
string id = 1;
string name = 2;
int64 price_cents = 3;
repeated string tags = 4;
google.protobuf.Timestamp updated_at = 5;
}
```
### Go server (unary + stream)
```go
type catalogServer struct{ shopv1.UnimplementedCatalogServer }
func (s *catalogServer) GetProduct(ctx context.Context, req *shopv1.GetProductRequest) (*shopv1.Product, error) {
if req.Id == "" {
return nil, status.Error(codes.InvalidArgument, "id required")
}
p, err := s.db.Find(ctx, req.Id)
if errors.Is(err, sql.ErrNoRows) {
return nil, status.Error(codes.NotFound, "product missing")
}
return p, err
}
func (s *catalogServer) StreamUpdates(req *shopv1.StreamUpdatesRequest, srv shopv1.Catalog_StreamUpdatesServer) error {
for ev := range s.bus.Subscribe(srv.Context()) {
if err := srv.Send(ev); err != nil { return err }
}
return nil
}
```
### TS client (ts-proto + grpc-js)
```typescript
import { credentials } from '@grpc/grpc-js';
import { CatalogClient } from './gen/shop/v1/catalog';
const client = new CatalogClient('catalog:50051', credentials.createSsl());
const p = await client.getProduct({ id: 'sku-42' }, { deadline: Date.now() + 1000 });
console.log(p.name);
// streaming
const stream = client.streamUpdates({});
stream.on('data', (u) => console.log('update', u));
stream.on('error', (e) => console.error(e));
```
### Deadline propagation
```go
ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
// 매 outgoing RPC 매 자동 deadline 전달.
resp, err := downstream.Sub(ctx, req)
```
### Interceptor (auth + tracing)
```go
func authUnary(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
md, _ := metadata.FromIncomingContext(ctx)
tok := md.Get("authorization")
if len(tok) == 0 { return nil, status.Error(codes.Unauthenticated, "no token") }
user, err := verify(tok[0])
if err != nil { return nil, status.Error(codes.Unauthenticated, "bad token") }
return handler(context.WithValue(ctx, userKey{}, user), req)
}
s := grpc.NewServer(grpc.UnaryInterceptor(authUnary))
```
### gRPC-Web (browser)
```typescript
import { createPromiseClient } from '@connectrpc/connect';
import { createGrpcWebTransport } from '@connectrpc/connect-web';
import { Catalog } from './gen/shop/v1/catalog_connect';
const transport = createGrpcWebTransport({ baseUrl: 'https://api.example.com' });
const client = createPromiseClient(Catalog, transport);
const p = await client.getProduct({ id: 'sku-42' });
```
### Buf for build + lint
```yaml
# buf.yaml
version: v2
modules:
- path: proto
lint:
use: [DEFAULT]
breaking:
use: [FILE]
```
```bash
buf lint
buf breaking --against '.git#branch=main'
buf generate
```
### Backward-compat 규칙
```protobuf
message Product {
string id = 1;
string name = 2;
// 매 deprecated 후에도 number 재사용 X
reserved 3;
reserved "old_price";
int64 price_cents = 4;
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 internal microservice | gRPC unary + interceptor |
| 매 browser client | Connect / gRPC-Web |
| 매 public open API | REST/JSON or gRPC-Gateway dual |
| 매 streaming (logs, ML) | server-stream / bidi |
| 매 mobile (cellular flaky) | gRPC + retry interceptor + deadline |
**기본값**: 매 internal = gRPC, 매 external = Connect (dual REST + gRPC).
## 🔗 Graph
- 변형: [[Connect_RPC]]
- 응용: [[Service_Mesh]] · [[Microservices]] · [[Envoy]]
- Adjacent: [[Buf]] · [[OpenAPI]]
## 🤖 LLM 활용
**언제**: 매 cross-language API, 매 streaming, 매 strict contract.
**언제 X**: 매 simple browser CRUD (REST 충분), 매 ad-hoc tooling (JSON 직관적).
## ❌ 안티패턴
- **Field number 재사용**: 매 wire-incompatible — 매 reserved 의 사용.
- **매 required 다용**: 매 schema evolution 차단 — proto3 default optional 유지.
- **매 deadline 미설정**: 매 server cascade hang.
- **매 large message (>4MB)**: 매 default limit hit — 매 stream 으로 분할.
- **매 .proto 의 versioning X**: 매 `v1`, `v2` package 분리 mandatory.
## 🧪 검증 / 중복
- Verified (grpc.io docs, protobuf.dev Edition 2024 spec, Buf docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — gRPC patterns, Edition 2024, Connect-RPC |
@@ -0,0 +1,144 @@
---
id: wiki-2026-0508-가상현실-vr
title: 가상현실(VR)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [VR, Virtual Reality, 가상현실]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [vr, xr, immersive, hardware, graphics]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: C++
framework: OpenXR / Unity XR / Unreal XR
---
# 가상현실(VR)
## 매 한 줄
> **"매 VR 의 head-mounted display + 6DoF tracking 의 immersive 3D world."**. 매 1968 Sutherland 의 Sword of Damocles 의 origin, 매 2026 의 Apple Vision Pro 2 / Quest 4 / Valve Deckard 의 mainstream 진입, 매 spatial computing 의 paradigm shift.
## 매 핵심
### 매 hardware stack
- HMD: dual-display (매 eye 마다 4K micro-OLED 의 2026 표준).
- Tracking: inside-out SLAM (매 cameras + IMU) 또는 outside-in lighthouse.
- Controllers: 6DoF + finger tracking + haptics.
- Eye tracking + foveated rendering: 매 GPU cost 의 50-70% 감소.
### 매 software stack
- OpenXR: 매 Khronos cross-vendor standard.
- Unity XR / Unreal XR / Godot XR: engine layer.
- WebXR: browser-based VR.
- visionOS / Horizon OS / SteamVR: platform layer.
### 매 응용
1. Gaming (Half-Life Alyx, Beat Saber).
2. Training simulation (surgery, aviation, military).
3. Virtual collaboration (Horizon Workrooms, Spatial).
4. Therapy (PTSD exposure, phobia treatment).
## 💻 패턴
### Pattern 1 — OpenXR session bootstrap (C++)
```cpp
XrInstance instance;
XrInstanceCreateInfo ci{XR_TYPE_INSTANCE_CREATE_INFO};
strcpy(ci.applicationInfo.applicationName, "MyVRApp");
ci.applicationInfo.apiVersion = XR_CURRENT_API_VERSION;
xrCreateInstance(&ci, &instance);
XrSystemId sysId;
XrSystemGetInfo sgi{XR_TYPE_SYSTEM_GET_INFO};
sgi.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
xrGetSystem(instance, &sgi, &sysId);
```
### Pattern 2 — Unity XR Interaction (C#)
```csharp
using UnityEngine.XR.Interaction.Toolkit;
public class GrabHandler : MonoBehaviour {
void OnEnable() {
var grab = GetComponent<XRGrabInteractable>();
grab.selectEntered.AddListener(OnGrab);
}
void OnGrab(SelectEnterEventArgs args) {
Debug.Log($"Grabbed by {args.interactorObject}");
}
}
```
### Pattern 3 — foveated rendering hint (Unreal)
```cpp
// VRS (Variable Rate Shading) tied to eye gaze
FEyeTrackerGazeData gaze;
UEyeTrackerFunctionLibrary::GetGazeData(gaze);
FoveationRenderer->SetFoveationCenter(gaze.GazeOrigin, gaze.GazeDirection);
FoveationRenderer->SetFoveationLevel(EFoveationLevel::High);
```
### Pattern 4 — locomotion (teleport, smooth, room-scale)
```csharp
// Teleport: discrete jump (low motion sickness).
// Smooth: continuous joystick (immersion ↑, sickness ↑).
// Room-scale: physical walking within play area.
locomotionProvider.MoveType = comfortSetting == HIGH ? Teleport : Smooth;
```
### Pattern 5 — async reprojection (90Hz lock)
```cpp
// Compositor re-warps last frame using latest head pose
// when app misses frame budget. Critical for sub-20ms motion-to-photon.
xrEndFrame(session, &endInfo); // compositor handles reprojection
```
### Pattern 6 — WebXR session
```javascript
const session = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['local-floor', 'hand-tracking']
});
const refSpace = await session.requestReferenceSpace('local-floor');
session.requestAnimationFrame(onXRFrame);
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 cross-platform deploy | OpenXR + Unity XR |
| 매 web reach | WebXR |
| 매 Apple ecosystem only | visionOS native (Swift + RealityKit) |
| 매 maximum fidelity (PCVR) | Unreal + Vulkan |
| 매 mobile standalone | Quest native (Android NDK) |
**기본값**: 매 Unity XR + OpenXR 의 cross-vendor.
## 🔗 Graph
- 부모: [[Computer-Graphics]] · [[Human-Computer-Interaction]]
- 변형: [[Mixed-Reality]] · [[Spatial-Computing]]
- Adjacent: [[깊이_지각(Depth_perception)]]
## 🤖 LLM 활용
**언제**: 매 immersive simulation 의 design 시, 매 OpenXR API 의 boilerplate 생성, 매 locomotion 의 comfort tradeoff 분석.
**언제 X**: 매 hardware-specific tuning (매 HMD 마다 의 IPD calibration), 매 user 의 actual motion sickness 의 real-world test.
## ❌ 안티패턴
- **Frame drops**: 매 90Hz 미달 → motion sickness 직결. 매 budget 의 11ms hard cap.
- **Smooth locomotion default**: 매 first-time user 의 nausea 의 cause. Teleport default.
- **Camera jerks**: 매 cinematic cuts 의 cinema convention 의 VR 적용 금지.
- **Tiny UI**: 매 angular size <2° 의 unreadable. 매 dpi 의 web 의 mental model 금지.
## 🧪 검증 / 중복
- Verified (Khronos OpenXR spec, Apple visionOS docs, Meta Developer docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — VR hardware/software stack + OpenXR/Unity/Unreal patterns |
@@ -0,0 +1,165 @@
---
id: wiki-2026-0508-마이크로서비스-아키텍처의-의존성-관리
title: 마이크로서비스 아키텍처의 의존성 관리
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Microservice Dependency Management, Service Dependencies, MSA 의존성]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [microservices, architecture, dependency-management, distributed-systems]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Go
framework: gRPC/Kubernetes
---
# 마이크로서비스 아키텍처의 의존성 관리
## 매 한 줄
> **"매 service 간 coupling 의 minimize, 매 explicit contract 의 enforce."**. 매 monolith 의 internal call 의 network call 의 transform 의 후, 매 transitive dependency · version skew · cascading failure 의 새로운 challenge 의 emerge. 2026 modern stack 은 매 OpenAPI/Protobuf contract + service mesh (Istio/Linkerd) + 매 SBOM-driven dependency tracking 의 combine.
## 매 핵심
### 매 dependency 의 종류
- **Build-time**: 매 shared library 의 dependency (avoid — leads to coordinated deploys).
- **Runtime sync**: 매 HTTP/gRPC call 의 직접 의존 (latency · failure propagation).
- **Runtime async**: 매 event/queue 의 통한 loose coupling (Kafka, NATS).
- **Data**: 매 shared DB schema 의 의존 (anti-pattern — own your data).
### 매 핵심 원칙
- **Bounded context**: 매 서비스 의 own 의 data + 매 logic 의 own.
- **Explicit contract**: 매 OpenAPI/gRPC schema 의 source-of-truth.
- **Backward compatibility**: 매 N-2 version 의 support.
- **Failure isolation**: 매 circuit breaker · timeout · bulkhead.
### 매 응용
1. 매 dependency graph 의 visualize (Backstage, Grafana service map).
2. 매 contract testing 의 CI integration (Pact, Schemathesis).
3. 매 chaos engineering 의 통한 cascading failure 의 test.
## 💻 패턴
### Circuit Breaker (Go, gobreaker)
```go
import "github.com/sony/gobreaker"
cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{
Name: "payment-service",
MaxRequests: 3,
Interval: 60 * time.Second,
Timeout: 30 * time.Second,
ReadyToTrip: func(c gobreaker.Counts) bool {
return c.ConsecutiveFailures > 5
},
})
result, err := cb.Execute(func() (interface{}, error) {
return paymentClient.Charge(ctx, req)
})
```
### gRPC contract via Protobuf
```proto
syntax = "proto3";
package payment.v1;
service PaymentService {
rpc Charge(ChargeRequest) returns (ChargeResponse);
}
message ChargeRequest {
string order_id = 1;
int64 amount_cents = 2;
string currency = 3;
}
```
### Pact consumer-driven contract test
```typescript
import { PactV3 } from "@pact-foundation/pact";
const provider = new PactV3({ consumer: "checkout", provider: "payment" });
provider
.uponReceiving("a charge request")
.withRequest({ method: "POST", path: "/v1/charge", body: { amount: 1000 } })
.willRespondWith({ status: 200, body: { id: "ch_123", status: "ok" } });
```
### Async event via Kafka (decouple)
```go
producer.Send(&kafka.Message{
Topic: "order.placed.v1",
Value: marshal(OrderPlaced{ID: orderID, Items: items}),
})
// payment, inventory, notification 의 own pace 의 consume.
```
### Service mesh policy (Istio)
```yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
spec:
hosts: [payment]
http:
- timeout: 2s
retries:
attempts: 3
perTryTimeout: 500ms
retryOn: 5xx,reset,connect-failure
```
### Dependency graph extraction
```bash
# Backstage catalog scan + 매 OpenTelemetry trace 의 통한 actual call graph
otel-cli export --format=json | jq '.spans[] | {service, downstream}'
```
### SBOM for transitive deps
```bash
syft packages dir:. -o cyclonedx-json > sbom.json
grype sbom:sbom.json --fail-on high
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Strong consistency 의 required | Sync gRPC + saga compensation |
| 매 latency-sensitive read | Sync + cache (Redis) |
| 매 cross-service workflow | Async event + saga orchestrator (Temporal) |
| Shared reference data | Read replica or 매 cached projection |
| Tight build coupling | Refactor — extract 매 shared concept 의 own service |
**기본값**: 매 async event-driven + 매 contract testing + 매 service mesh resilience.
## 🔗 Graph
- 부모: [[Microservices]] · [[Distributed_Systems]]
- 변형: [[Service_Mesh]] · [[Event_Driven_Architecture]]
- 응용: [[Circuit_Breaker]] · [[Contract_Testing]]
- Adjacent: [[API_Versioning]] · [[Observability]]
## 🤖 LLM 활용
**언제**: 매 service decomposition 의 design, 매 dependency graph 의 review, 매 contract evolution 의 plan.
**언제 X**: 매 small monolith — 매 premature decomposition 의 cost > benefit.
## ❌ 안티패턴
- **Distributed monolith**: 매 service 의 split 의 했지만 매 deploy 의 still coordinated.
- **Shared DB**: 매 두 service 가 same table 의 write — coupling worst case.
- **Chatty API**: 매 single user action 의 N개 service call 의 fan-out.
- **No timeout**: 매 default infinite timeout — cascading hang.
- **Synchronous chain**: A → B → C → D 매 single failure 의 entire chain 의 break.
## 🧪 검증 / 중복
- Verified (Sam Newman *Building Microservices* 2nd ed, CNCF service mesh landscape 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — dependency types, contract testing, mesh resilience patterns |
@@ -0,0 +1,136 @@
---
id: wiki-2026-0508-매몰-비용-오류-sunk-cost-fallacy
title: 매몰 비용 오류 (Sunk Cost Fallacy)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Sunk Cost Fallacy, Concorde Fallacy]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [cognitive-bias, decision-making, architecture-decision]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: na
framework: decision-framework
---
# 매몰 비용 오류 (Sunk Cost Fallacy)
## 매 한 줄
> **"매 이미 쓴 비용 때문에 매 잘못된 길을 더 간다"**. Arkes & Blumer (1985) 가 실증. 매 software 에서 "이미 6개월 썼으니 이 framework 못 버려" 의 형태로 발현 — 매 Concorde 사례 (영국+프랑스 정부가 이미 투자 때문에 적자 supersonic jet 을 1976-2003 운영) 에서 명명.
## 매 핵심
### 매 매커니즘
- **Loss aversion** (Kahneman): 매 손실 회피 본능이 합리적 abandon 을 막음.
- **Commitment escalation**: 매 공개적 commitment 일수록 후퇴 비용 (face) 추가.
- **Effort justification**: 매 노력한 만큼 가치 있다고 후방 합리화.
### 매 Software 발현
- Legacy framework 을 1년 마이그레이션 했는데 막힘 → 매 그래도 끝까지.
- 6개월 짠 architecture 의 fundamental flaw 발견 → 매 patch 만 계속.
- 1만 LOC PR review 에서 fundamental design 문제 발견 → 매 reviewer 가 미안해서 통과.
### 매 응용 (decision rule)
1. "Forward-looking only": 매 future cost vs future benefit 만 비교.
2. Pre-commit kill criteria: 매 시작 전에 abandon 조건 명문화.
3. Sunk cost label 명시: 매 retro 에서 "this is sunk cost reasoning" 언급 normalizing.
## 💻 패턴
### Decision Journal Template
```markdown
## Project Continuation Review
- Already invested: $X / Y months (sunk — IGNORE for decision)
- Estimated cost-to-complete: $A / B months
- Estimated value if completed: $V
- Estimated value of best alternative: $W
- DECISION: continue iff (V - A) > (W - 0)
```
### Pre-Mortem Kill Criteria
```yaml
# project-charter.yml
project: legacy-migration
abandon_if:
- cost_overrun_percent: 50
- timeline_overrun_percent: 100
- critical_unknown_unknowns_found: true
- team_morale_score_below: 5
- alternative_emerges_with_value_ratio: 2.0
```
### LLM-Assisted Sunk Cost Detection
```python
# Project review prompt
prompt = """
Analyze this project status report for sunk cost reasoning.
Flag phrases like:
- "we've already invested..."
- "we've come too far..."
- "we can't waste what we've done..."
Suggest forward-looking reframes.
Report: {status_report}
"""
# Use Claude Opus 4.7 for nuanced detection
```
### Stop-Loss Rule (Trading-style)
```python
class ProjectStopLoss:
def __init__(self, max_overrun=1.5):
self.max_overrun = max_overrun
self.original_estimate = None
def should_kill(self, current_spend, original_estimate):
return current_spend / original_estimate > self.max_overrun
```
### Reverse-Engineering the Decision
```markdown
## Fresh-Eye Test
"If I were starting today with zero invested,
would I choose this path?"
- If NO → sunk cost reasoning is in play
- If YES → continue is rational
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 50% 진행, 막힘 발견 | Fresh-eye test 적용 |
| 사용자 commit 한 feature | Demo MVP 후 재평가 (sunk cost 제외) |
| Public roadmap 약속 | Communicate honestly, kill if forward-looking 비합리 |
| 팀 morale 의 sunk cost | Retro + explicit naming |
**기본값**: Forward-looking analysis + pre-commit kill criteria.
## 🔗 Graph
- 부모: [[Cognitive_Bias]] · [[Decision_Making]]
- 변형: [[Concorde_Fallacy]]
- Adjacent: [[Loss_Aversion]]
## 🤖 LLM 활용
**언제**: 매 project status report 의 sunk cost reasoning 자동 탐지, 매 retro facilitation, 매 reframe suggestion.
**언제 X**: 매 emotional / political stakes 가 본질인 상황 — 매 사람의 심리적 work 필요.
## ❌ 안티패턴
- **"이미 X% 했어"**: 매 그 자체가 결정 근거가 됨 — 매 fallacy 본체.
- **No kill criteria**: 매 시작할 때 abandon 조건이 없음 → 매 무한 escalation.
- **Public commitment 의 hostage**: 매 face-saving 위해 매 손실 누적.
- **Confirmation seeking**: 매 "이미 했으니 옳다" 증거만 모음.
## 🧪 검증 / 중복
- Verified (Arkes & Blumer 1985, *Organizational Behavior and Human Decision Processes*; Kahneman *Thinking Fast and Slow* 2011).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — software-specific patterns + LLM detection 추가 |
@@ -0,0 +1,179 @@
---
id: wiki-2026-0508-배수구-sinks
title: 배수구 (Sinks)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Sinks, Taint Sinks, Dangerous Sinks, Vulnerable Functions]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [security, taint-analysis, sast, vulnerabilities, appsec]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: multi
framework: Semgrep/CodeQL
---
# 배수구 (Sinks)
## 매 한 줄
> **"매 untrusted data 의 dangerous 의 reach 한 곳 — 매 taint analysis 의 endpoint."**. Source (사용자 input) → Flow (변수, 함수 chain) → Sink (eval, exec, SQL, file write). 2026 SAST tooling (CodeQL, Semgrep, Snyk Code) 은 매 이 source-to-sink graph 의 trace — 매 sanitizer 의 absence 의 vulnerability 의 flag.
## 매 핵심
### 매 sink 의 종류
- **Code execution**: `eval`, `exec`, `Function()`, `os.system`, 매 deserialize.
- **SQL**: 매 raw query string concat (`f"SELECT * FROM u WHERE id={id}"`).
- **Command**: `subprocess.Popen(shell=True)`, `child_process.exec`.
- **Path**: `open(path)` with 매 user-controlled path → traversal.
- **HTML/DOM**: `innerHTML`, `document.write` → XSS.
- **SSRF**: `requests.get(user_url)` → 매 internal network access.
- **Log forging / template**: 매 user input 의 unescape 된 template.
### 매 source 의 종류
- HTTP request body/query/header.
- 매 file content (untrusted upload).
- 매 environment variable (in shared env).
- 매 third-party API response.
- 매 message queue payload.
### 매 응용
1. 매 SAST rule 의 author — 매 custom sink 의 register.
2. 매 code review 의 checklist — 매 sink 의 list 의 grep.
3. 매 fuzzing target 의 prioritize — 매 sink 가 most 인 endpoint.
## 💻 패턴
### Semgrep — custom sink rule
```yaml
rules:
- id: python-eval-tainted
pattern-sources:
- pattern: request.$X
pattern-sinks:
- pattern: eval(...)
- pattern: exec(...)
pattern-sanitizers:
- pattern: ast.literal_eval(...)
message: User input 의 eval 의 reach
severity: ERROR
languages: [python]
```
### CodeQL — taint tracking
```ql
import python
import semmle.python.dataflow.new.TaintTracking
class UserInputToSqlConfig extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node n) {
n.asExpr().(Attribute).getAttr() in ["args", "form", "json"]
}
override predicate isSink(DataFlow::Node n) {
exists(Call c | c.getFunc().(Attribute).getAttr() = "execute" |
n.asExpr() = c.getArg(0))
}
}
```
### SQL sink — parameterize (fix)
```python
# BAD — sink reachable
db.execute(f"SELECT * FROM users WHERE id = {user_id}")
# GOOD — sink 의 sanitize (parameterized)
db.execute("SELECT * FROM users WHERE id = %s", (user_id,))
```
### Command sink — avoid shell
```python
# BAD
subprocess.run(f"ping {host}", shell=True)
# GOOD
subprocess.run(["ping", "-c", "1", host], shell=False)
```
### Path traversal sink — resolve + check
```python
import os
base = "/var/uploads"
path = os.path.realpath(os.path.join(base, user_filename))
if not path.startswith(base + os.sep):
raise PermissionError("path traversal")
open(path, "rb")
```
### XSS sink — escape
```javascript
// BAD
el.innerHTML = userBio;
// GOOD — DOM API
el.textContent = userBio;
// 또는 매 DOMPurify 의 sanitize 후
el.innerHTML = DOMPurify.sanitize(userBio);
```
### SSRF — allowlist
```python
from urllib.parse import urlparse
ALLOWED_HOSTS = {"api.partner.com", "img.cdn.com"}
def safe_fetch(url):
host = urlparse(url).hostname
if host not in ALLOWED_HOSTS: raise ValueError("blocked host")
# 매 DNS rebinding 의 also guard — 매 resolve + IP check
return requests.get(url, timeout=5)
```
### Deserialize sink — never on untrusted
```python
# BAD — pickle 의 RCE
data = pickle.loads(request.body)
# GOOD — JSON only
data = json.loads(request.body)
```
## 매 결정 기준
| Sink type | Sanitizer | Notes |
|---|---|---|
| SQL | Parameterized query, ORM | 매 string concat 의 X |
| Shell | argv list, no `shell=True` | 매 quoting 의 trust 의 X |
| Path | realpath + prefix check | symlink 의 also handle |
| HTML | textContent or DOMPurify | 매 innerHTML 매 last resort |
| Eval | 매 그냥 사용 X | 매 alternative 의 find |
| Deserialize | JSON only on untrusted | pickle/yaml.load 매 X |
**기본값**: 매 sink 의 see 한 후 매 source 의 trace — 매 sanitizer 의 between 의 verify.
## 🔗 Graph
- 부모: [[Application_Security]]
- 변형: [[SAST]] · [[보안_및_시스템_신뢰성_표준|DAST]] · [[IAST]]
- 응용: [[OWASP_Top_10]]
- Adjacent: [[Fuzzing]]
## 🤖 LLM 활용
**언제**: 매 unfamiliar codebase 의 sink inventory 의 quickly 의 generate, 매 PR 매 new sink 의 introduce 의 spot.
**언제 X**: 매 production-grade SAST 의 replace — 매 LLM 의 false negative 의 risk, 매 dedicated tooling 의 use.
## ❌ 안티패턴
- **Blacklist sanitizer**: 매 known-bad 의 remove — 매 bypass 의 always exist.
- **Sanitize at sink**: 매 throughout flow 의 mutate — 매 single point 의 trust 의 X.
- **Trust 매 internal**: 매 internal API 의 source 의 also treat — 매 SSRF · Confused deputy.
- **Generic exception**: 매 sanitizer fail 의 silent swallow — 매 fail closed.
- **String comparison 의 host check**: 매 `endswith("trusted.com")``evil-trusted.com` bypass.
## 🧪 검증 / 중복
- Verified (OWASP Source-Sink-Sanitizer model, CodeQL taint tracking docs, Semgrep registry 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — sink categories, SAST rules, sanitizer patterns |
@@ -0,0 +1,181 @@
---
id: wiki-2026-0508-부분-유료화-free-to-play
title: 부분 유료화 (Free-to-Play)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Free-to-Play, F2P, Freemium, 부분유료화, 프리투플레이]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [game-design, monetization, business-model, economy]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: language-agnostic
framework: monetization
---
# 부분 유료화 (Free-to-Play)
## 매 한 줄
> **"매 무료 entry, 매 in-game purchase 의 통한 monetize."**. 2010s mobile gaming 의 explosion 의 driver — 매 Candy Crush, Clash of Clans, Genshin Impact, Fortnite 의 backbone. 2026 의 매 cosmetics-only (Fortnite, Valorant) 와 매 progression-gated (gacha) 의 split — 매 EU/KR regulation (gambling disclosure, 매 odds publication) 의 매 design 의 reshape.
## 매 핵심
### 매 monetization 의 종류
- **Cosmetic**: 매 skin · emote · nameplate — 매 power 의 X.
- **Battle pass**: 매 seasonal progression — 매 paid + free track.
- **Gacha / loot box**: 매 randomized reward — 매 rarity tier.
- **Energy / wait gate**: 매 stamina · timer — 매 pay-to-skip.
- **Pay-to-win (P2W)**: 매 power 의 직접 sell — 매 controversial.
- **Subscription**: 매 monthly perk (Apple Arcade, Game Pass — F2P 의 hybrid).
### 매 metric
- **ARPU**: average revenue per user.
- **ARPPU**: average revenue per paying user.
- **Conversion rate**: 매 free → paying %.
- **Whale concentration**: 매 top 1% 의 50%+ revenue 의 contribute (typical).
- **D1/D7/D30 retention**: 매 monetization 의 prerequisite.
### 매 응용
1. 매 economy design — 매 sink/source balance 의 inflation 의 prevent.
2. 매 A/B test — 매 price point · 매 offer cadence.
3. 매 ethical disclosure — 매 gacha odds publication (KR · CN law).
## 💻 패턴
### Pricing tier (server config)
```yaml
products:
- id: gem_pack_small
price_usd: 4.99
gems: 500
bonus: 0
- id: gem_pack_medium
price_usd: 19.99
gems: 2200 # 매 10% bonus
bonus: 200
badge: "best_value"
- id: gem_pack_large
price_usd: 99.99
gems: 13000 # 매 30% bonus, whale tier
bonus: 3000
```
### Gacha pull with pity
```python
import random
def pull(banner, pity_counter):
rates = banner.rates # {"5★": 0.006, "4★": 0.051, "3★": 0.943}
if pity_counter >= banner.hard_pity: # 매 90 pulls 의 5★ guarantee
return banner.featured_5star, 0
r = random.random()
if r < rates["5★"]: return random_5star(), 0
if r < rates["5★"] + rates["4★"]: return random_4star(), pity_counter + 1
return random_3star(), pity_counter + 1
```
### Battle pass progression
```typescript
interface BattlePass {
season: number;
currentXP: number;
tiers: Tier[]; // 매 100 tiers
ownsPaid: boolean;
}
function unlockedRewards(bp: BattlePass): Reward[] {
const tier = Math.floor(bp.currentXP / 1000);
return bp.tiers.slice(0, tier).flatMap(t =>
bp.ownsPaid ? [t.free, t.paid] : [t.free]
);
}
```
### Energy/stamina regen
```typescript
function currentStamina(user: User, now: Date): number {
const elapsed = (now.getTime() - user.lastStaminaUpdate.getTime()) / 1000;
const regen = Math.floor(elapsed / 360); // 매 6 min/point
return Math.min(user.stamina + regen, user.maxStamina);
}
// pay 의 instant refill: refill_cost = 50 gems
```
### Whale-friendly bundle
```yaml
bundle_starter:
one_time_only: true
price_usd: 0.99
contents:
- hero_card_5star: 1
- gems: 1000
rationale: "low-friction first purchase — 매 conversion driver"
```
### Disclosure (KR/CN law compliance)
```json
{
"banner": "limited_5star_featured",
"rates_disclosed": {
"5★_featured": 0.0030,
"5★_other": 0.0030,
"4★_any": 0.0510,
"3★_any": 0.9430
},
"pity_disclosed": { "soft_pity_at": 75, "hard_pity_at": 90 }
}
```
### Live ops calendar (offers)
```yaml
events:
- id: "weekend_sale"
cadence: "Fri 18:00 → Sun 23:59 KST"
discount: 0.20
- id: "comeback_offer"
trigger: "user.daysSinceLastSession >= 7"
contents: [gems: 500, hero_token: 1]
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 competitive PvP | Cosmetic-only — 매 P2W 의 player exodus 의 cause |
| 매 RPG/gacha audience | Banner + pity + battle pass |
| 매 casual puzzle | Energy gate + remove-ad IAP |
| 매 EU/KR market | Disclosure 의 mandatory · 매 gambling-like 의 minor restriction |
| 매 retention < D7 | 매 monetize 의 premature — 매 retention 의 fix first |
**기본값**: 매 cosmetic + battle pass — 매 controversy 의 minimize, 매 long-term retention 의 protect.
## 🔗 Graph
- 부모: [[Game_Monetization]]
- 변형: [[Freemium]]
- 응용: [[Gacha]] · [[Loot_Box]] · [[Live_Ops]]
- Adjacent: [[Game_Economy]] · [[Player_Retention]]
## 🤖 LLM 활용
**언제**: 매 economy simulation — 매 sink/source balance 의 model, 매 offer copy 의 generate.
**언제 X**: 매 ethical decision — 매 manipulative dark pattern 의 design 의 X.
## ❌ 안티패턴
- **Pay-to-win in PvP**: 매 competitive integrity 의 destroy → 매 churn.
- **Hidden gacha rates**: 매 KR/CN illegal · 매 trust 의 destroy.
- **Inflation**: 매 currency source > sink — 매 economy 의 break.
- **Monetize early**: 매 D1 popup 의 IAP — 매 retention 의 tank.
- **Whale-only design**: 매 top 1% 의 only 의 fun — 매 base 의 hollow out.
## 🧪 검증 / 중복
- Verified (Schell *Art of Game Design*; KR Game Industry Promotion Act 2024 amend; Sensor Tower 2026 mobile report).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — monetization types, gacha mechanics, regulation |
@@ -0,0 +1,157 @@
---
id: wiki-2026-0508-불변성-immutability
title: 불변성 (Immutability)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Immutability, Immutable Data, Persistent Data Structures, 불변 자료구조]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [functional-programming, concurrency, data-structures, design]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: multi
framework: Immer/Immutable.js
---
# 불변성 (Immutability)
## 매 한 줄
> **"매 생성 후 의 state 의 mutate 의 X — 매 update 의 new value 의 produce."**. 매 shared mutable state 의 concurrency · reasoning · debugging hell 의 root cause — 매 immutable data 의 매 reasoning 의 local 의 keep · race 의 eliminate · 매 time-travel · undo 의 cheap. 2026 modern stack (Rust ownership, Clojure, Immer, structural sharing) 은 매 immutability 의 performance cost 의 near-zero.
## 매 핵심
### 매 levels
- **Reference immutable**: 매 variable rebind X (`const x = ...`).
- **Shallow immutable**: 매 object reference X 의 change, 매 nested mutable 가능.
- **Deep immutable**: 매 entire tree mutable X (Object.freeze 매 recursive).
- **Persistent**: 매 update 의 structural sharing 의 통한 efficient (HAMT, finger tree).
### 매 benefits
- **Concurrency**: 매 lock-free read · 매 race 의 X.
- **Equality**: 매 reference equality 의 enough — `prev === next` (React memo).
- **Time-travel**: 매 undo/redo · 매 debugging snapshot.
- **Predictability**: 매 function 의 input 의 mutate X — 매 reason 의 local.
### 매 응용
1. 매 React/Redux state — 매 immutable update 의 re-render 의 cheap detect.
2. 매 Event sourcing — 매 event log immutable.
3. 매 functional core, imperative shell pattern.
## 💻 패턴
### JavaScript — Object spread (shallow)
```javascript
const user = { name: "Ada", age: 30 };
const older = { ...user, age: 31 }; // user 의 unchanged
```
### Immer — mutable syntax, immutable result
```javascript
import { produce } from "immer";
const next = produce(state, draft => {
draft.users[0].name = "Ada"; // 매 draft 의 freely mutate
draft.todos.push({ text: "x" });
});
// next 매 new immutable, state 매 unchanged
```
### Rust — ownership + immutable by default
```rust
let v = vec![1, 2, 3]; // immutable
let mut w = v.clone(); // explicit mut
w.push(4);
// fn 매 borrow as &T 의 read-only access
fn sum(xs: &[i32]) -> i32 { xs.iter().sum() }
```
### Clojure — persistent data structures
```clojure
(def m {:a 1 :b 2})
(def m2 (assoc m :c 3)) ; 매 m unchanged, structural sharing
(= (get m :c) nil) ; true
```
### Python — frozen dataclass
```python
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class User:
id: int
name: str
u1 = User(1, "Ada")
u2 = replace(u1, name="Grace") # 매 new instance
```
### Immutable.js (Map / List)
```javascript
import { Map } from "immutable";
const m = Map({ a: 1, b: 2 });
const m2 = m.set("c", 3); // structural sharing
```
### Event sourcing — append-only
```typescript
interface Event { type: string; payload: any; ts: number; }
class Aggregate {
private events: readonly Event[] = [];
apply(e: Event) { return new Aggregate([...this.events, e]); }
state() { return this.events.reduce(reducer, initial); }
}
```
### React — useState 의 immutable update
```typescript
const [todos, setTodos] = useState<Todo[]>([]);
// add
setTodos(prev => [...prev, newTodo]);
// update by id
setTodos(prev => prev.map(t => t.id === id ? { ...t, done: true } : t));
// remove
setTodos(prev => prev.filter(t => t.id !== id));
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 React/Redux state | Immer or spread |
| 매 hot path mutation (10M+/s) | Mutable + 매 boundary 에서 freeze |
| 매 deeply nested update | Immer (productivity > raw perf) |
| 매 multi-thread shared | Persistent + lock-free read |
| 매 audit/compliance | Event sourcing — append-only log |
**기본값**: 매 default immutable, 매 measured hotspot 의 mutable optimize.
## 🔗 Graph
- 부모: [[Functional_Programming]]
- 변형: [[Persistent_Data_Structures]]
- 응용: [[Event Sourcing Pattern|Event_Sourcing]] · [[프론트엔드_및_UIUX_표준|Redux]]
- Adjacent: [[Referential_Transparency]] · [[Concurrency]]
## 🤖 LLM 활용
**언제**: 매 mutation bug 의 hunt — 매 trace where state 의 escape, 매 immutable refactor 의 propose.
**언제 X**: 매 raw numeric kernel · 매 GPU buffer — 매 in-place 의 unavoidable.
## ❌ 안티패턴
- **Shallow freeze**: `Object.freeze(x)` 매 nested 의 still mutable — 매 deep freeze 의 필요.
- **Mutating in reducer**: Redux `state.x = 1` — 매 silent bug, 매 detect 의 hard.
- **Copy 의 매 op**: 매 deep clone 매 every update — 매 structural sharing 의 use.
- **Frozen 의 mutate 의 try**: strict mode 매 throw — 매 silent fail 의 X.
- **Immutable 의 cargo cult**: 매 single-threaded local var 의 over-immutable — 매 noise.
## 🧪 검증 / 중복
- Verified (Okasaki *Purely Functional Data Structures*; Immer docs; Rust Book ch4).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — levels, persistent structures, language patterns |
@@ -0,0 +1,206 @@
---
id: wiki-2026-0508-상태-머신-state-machine-모델링-및-redux-
title: 상태 머신 (State Machine) 모델링 및 Redux 액션/리듀서 설계
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [State Machine + Redux, FSM Redux Design, XState + Redux]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [state-machine, redux, xstate, frontend, architecture]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: redux-toolkit
---
# 상태 머신 (State Machine) 모델링 및 Redux 액션/리듀서 설계
## 매 한 줄
> **"매 impossible state 의 unrepresentable 화"**. 매 finite state machine (FSM) 는 explicit state + event + transition 의 enumerate. Redux reducer 는 매 (state, action) → state 의 pure function — 매 FSM 와 isomorphic. 2026 년 매 XState 5 + RTK 의 combine 패턴 의 standard.
## 매 핵심
### 매 FSM 5-tuple
- **States (Q)**: enumerable set — `idle | loading | success | error`.
- **Events (Σ)**: external triggers — `FETCH | RESOLVE | REJECT`.
- **Transitions (δ)**: `Q × Σ → Q` — 매 partial function.
- **Initial state (q₀)**: `idle`.
- **Final states (F)**: optional — terminal nodes.
### 매 Redux 와 mapping
- **Reducer = δ**: `(state, action) => newState` 의 pure transition.
- **Action = Σ event**: typed discriminated union.
- **Store state = Q**: 매 status field 의 enum.
- **Selector**: 매 derived view — `isLoading = state.status === 'loading'`.
### 매 응용
1. Form wizard — multi-step flow 의 state 의 explicit.
2. Data fetching — idle/loading/success/error 의 4-state.
3. Auth flow — anonymous/authenticating/authenticated/expired.
## 💻 패턴
### Discriminated union state
```typescript
type FetchState<T> =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: T }
| { status: 'error'; error: Error };
// 매 impossible state ('loading' + data) 의 unrepresentable.
```
### RTK slice = FSM reducer
```typescript
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: { status: 'idle' } as FetchState<User>,
reducers: {
fetch: (state) => {
if (state.status === 'idle' || state.status === 'error') {
return { status: 'loading' };
}
return state; // ignore invalid transition
},
resolve: (_, action: PayloadAction<User>) => ({
status: 'success',
data: action.payload,
}),
reject: (_, action: PayloadAction<Error>) => ({
status: 'error',
error: action.payload,
}),
},
});
```
### Transition guard table
```typescript
const TRANSITIONS = {
idle: { FETCH: 'loading' },
loading: { RESOLVE: 'success', REJECT: 'error' },
success: { FETCH: 'loading' },
error: { FETCH: 'loading' },
} as const;
function transition<S extends keyof typeof TRANSITIONS>(
state: S,
event: string
): string {
return (TRANSITIONS[state] as any)[event] ?? state;
}
```
### XState 5 + Redux integration
```typescript
import { createMachine, createActor } from 'xstate';
const fetchMachine = createMachine({
id: 'fetch',
initial: 'idle',
states: {
idle: { on: { FETCH: 'loading' } },
loading: {
invoke: {
src: 'fetchUser',
onDone: { target: 'success', actions: 'storeData' },
onError: 'error',
},
},
success: { on: { REFRESH: 'loading' } },
error: { on: { RETRY: 'loading' } },
},
});
const actor = createActor(fetchMachine).start();
actor.subscribe((snapshot) => store.dispatch({ type: 'fsm/sync', payload: snapshot.value }));
```
### Hierarchical (nested) state
```typescript
// 매 auth flow — 매 sub-state machine.
const authMachine = createMachine({
initial: 'unauthenticated',
states: {
unauthenticated: {
initial: 'idle',
states: {
idle: { on: { LOGIN: 'submitting' } },
submitting: { on: { SUCCESS: '#auth.authenticated', FAIL: 'idle' } },
},
},
authenticated: {
on: { LOGOUT: 'unauthenticated' },
},
},
}, { id: 'auth' });
```
### Parallel state regions
```typescript
const editorMachine = createMachine({
type: 'parallel',
states: {
document: { initial: 'clean', states: { clean: {}, dirty: {} } },
network: { initial: 'online', states: { online: {}, offline: {} } },
},
});
// 매 state = (document, network) 의 cross product — explicit.
```
### Test as transition table
```typescript
test.each([
['idle', 'FETCH', 'loading'],
['loading', 'RESOLVE', 'success'],
['loading', 'REJECT', 'error'],
['success', 'FETCH', 'loading'],
])('transition %s --%s--> %s', (from, event, to) => {
expect(transition(from, event)).toBe(to);
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Simple async (fetch) | RTK `createAsyncThunk` + discriminated union |
| Multi-step wizard | XState machine |
| Complex auth | XState hierarchical machine |
| Parallel concerns | XState parallel states |
| Pure UI toggle | useState (not Redux) |
**기본값**: RTK + discriminated union state. 복잡 시 XState 5.
## 🔗 Graph
- 부모: [[프론트엔드_및_UIUX_표준|Redux]]
- 변형: [[XState]]
- 응용: [[Data Fetching]]
- Adjacent: [[Discriminated Union]] · [[Pure Function]] · [[Event Sourcing]]
## 🤖 LLM 활용
**언제**: state 가 3+ 개 + transition 의 explicit rule 의 필요 시.
**언제 X**: simple boolean toggle 또는 single-shot async — 매 overkill.
## ❌ 안티패턴
- **Boolean explosion**: `isLoading + isError + isSuccess` — impossible state (true+true) 의 representable.
- **Implicit transition**: reducer 안 valid state check 의 X — 매 invalid transition 의 silently 발생.
- **God reducer**: 매 모든 logic 의 한 reducer — 매 split.
- **Side effect in reducer**: `fetch()` 의 reducer 내부 — 매 thunk/saga/middleware 사용.
## 🧪 검증 / 중복
- Verified (Hopcroft & Ullman *Automata Theory*; Redux docs; XState v5 docs 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — FSM↔Redux mapping + XState 5 patterns |
@@ -0,0 +1,161 @@
---
id: wiki-2026-0508-소프트웨어-아키텍처-설계
title: 소프트웨어 아키텍처 설계
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Software Architecture Design, SW Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, design, software-engineering]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: agnostic
framework: agnostic
---
# 소프트웨어 아키텍처 설계
## 매 한 줄
> **"매 architecture는 매 의사결정의 기록이며, 매 변경 비용을 결정한다"**. Bass/Clements/Kazman의 SEI 정의 이후, 매 architecture는 매 코드 자체가 아닌 매 component / connector / constraint의 집합으로 본다. 매 2026 modern view는 매 evolutionary architecture (Ford) — 매 fitness function 으로 매 architectural property 를 매 자동 검증.
## 매 핵심
### 매 4+1 View (Kruchten)
- **Logical**: 매 도메인 객체 / 책임 분배.
- **Process**: 매 runtime concurrency / 매 thread / 매 process.
- **Development**: 매 module / 매 package 구조.
- **Physical**: 매 deployment topology.
- **Scenarios (+1)**: 매 use case driven validation.
### 매 Quality Attributes (ISO/IEC 25010)
- **Performance**: latency, throughput.
- **Scalability**: horizontal / vertical 확장.
- **Availability**: SLA, MTBF, MTTR.
- **Security**: CIA triad.
- **Modifiability**: 매 변경 cost.
- **Testability**: 매 격리 가능성.
### 매 응용
1. C4 model 으로 매 stakeholder communication.
2. ADR (Architecture Decision Record) 으로 매 결정 추적.
3. Fitness function 으로 매 architectural drift 방지.
## 💻 패턴
### ADR template
```markdown
# ADR 0042: Adopt CQRS for Order service
## Status
Accepted (2026-05-10)
## Context
Read traffic 100x higher than write. Single Postgres table contention.
## Decision
Split into command (Postgres) + query (Read replica + Redis cache).
Event sourcing via Kafka.
## Consequences
+ Read scales independently.
- Eventual consistency window ~50ms.
- Two data models to maintain.
```
### Fitness function (ArchUnit, Java)
```java
@AnalyzeClasses(packages = "com.shop")
class ArchitectureTest {
@ArchTest
static final ArchRule domain_independent =
noClasses().that().resideInAPackage("..domain..")
.should().dependOnClassesThat().resideInAPackage("..infra..");
@ArchTest
static final ArchRule controllers_only_call_services =
classes().that().resideInAPackage("..controller..")
.should().onlyDependOnClassesThat()
.resideInAnyPackage("..service..", "java..");
}
```
### C4 Container diagram (Structurizr DSL)
```
workspace {
model {
user = person "Customer"
shop = softwareSystem "Shop" {
web = container "Web App" "React" "TypeScript"
api = container "API" "Spring Boot"
db = container "Database" "PostgreSQL 16"
}
user -> web "Browses"
web -> api "Calls" "REST/JSON"
api -> db "Reads/writes" "JDBC"
}
}
```
### Hexagonal Architecture (Python)
```python
# domain/order.py — pure
class Order:
def confirm(self) -> "Order": ...
# application/ports.py
class OrderRepo(Protocol):
def save(self, o: Order) -> None: ...
# infra/postgres_order_repo.py — adapter
class PostgresOrderRepo:
def save(self, o: Order) -> None:
self.conn.execute("INSERT ...")
```
### Event Storming output → bounded contexts
```
[Order Placed] → [Payment Authorized] → [Inventory Reserved] → [Order Confirmed]
Order BC Payment BC Inventory BC Order BC
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 small team, simple domain | Modular monolith (Shopify-style) |
| 매 high read/write asymmetry | CQRS |
| 매 audit critical | Event sourcing |
| 매 polyglot / independent scaling | Microservices |
| 매 latency critical, ML inference | Service mesh + sidecar |
**기본값**: 매 modular monolith → 매 evidence 기반 매 split.
## 🔗 Graph
- 부모: [[아키텍처 패턴 지식]]
- 변형: [[Hexagonal Architecture]] · [[CQRS]] · [[Event Sourcing]]
- 응용: [[Microservices]] · [[Cloud_Native|Modular Monolith]]
- Adjacent: [[Domain-Driven Design]] · [[ADR]] · [[C4 Model]]
## 🤖 LLM 활용
**언제**: 매 ADR 초안 / 매 trade-off 분석 / 매 quality attribute scenario 생성.
**언제 X**: 매 production-grade fitness function 의 자동 작성 — 매 human review 필수.
## ❌ 안티패턴
- **Big design up-front**: 매 evolution 무시.
- **Architecture astronaut**: 매 abstraction layer 과잉.
- **Distributed monolith**: 매 microservice 의 분리 but 매 coupling 유지.
- **No fitness function**: 매 drift 매 silently.
## 🧪 검증 / 중복
- Verified (Bass/Clements/Kazman, *Software Architecture in Practice 4e*; Ford, *Building Evolutionary Architectures 2e*).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 매 4+1, ADR, fitness function 패턴 추가 |
@@ -0,0 +1,164 @@
---
id: wiki-2026-0508-스택-트레이스-stack-trace
title: 스택 트레이스 (Stack Trace)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Stack Trace, Call Stack, Backtrace, 콜스택]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [debugging, observability, error-handling, runtime]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Python/Go/JS
framework: Sentry/OpenTelemetry
---
# 스택 트레이스 (Stack Trace)
## 매 한 줄
> **"매 error 의 발생 시점 의 call chain 의 snapshot."**. 매 runtime 의 active frame 의 list — function name · file · line · 매 local variable (optional). 2026 modern observability 는 매 stack trace 의 distributed trace · source map · symbolication · 매 LLM-assisted root cause 의 통합.
## 매 핵심
### 매 구성 요소
- **Frame**: 매 each function call 의 record (caller info).
- **Top of stack**: 매 error 의 throw 한 가장 안쪽 frame.
- **Bottom**: 매 program entry (main, event loop).
- **Symbolication**: 매 minified/compiled binary 의 readable name 의 resolve.
### 매 종류
- **Native**: 매 Go panic, C++ SIGSEGV — debug symbols 의 필요.
- **Managed**: JVM, .NET, Python — runtime 의 자동 capture.
- **Async**: 매 promise/coroutine — 매 await chain 의 reconstruct (Python 3.11+ exception groups, V8 async stack).
- **Distributed**: 매 trace_id + span 의 across-service stack.
### 매 응용
1. 매 production error 의 root cause 의 빠르게 locate.
2. 매 performance profiling — 매 sample-based stack 의 hot path 의 reveal.
3. 매 security forensics — 매 exploit 의 entry point 의 identify.
## 💻 패턴
### Python — full traceback with locals
```python
import traceback, sys
try:
risky_op()
except Exception:
tb = traceback.TracebackException.from_exception(
sys.exc_info()[1], capture_locals=True
)
print("".join(tb.format()))
```
### Go — runtime stack
```go
import "runtime/debug"
defer func() {
if r := recover(); r != nil {
log.Printf("panic: %v\n%s", r, debug.Stack())
}
}()
```
### Node.js — async stack 의 enable
```js
// Node 22+ 매 default
Error.stackTraceLimit = 50;
process.on("unhandledRejection", (reason) => {
console.error(reason instanceof Error ? reason.stack : reason);
});
```
### Source map symbolication (browser)
```js
import { SourceMapConsumer } from "source-map";
const raw = await fetch("app.js.map").then(r => r.json());
await SourceMapConsumer.with(raw, null, consumer => {
const orig = consumer.originalPositionFor({ line: 42, column: 13 });
console.log(orig); // { source: "src/app.tsx", line: 117, name: "handleClick" }
});
```
### Sentry SDK with breadcrumbs
```python
import sentry_sdk
sentry_sdk.init(dsn="https://...", traces_sample_rate=0.1)
sentry_sdk.add_breadcrumb(category="auth", message="user login", level="info")
# 매 exception 의 자동 capture + breadcrumb chain
```
### OpenTelemetry — stack 의 distributed trace 의 attach
```python
from opentelemetry import trace
span = trace.get_current_span()
span.record_exception(exc, attributes={"stack": traceback.format_exc()})
```
### Java — Throwable.getStackTrace
```java
try { ... } catch (Exception e) {
for (StackTraceElement el : e.getStackTrace()) {
log.error("{}.{} ({}:{})",
el.getClassName(), el.getMethodName(),
el.getFileName(), el.getLineNumber());
}
}
```
### LLM-assisted analysis (Claude Opus 4.7)
```python
prompt = f"""Stack trace:
{stack}
Recent commits:
{git_log}
매 root cause + 매 fix candidate 의 propose."""
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Production unhandled error | Sentry/Datadog 매 자동 capture |
| Local dev | Native debugger (gdb, dlv, pdb) |
| Async/promise chain | Runtime async stack 의 enable |
| Minified prod JS | Source map upload + symbolication |
| Distributed call | OTel trace + span exception |
**기본값**: 매 OTel + Sentry 의 combine — 매 single trace 에서 매 service-crossing stack 의 see.
## 🔗 Graph
- 부모: [[Debugging]] · [[Observability]]
- 변형: [[Distributed_Tracing]]
- 응용: [[Profiling]]
- Adjacent: [[Source_Maps]] · [[Logging]]
## 🤖 LLM 활용
**언제**: 매 long stack trace 의 summarize, 매 framework noise 의 filter, 매 likely culprit frame 의 highlight.
**언제 X**: 매 sensitive PII 의 local variable 의 포함 — sanitize first.
## ❌ 안티패턴
- **Swallow exception**: `except: pass` — 매 stack 의 lose.
- **Re-raise wrong**: 매 `raise e` (Python) 매 traceback 의 truncate — `raise` bare 의 use.
- **No source map**: 매 prod minified — stack 의 unreadable.
- **Stack 의 user 의 expose**: 매 5xx response 에 raw stack 의 dump — info leak.
- **Limit too low**: `Error.stackTraceLimit = 10` 매 root frame 의 cut off.
## 🧪 검증 / 중복
- Verified (Python docs traceback module, V8 async stack RFC, Sentry symbolication guide 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — async stacks, symbolication, OTel integration |
@@ -0,0 +1,165 @@
---
id: wiki-2026-0508-시스템-아키텍처-시각화-system-architecture
title: 시스템 아키텍처 시각화 (System Architecture Visualization)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Architecture Visualization, C4 Model, Architecture Diagrams]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, visualization, diagrams, c4]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: text
framework: structurizr-mermaid-d2
---
# 시스템 아키텍처 시각화 (System Architecture Visualization)
## 매 한 줄
> **"매 diagram 은 매 system 의 매 mental model 을 매 stakeholder 간 매 align 하는 매 communication tool 이다"**. Simon Brown 의 매 C4 model (2018) 이 매 modern de-facto standard. 매 2026 trend 는 매 diagram-as-code (Structurizr DSL, D2, Mermaid) 으로 매 version control + AI generation.
## 매 핵심
### 매 C4 levels
1. **System Context**: 매 system + actors + 매 external systems.
2. **Container**: 매 deployable unit (web app, DB, queue).
3. **Component**: 매 container 내부 logical block.
4. **Code (optional)**: UML class — 매 거의 사용 X.
### 매 supplementary diagrams
- **Deployment**: physical / cloud topology.
- **Sequence**: temporal interactions.
- **State**: entity lifecycle.
- **ERD**: data model.
- **Network**: subnets / firewalls.
### 매 응용
1. 매 stakeholder 별 매 abstraction level 선택.
2. 매 ADR 의 시각적 근거.
3. 매 onboarding 의 매 first artifact.
## 💻 패턴
### C4 Container (Structurizr DSL)
```
workspace {
model {
customer = person "Customer"
shop = softwareSystem "Shop" {
web = container "Web App" "React 19" "TypeScript"
api = container "API" "Spring Boot 4" "Java 25"
db = container "Database" "PostgreSQL 17"
queue = container "Queue" "Kafka 4.0"
}
payment = softwareSystem "Stripe" "External"
customer -> web "Browses"
web -> api "Calls" "REST/JSON"
api -> db "Reads/writes" "JDBC"
api -> queue "Publishes events"
api -> payment "Charges" "HTTPS"
}
views {
container shop { include * autolayout lr }
theme default
}
}
```
### Mermaid C4 (in markdown)
```mermaid
C4Container
Person(user, "Customer")
System_Boundary(shop, "Shop") {
Container(web, "Web App", "React")
Container(api, "API", "Spring Boot")
ContainerDb(db, "DB", "PostgreSQL")
}
Rel(user, web, "Uses")
Rel(web, api, "Calls", "REST")
Rel(api, db, "Reads/writes", "JDBC")
```
### D2 (modern DSL)
```d2
user -> web: browses
web -> api: REST/JSON {
style.stroke: blue
}
api -> db: SQL
api -> kafka -> worker
shape: sequence_diagram
```
### Sequence (Mermaid)
```mermaid
sequenceDiagram
participant U as User
participant W as Web
participant A as API
participant S as Stripe
U->>W: Submit checkout
W->>A: POST /orders
A->>S: Charge
S-->>A: Receipt
A-->>W: 201 Created
```
### CI render → PNG (Structurizr CLI)
```yaml
- name: Render diagrams
run: |
docker run --rm -v $PWD:/usr/local/structurizr \
structurizr/cli export -workspace workspace.dsl -format mermaid
docker run --rm -v $PWD:/data minlag/mermaid-cli \
-i workspace-Container.mmd -o docs/architecture.png
```
### AI-assisted diagram generation
```bash
# Claude Opus 4.7 reads codebase, infers C4 Container
claude diagram --level=container --format=structurizr ./src > workspace.dsl
```
## 매 결정 기준
| Context | Tool |
|---|---|
| 매 living architecture (versioned) | Structurizr DSL |
| 매 quick markdown embed | Mermaid |
| 매 modern, scriptable | D2 |
| 매 deployment topology | draw.io / Excalidraw |
| 매 cloud-specific | AWS / Azure architecture icons |
**기본값**: 매 Structurizr DSL (1 source) + 매 Mermaid export → README.
## 🔗 Graph
- 부모: [[소프트웨어 아키텍처 설계]]
- 변형: [[C4 Model]]
- 응용: [[아키텍처 다이어그램 Architecture Diagram]] · [[ADR]]
- Adjacent: [[Mermaid]] · [[D2]]
## 🤖 LLM 활용
**언제**: 매 codebase → diagram inference / 매 diagram → narrative explanation.
**언제 X**: 매 production deployment topology — 매 SRE 검증 필수.
## ❌ 안티패턴
- **Diagram zoo**: 매 100 가지 abstraction level 의 mix.
- **PowerPoint architecture**: 매 version 무관, 매 stale.
- **No legend**: 매 box meaning 매 unclear.
- **Over-abstracted**: 매 "Cloud" box 1개로 매 모든 detail 숨김.
## 🧪 검증 / 중복
- Verified (Brown, *The C4 Model for Software Architecture* (c4model.com); Bass *SAIP 4e*).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — C4 / Structurizr / D2 / Mermaid 패턴 추가 |
@@ -0,0 +1,151 @@
---
id: wiki-2026-0508-시프트-레프트-shift-left
title: 시프트 레프트 (Shift-Left)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Shift Left, Shift-Left Testing, Shift-Left Security]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [devops, testing, security, ci-cd]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: agnostic
framework: ci-cd
---
# 시프트 레프트 (Shift-Left)
## 매 한 줄
> **"매 결함은 매 발견 시점이 빠를수록 매 비용이 기하급수적으로 감소한다"**. Larry Smith가 2001년 매 명명. 매 testing / security / compliance 를 매 SDLC 의 좌측 (design / coding) 으로 매 이동. 매 2026 modern form은 매 IDE 안에서 매 SAST + AI assisted review (Claude Opus 4.7, GitHub Copilot) 가 매 commit 전 매 결함 탐지.
## 매 핵심
### 매 Cost curve (Boehm / NIST)
- 매 design phase: 1x
- 매 implementation: 5x
- 매 testing: 10x
- 매 production: 100x+
### 매 적용 영역
- **Testing**: TDD / unit test in pre-commit hook.
- **Security**: SAST (Semgrep, CodeQL), SCA (Dependabot, Snyk), secret scanning (gitleaks).
- **Compliance**: policy as code (OPA / Conftest).
- **Infrastructure**: tfsec, checkov.
- **Quality**: lint / type check at IDE save.
### 매 응용
1. Pre-commit hooks 으로 매 30 sec feedback.
2. PR-blocking CI 로 매 main 매 clean.
3. AI review (Claude Code / Copilot) 으로 매 design phase 매 결함 탐지.
## 💻 패턴
### Pre-commit hook config
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.0
hooks: [{ id: gitleaks }]
- repo: https://github.com/returntocorp/semgrep
rev: v1.95.0
hooks: [{ id: semgrep, args: [--config=auto, --error] }]
- repo: local
hooks:
- id: pytest-changed
name: pytest-changed
entry: pytest --testmon
language: system
pass_filenames: false
```
### GitHub Actions: shift-left CI
```yaml
on: [pull_request]
jobs:
shift-left:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: github/codeql-action/init@v3
with: { languages: python }
- uses: github/codeql-action/analyze@v3
- uses: aquasecurity/tfsec-action@v1
- run: npx snyk test --severity-threshold=high
- run: gitleaks detect --source . --redact
```
### Policy as code (OPA / Rego)
```rego
package terraform.s3
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
not resource.change.after.server_side_encryption_configuration
msg := sprintf("S3 bucket %v: encryption not configured", [resource.name])
}
```
### IDE-time SAST (VS Code Semgrep)
```json
{
"semgrep.scan.configuration": ["auto", "p/owasp-top-ten"],
"semgrep.scan.onSave": true,
"editor.codeActionsOnSave": { "source.fixAll": "explicit" }
}
```
### AI design review (Claude Opus 4.7)
```bash
claude review --pre-commit \
--rules "OWASP Top 10, race conditions, error handling" \
$(git diff --cached --name-only)
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 secret leak 매 방지 | gitleaks pre-commit + GitHub secret scanning |
| 매 dependency vulnerability | Dependabot + Snyk in PR |
| 매 IaC misconfiguration | tfsec + OPA |
| 매 logic bug | TDD + property-based tests |
| 매 design flaw | AI-assisted review (Claude / Copilot) |
**기본값**: 매 pre-commit (lint + secret) + PR-CI (SAST + SCA + tests).
## 🔗 Graph
- 부모: [[CI_CD 파이프라인 및 IDE 통합 보안|DevSecOps]]
- 응용: [[SAST]] · [[SCA_Fundamentals|SCA]]
- Adjacent: [[TDD]] · [[Supply Chain Security]]
## 🤖 LLM 활용
**언제**: 매 PR review 의 first-pass / 매 security policy generation / 매 test case 생성.
**언제 X**: 매 final security signoff — 매 human security engineer 필수.
## ❌ 안티패턴
- **Shift-left without budget**: 매 dev 에 매 책임만 떠넘기기.
- **Tool spam**: 매 30 가지 scanner — 매 noise 로 매 ignored.
- **Block on everything**: 매 false positive 로 매 trust 상실.
- **No baseline**: 매 legacy code 의 매 모든 finding block.
## 🧪 검증 / 중복
- Verified (Smith 2001 *Shift-Left Testing*, Forrester *State of Application Security 2025*, OWASP DevSecOps Guideline).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 매 pre-commit, OPA, AI review 패턴 추가 |
@@ -0,0 +1,180 @@
---
id: wiki-2026-0508-실시간-엔진-real-time-engine
title: 실시간 엔진 (Real-Time Engine)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Real-Time Engine, RTE, Game Engine, Realtime Rendering]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [game-engine, realtime, rendering, simulation]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: cpp
framework: unreal-unity-godot
---
# 실시간 엔진 (Real-Time Engine)
## 매 한 줄
> **"매 RTE 는 매 매 프레임 (16.67ms @ 60Hz, 매 8.33ms @ 120Hz) 안에 매 simulation + render 매 완료해야 한다 — 매 deadline 매 hard"**. Gregory 의 매 *Game Engine Architecture* 가 매 canonical reference. 매 2026 modern engines: Unreal Engine 5.5 (Nanite, Lumen, MetaHuman), Unity 6 (HDRP, ECS/DOTS), Godot 4.4, Bevy (Rust ECS).
## 매 핵심
### 매 frame budget breakdown (60 Hz)
- Input poll: <1 ms
- Game logic / scripting: 2-4 ms
- Physics: 2-4 ms
- Animation / IK: 1-3 ms
- Render submit (CPU): 1-3 ms
- GPU render: 4-10 ms
- Total: <16.67 ms
### 매 core subsystems
- **Renderer**: scene graph, culling, rasterizer / RT.
- **Physics**: rigid body, soft body, character controller.
- **Audio**: 3D positional, mixing, DSP.
- **Animation**: skeletal, blend tree, state machine.
- **Networking**: client prediction, lag compensation.
- **Scripting / ECS**: gameplay code.
- **Asset pipeline**: import, baking, streaming.
### 매 응용
1. 매 game (AAA / indie / mobile).
2. 매 architecture viz / digital twin.
3. 매 VR / AR experience.
4. 매 simulation training.
## 💻 패턴
### Fixed timestep + interpolation (Glenn Fiedler)
```cpp
double accumulator = 0, t = 0;
const double dt = 1.0 / 60.0;
double prevTime = now();
while (running) {
double curr = now();
accumulator += curr - prevTime;
prevTime = curr;
while (accumulator >= dt) {
physics.step(dt);
accumulator -= dt;
}
double alpha = accumulator / dt;
renderer.render(state.lerp(prev, alpha));
}
```
### ECS (Bevy 0.15, Rust)
```rust
#[derive(Component)] struct Position(Vec3);
#[derive(Component)] struct Velocity(Vec3);
fn movement(time: Res<Time>, mut q: Query<(&mut Position, &Velocity)>) {
for (mut pos, vel) in &mut q {
pos.0 += vel.0 * time.delta_seconds();
}
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Update, movement)
.run();
}
```
### Frustum culling (renderer)
```cpp
void cull(const Camera& cam, const std::vector<Renderable>& objs,
std::vector<Renderable>& visible) {
Frustum f = cam.frustum();
for (const auto& o : objs)
if (f.intersects(o.bounds)) visible.push_back(o);
}
```
### Spatial hash for broadphase
```cpp
class SpatialHash {
std::unordered_map<int64_t, std::vector<EntityId>> cells;
static constexpr float cellSize = 4.0f;
static int64_t key(Vec3 p) {
return ((int64_t)(p.x / cellSize) << 40)
^ ((int64_t)(p.y / cellSize) << 20)
^ (int64_t)(p.z / cellSize);
}
public:
void insert(EntityId id, Vec3 p) { cells[key(p)].push_back(id); }
std::vector<EntityId> query(Vec3 p) { return cells[key(p)]; }
};
```
### Client prediction + reconciliation (netcode)
```typescript
class Client {
pending: Input[] = [];
onInput(i: Input) {
this.applyLocal(i);
this.send(i);
this.pending.push(i);
}
onServerSnapshot(s: Snapshot) {
this.state = s.state;
this.pending = this.pending.filter(i => i.seq > s.lastAcked);
for (const i of this.pending) this.applyLocal(i);
}
}
```
### Unreal Lumen / Nanite usage (high-level config)
```cpp
// Project Settings → Rendering
// - Dynamic Global Illumination Method: Lumen
// - Reflection Method: Lumen
// - Shadow Method: Virtual Shadow Maps
// - Generate Mesh Distance Fields: enabled
// - Nanite-enabled meshes: import with "Build Nanite" checked
```
## 매 결정 기준
| Use case | Engine |
|---|---|
| 매 AAA / cinematic | Unreal Engine 5.5 |
| 매 mobile / 2D / cross-platform | Unity 6 |
| 매 open source / lightweight | Godot 4.4 |
| 매 data-oriented / Rust | Bevy |
| 매 web | three.js / Babylon.js |
| 매 simulation (no rendering) | custom + physics lib |
**기본값**: 매 Unreal 5.5 (high fidelity) / Unity 6 (productivity).
## 🔗 Graph
- 부모: [[Computer Graphics]]
- 변형: [[실시간 엔진 RTE]] (alias)
- 응용: [[Unity]] · [[Bevy]]
- Adjacent: [[ECS]] · [[Game Loop]] · [[Frustum Culling]]
## 🤖 LLM 활용
**언제**: 매 ECS architecture design / 매 shader explanation / 매 netcode pattern.
**언제 X**: 매 production shader / 매 critical-path code — 매 profile 기반 review.
## ❌ 안티패턴
- **Variable timestep physics**: 매 instability + 매 nondeterminism.
- **Single-threaded mainloop**: 매 modern multi-core 미활용.
- **No frame budget**: 매 random stutter / spike.
- **OOP-heavy hot path**: 매 cache miss / 매 ECS 매 미적용.
## 🧪 검증 / 중복
- Verified (Gregory, *Game Engine Architecture 4e*; Akenine-Möller et al., *Real-Time Rendering 5e*; Fiedler, *Fix Your Timestep*).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — fixed-timestep / ECS / culling / netcode 패턴 추가 |
@@ -0,0 +1,188 @@
---
id: wiki-2026-0508-안구-운동-기능-oculomotor-functions
title: 안구 운동 기능 (Oculomotor functions)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Oculomotor, Eye Tracking, Gaze, Foveated Rendering Input]
duplicate_of: none
source_trust_level: B
confidence_score: 0.85
verification_status: applied
tags: [hci, eye-tracking, vr-ar, accessibility, foveated-rendering]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: webxr
---
# 안구 운동 기능 (Oculomotor functions)
## 매 한 줄
> **"매 시선은 의도다"**. 사람의 안구 움직임 (saccade, smooth pursuit, fixation, vergence)은 attention과 intent의 신호 — HCI architecture에서 input modality, foveated rendering의 trigger, 그리고 accessibility의 핵심 channel. 2026 Apple Vision Pro·Quest 3·PSVR 2가 모두 eye tracking을 표준화하면서 architecture-level 시스템 component로 격상.
## 매 핵심
### 매 4 가지 안구 운동
- **Saccade**: 빠른 도약 (200-300°/s), 도중에는 시각 정보 suppress (saccadic suppression).
- **Smooth pursuit**: 움직이는 target 추적, 대상 없이 의식적으로 만들 수 없음.
- **Fixation**: 한 점 응시 (200-300ms 평균), micro-tremor 포함.
- **Vergence**: 양안의 거리 조절 — depth/3D UI에서 핵심.
### 매 architecture 역할
- **Input**: gaze + dwell, gaze + pinch (Vision Pro 모델). 정확도 ~1°.
- **Foveated rendering**: gaze 주변 high-res, 주변부 low-res → GPU 50-70% 절약.
- **Attention metric**: heatmap 기반 UX 검증, A/B test의 implicit signal.
- **Accessibility**: ALS 등 운동 장애 사용자의 통신 channel.
### 매 응용
1. **VR/AR**: foveated rendering, 자연스러운 selection.
2. **Web analytics**: heatmap (Hotjar, Microsoft Clarity).
3. **자동차 HMI**: 운전자 attention 모니터링 (Tesla driver-facing camera, Cadillac Super Cruise).
4. **의료**: 신경학적 진단 (saccade latency = Parkinson 지표).
## 💻 패턴
### WebXR로 gaze ray 얻기 (Vision Pro Safari)
```typescript
// XRSession with eye-tracking feature
const session = await navigator.xr!.requestSession('immersive-vr', {
requiredFeatures: ['hand-tracking', 'eye-tracking'],
});
session.requestAnimationFrame(function frame(_t, xrFrame) {
const referenceSpace = /* … */;
for (const source of xrFrame.session.inputSources) {
if (source.targetRayMode === 'gaze') {
const pose = xrFrame.getPose(source.targetRaySpace, referenceSpace);
if (pose) handleGazeRay(pose.transform);
}
}
session.requestAnimationFrame(frame);
});
```
### Dwell-time selection
```typescript
class GazeDwellSelector {
private hovered: Element | null = null;
private since = 0;
constructor(private readonly thresholdMs = 800) {}
update(target: Element | null, now: number) {
if (target !== this.hovered) {
this.hovered = target; this.since = now;
target?.dispatchEvent(new CustomEvent('gazeenter'));
return;
}
if (target && now - this.since >= this.thresholdMs) {
target.dispatchEvent(new CustomEvent('gazeselect'));
this.since = Number.POSITIVE_INFINITY; // 한 번만 fire
}
}
}
```
### Fixation detection (I-DT algorithm)
```typescript
// I-DT: dispersion-threshold identification
type Sample = { x: number; y: number; t: number };
export function detectFixations(
samples: Sample[],
windowMs = 100,
dispersionDeg = 1.0,
): Array<{ start: number; end: number; cx: number; cy: number }> {
const out: any[] = [];
let i = 0;
while (i < samples.length) {
let j = i + 1;
while (j < samples.length && samples[j].t - samples[i].t < windowMs) j++;
const win = samples.slice(i, j);
const xs = win.map(s => s.x), ys = win.map(s => s.y);
const disp = (Math.max(...xs) - Math.min(...xs))
+ (Math.max(...ys) - Math.min(...ys));
if (disp < dispersionDeg) {
// extend
while (j < samples.length) {
const x2 = [...xs, samples[j].x], y2 = [...ys, samples[j].y];
const d = (Math.max(...x2) - Math.min(...x2))
+ (Math.max(...y2) - Math.min(...y2));
if (d >= dispersionDeg) break;
xs.push(samples[j].x); ys.push(samples[j].y); j++;
}
out.push({
start: samples[i].t, end: samples[j - 1].t,
cx: avg(xs), cy: avg(ys),
});
}
i = j;
}
return out;
}
const avg = (xs: number[]) => xs.reduce((a, b) => a + b, 0) / xs.length;
```
### Foveated rendering hint (WebGPU)
```typescript
// 2026 WebGPU에서 variable rate shading via gaze
const gaze = getGazeNDC(); // [-1,1]^2
device.queue.writeBuffer(uniformBuffer, 0, new Float32Array([
gaze.x, gaze.y, /*innerRadius*/ 0.15, /*outerRadius*/ 0.45,
]));
// fragment shader: distance(uv, gaze) > outer ⇒ discard 75% samples
```
### Saccade 중 UI 변화 (change blindness 활용)
```typescript
// saccade 검출 시 다음 frame에 layout 변경 → 사용자가 인지 못함
function onSaccadeStart(cb: () => void) {
// velocity > 200 deg/s 임계
let last: Sample | null = null;
return (s: Sample) => {
if (last) {
const v = Math.hypot(s.x - last.x, s.y - last.y) / (s.t - last.t) * 1000;
if (v > 200) cb();
}
last = s;
};
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| VR/AR primary input | gaze + pinch (Vision Pro 패턴) |
| Desktop accessibility | dwell selection (800-1500ms) |
| Analytics only | heatmap aggregation, real-time 처리 X |
| 의료 진단 | 120Hz+ 정밀 tracker, raw sample 저장 |
**기본값**: 정확도 1° / 60Hz / dwell 800ms — 일반 UX의 baseline.
## 🔗 Graph
- 부모: [[Human-Computer Interaction]]
- 변형: [[Eye Tracking]]
- 응용: [[Accessibility (A11y)|Accessibility]]
- Adjacent: [[WebXR]]
## 🤖 LLM 활용
**언제**: VR/AR 입력 설계, gaze heatmap 분석 결과 해석.
**언제 X**: gaze data 정확도가 낮은 환경 (일반 webcam 기반 1° 이상 오차)에서 critical input으로 사용 — false trigger 폭주.
## ❌ 안티패턴
- **Midas touch**: 보는 것을 모두 click으로 해석 → 의도하지 않은 trigger. dwell·confirmation 필수.
- **고정 dwell time**: 사용자별 적응 필요 — 노약자는 길게.
- **Saccade 중 UI 깜빡임**: 사용자에 멀미·혼란.
- **Calibration 없이 시작**: 정확도 5° 이상 → 사실상 무용.
## 🧪 검증 / 중복
- Verified (Apple visionOS HIG 2026; Tobii eye-tracking research; Salvucci & Goldberg I-DT 2000).
- 신뢰도 B (HCI 분야 표준이지만 architecture wiki에서는 보조 주제).
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — saccade/fixation/vergence·WebXR·I-DT 알고리즘 |
@@ -0,0 +1,138 @@
---
id: wiki-2026-0508-약한-타입-검사-weak-type-detection
title: 약한 타입 검사 (Weak Type Detection)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Weak Type Detection, TypeScript Weak Types, Excess Property Check]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, types, type-safety]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: typescript-5
---
# 약한 타입 검사 (Weak Type Detection)
## 매 한 줄
> **"매 weak type 은 매 모든 property 가 매 optional 인 type → 매 TypeScript 가 매 어떤 object 든 매 assignable 로 보아 매 typo 매 silently"**. TS 2.4 (2017) 부터 매 specific weak-type assignment check 추가. 매 2026 modern TS 5.7 은 매 strict + exactOptionalPropertyTypes + verbatimModuleSyntax 로 매 default-strict.
## 매 핵심
### 매 weak type 정의
- 매 모든 property 가 매 `?:` (optional).
- 예: `interface Opts { timeout?: number; retry?: number; }`.
### 매 detection rule
- 매 source object 가 매 weak type target 의 매 어떤 property 와도 매 overlap 하지 않으면 → 매 error.
- 매 typo (e.g. `tiemout` instead of `timeout`) → 매 catch.
### 매 응용
1. 매 config object 매 typo 방지.
2. 매 partial type 의 매 안전한 사용.
3. 매 React props 의 매 narrow 검사.
## 💻 패턴
### Basic weak-type error
```typescript
interface Options {
timeout?: number;
retry?: number;
}
function call(opts: Options) { /*...*/ }
// ✗ Error: Type '{ tiemout: number; }' has no properties in common with type 'Options'.
call({ tiemout: 30 });
// ✓
call({ timeout: 30 });
```
### Excess property check (related)
```typescript
// Object literal — excess properties checked
call({ timeout: 30, foo: 1 }); // ✗ Error: 'foo' does not exist
// Variable — only weak-type rule applies
const o = { timeout: 30, foo: 1 };
call(o); // ✓ (excess check skipped, but weak-type still checks overlap)
```
### exactOptionalPropertyTypes (TS 4.4+, default in 2026 setups)
```json
{ "compilerOptions": { "exactOptionalPropertyTypes": true } }
```
```typescript
interface User { name: string; nickname?: string; }
const u: User = { name: "kim", nickname: undefined }; // ✗ Error
const u2: User = { name: "kim" }; // ✓
```
### Branded type to avoid weak-type ambiguity
```typescript
type UserId = string & { readonly __brand: "UserId" };
type OrderId = string & { readonly __brand: "OrderId" };
function getUser(id: UserId) { /*...*/ }
const oid = "ord_1" as OrderId;
getUser(oid); // ✗ Error
```
### Required<> to disable weak detection
```typescript
type StrictOptions = Required<Options>;
function strictCall(opts: StrictOptions) { /*...*/ }
strictCall({ timeout: 30 }); // ✗ retry missing — clearer than weak type
```
### Const assertion for narrow inference
```typescript
const opts = { timeout: 30 } as const;
type T = typeof opts; // { readonly timeout: 30 }
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 config object | 매 weak-type 의 명시적 인지 |
| 매 ID confusion | branded types |
| 매 truly partial input | `Partial<T>` + explicit narrow |
| 매 strict undefined handling | exactOptionalPropertyTypes |
| 매 enum-like literal | `as const` |
**기본값**: 매 `strict: true` + `exactOptionalPropertyTypes: true`.
## 🔗 Graph
- 부모: [[TypeScript]] · [[TypeScript 타입 시스템 (TypeScript Type System)|Type System]]
- 변형: [[Excess Property Check]] · [[Structural Typing]]
- 응용: [[Branded Types]]
- Adjacent: [[선언 파일 dts]]
## 🤖 LLM 활용
**언제**: 매 type error 의 매 explanation / 매 branded type design.
**언제 X**: 매 production code 의 매 mass refactor — 매 incremental.
## ❌ 안티패턴
- **All-optional config**: 매 weak type 의 typo 위험.
- **`any` escape**: 매 weak-type error 회피용 매 `any`.
- **Spreading external object**: 매 weak-type check 우회.
- **Disabling strict**: 매 entire codebase 의 매 type-safety 손실.
## 🧪 검증 / 중복
- Verified (TypeScript 2.4 release notes, TypeScript Handbook 2026, *Effective TypeScript 3e*).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — weak-type / branded / exactOptional 패턴 추가 |
@@ -0,0 +1,201 @@
---
id: wiki-2026-0508-의존성-규칙-dependency-rule
title: 의존성 규칙 (Dependency Rule)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Dependency Rule, Clean Architecture Dependency Rule]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, clean-architecture, dependency-rule, layering]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: nestjs
---
# 의존성 규칙 (Dependency Rule)
## 매 한 줄
> **"매 source code dependency는 안쪽으로만 향한다"**. Robert C. Martin이 *Clean Architecture* (2017)에서 정식화한 핵심 규칙으로, 외곽 layer (frameworks, UI, DB)는 내부 layer (use cases, entities)를 알지만 그 반대는 금지된다 — 도메인의 framework-independence를 강제하는 architectural invariant.
## 매 핵심
### 매 4-layer 모델
- **Entities** (innermost): enterprise-wide business rules. 가장 추상.
- **Use Cases**: application-specific business rules. Entities 사용.
- **Interface Adapters**: controllers, presenters, gateways. Use case에 맞춰 데이터 변환.
- **Frameworks & Drivers** (outermost): Web, DB, external API, UI framework.
### 매 규칙의 정확한 statement
- 안쪽 circle은 바깥쪽 circle의 **이름조차** 알아서는 안 됨 (class, function, variable, 어떤 software entity든).
- 바깥쪽 circle의 데이터 형식이 안쪽으로 새어들어와도 안 됨 — 새는 순간 dependency arrow가 거꾸로 흐름.
- 위반 발견 시 → DIP (Dependency Inversion Principle)로 풀기: interface를 안쪽에 정의, 구현을 바깥쪽에 둠.
### 매 응용
1. **Domain layer에서 ORM annotation 금지**`@Entity` (TypeORM)를 도메인 클래스에 붙이는 순간 도메인이 ORM을 알게 됨.
2. **Use case는 HTTP request/response 모름** — controller가 DTO → command로 mapping.
3. **Test 전략**: 안쪽 layer는 framework 없이 pure unit test 가능. 이게 안 되면 위반 의심.
## 💻 패턴
### Anti-pattern: 도메인이 ORM을 알고 있음
```typescript
// 안티: 도메인 entity가 TypeORM에 의존
import { Entity, Column } from 'typeorm';
@Entity()
export class Order {
@Column() id: string;
@Column() total: number;
// 도메인이 typeorm 패키지에 source-level dependency를 가짐 → 위반
}
```
### Fix: Pure 도메인 + 별도 persistence model
```typescript
// domain/order.ts — framework 모름
export class Order {
constructor(
public readonly id: string,
public readonly total: number,
) {}
static place(items: ReadonlyArray<{ price: number }>): Order {
const total = items.reduce((s, i) => s + i.price, 0);
if (total <= 0) throw new Error('empty order');
return new Order(crypto.randomUUID(), total);
}
}
// infra/persistence/order.entity.ts — ORM 전용
@Entity('orders')
export class OrderRow {
@PrimaryColumn() id!: string;
@Column('numeric') total!: number;
}
// infra/persistence/order.mapper.ts
export const toDomain = (r: OrderRow) => new Order(r.id, Number(r.total));
export const toRow = (o: Order): OrderRow =>
Object.assign(new OrderRow(), { id: o.id, total: o.total });
```
### DIP로 use case → infra 의존 뒤집기
```typescript
// domain/ports/order-repository.ts (안쪽 layer가 interface 정의)
export interface OrderRepository {
save(order: Order): Promise<void>;
findById(id: string): Promise<Order | null>;
}
// application/place-order.usecase.ts (안쪽 layer)
export class PlaceOrderUseCase {
constructor(private readonly repo: OrderRepository) {}
async execute(items: { price: number }[]): Promise<string> {
const order = Order.place(items);
await this.repo.save(order);
return order.id;
}
}
// infra/typeorm-order-repository.ts (바깥쪽 layer가 구현)
export class TypeOrmOrderRepository implements OrderRepository {
constructor(private readonly ds: DataSource) {}
async save(o: Order) { await this.ds.getRepository(OrderRow).save(toRow(o)); }
async findById(id: string) {
const row = await this.ds.getRepository(OrderRow).findOneBy({ id });
return row ? toDomain(row) : null;
}
}
```
### Controller → use case (변환만, 비즈니스 로직 X)
```typescript
@Controller('orders')
export class OrderController {
constructor(private readonly placeOrder: PlaceOrderUseCase) {}
@Post()
async create(@Body() dto: PlaceOrderDto): Promise<{ id: string }> {
const id = await this.placeOrder.execute(dto.items);
return { id };
}
}
```
### ESLint로 dependency direction 강제
```js
// .eslintrc.cjs — eslint-plugin-boundaries
module.exports = {
settings: {
'boundaries/elements': [
{ type: 'domain', pattern: 'src/domain/*' },
{ type: 'application', pattern: 'src/application/*' },
{ type: 'infra', pattern: 'src/infra/*' },
{ type: 'web', pattern: 'src/web/*' },
],
},
rules: {
'boundaries/element-types': ['error', {
default: 'disallow',
rules: [
{ from: 'application', allow: ['domain'] },
{ from: 'infra', allow: ['domain', 'application'] },
{ from: 'web', allow: ['application', 'domain'] },
],
}],
},
};
```
### Test가 위반을 잡아냄
```typescript
// domain은 framework import 없이 build 되어야 함
import { Order } from './order';
test('place creates order with summed total', () => {
const o = Order.place([{ price: 10 }, { price: 5 }]);
expect(o.total).toBe(15);
});
// jest 단독, DB·HTTP·DI container 없이 통과 → 규칙 준수 신호
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 작은 CRUD app, 팀 1-2명 | 규칙 약화 (도메인=ORM entity 허용) |
| 비즈니스 로직 복잡, 장수명 | 매 strict 적용 |
| Framework 교체 가능성 (DB, web) | 매 strict |
| Prototype·spike | 무시 가능 |
**기본값**: 도메인 layer는 framework import 0개로 시작 — 필요할 때 위반 허용.
## 🔗 Graph
- 부모: [[Clean Architecture]]
- 변형: [[Hexagonal Architecture Ports and Adapters]] · [[Onion Architecture]]
- 응용: [[Domain-Driven Design]]
- Adjacent: [[Dependency Inversion Principle]] · [[SOLID Principles]]
## 🤖 LLM 활용
**언제**: 코드 리뷰에서 "이 import가 layer 규칙을 깨는가?" 판단, refactor 계획 수립.
**언제 X**: 작은 script·prototype에서 규칙 강제 — 과잉.
## ❌ 안티패턴
- **도메인에 `@Entity` 부착**: ORM 의존이 안쪽으로 leak.
- **Use case에서 `req.body` 직접 참조**: HTTP 형식이 안쪽으로 leak.
- **Entity가 Repository import**: 안쪽 → 바깥 dependency.
- **DTO를 도메인 모델로 재사용**: layer 경계 소실.
## 🧪 검증 / 중복
- Verified (Robert C. Martin, *Clean Architecture*, 2017; Uncle Bob blog "The Clean Architecture", 2012).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Dependency Rule 정의·layer model·DIP 적용 패턴 정리 |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-인터페이스와-포트-어댑터-interfaces-and-por
title: 인터페이스와 포트-어댑터 (Interfaces and Ports-Adapters)
category: 10_Wiki/Topics
status: duplicate
canonical_id: wiki-2026-0508-hexagonal-architecture-ports-and-adapters
duplicate_of: "[[Hexagonal Architecture Ports and Adapters]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, architecture, hexagonal, ports-adapters]
last_reinforced: 2026-05-10
github_commit: pending
---
# 인터페이스와 포트-어댑터 (Interfaces and Ports-Adapters)
> **이 문서는 [[Hexagonal Architecture Ports and Adapters]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- Port = 도메인이 외부와 대화하는 추상 interface.
- Adapter = port의 구체 구현 (REST controller, DB repository, message consumer 등).
- 도메인은 port에만 의존, adapter에 의존하지 않음 (Dependency Inversion).
## 🔗 Graph
- 부모: [[Hexagonal Architecture Ports and Adapters]] (canonical)
- 인접: [[Dependency Inversion Principle]] · [[Clean Architecture]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,153 @@
---
id: wiki-2026-0508-하향식-탐색-top-down-approach
title: 하향식 탐색 Top-Down Approach
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Top-Down Design, Stepwise Refinement, 하향식 설계]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, design-method, decomposition]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: language-agnostic
framework: design-method
---
# 하향식 탐색 (Top-Down Approach)
## 매 한 줄
> **"매 큰 그림 → 매 세부"**. 매 system 의 high-level abstraction 부터 시작 → 매 단계마다 decomposition. 매 1970s Niklaus Wirth 의 stepwise refinement 가 origin — 매 modern 2026 microservice / DDD 의 strategic design 까지 매 살아있는 design heuristic.
## 매 핵심
### 매 핵심 idea
- **매 추상 → 매 구체**: System 전체 → subsystems → modules → functions → lines.
- **매 deferred decision**: Lower-level detail 의 결정 의 미루기 — 매 abstraction barrier.
- **매 wishful thinking**: 매 "이 helper 가 있다 가정" → 매 나중에 implement.
### 매 vs Bottom-Up
- Top-Down: 매 unknown / new system 의 design 적합. 매 risk: leaf-level 에서 매 mismatch 발견.
- Bottom-Up: 매 reusable primitive 부터. 매 known domain (e.g. data pipeline) 적합.
- 매 실전: 매 hybrid (meet-in-middle) 의 default.
### 매 응용
1. DDD strategic design — bounded context → context map → aggregate.
2. Microservice decomposition — capability mapping → service boundary.
3. Functional decomposition — main() → step functions → primitives.
## 💻 패턴
### Stepwise refinement (pseudocode → real)
```python
# Level 0: intent
def process_orders():
"""Process today's orders end-to-end."""
# Level 1: high-level steps
def process_orders():
orders = fetch_pending_orders()
validated = [o for o in orders if validate(o)]
results = [charge_and_ship(o) for o in validated]
notify_customers(results)
# Level 2: implement leaves (deferred until now)
def fetch_pending_orders() -> list[Order]:
return db.query(Order).filter(Order.status == "pending").all()
```
### Wishful thinking — assume helpers exist
```python
def render_dashboard(user_id: str) -> HTML:
user = fetch_user(user_id) # assume
metrics = compute_metrics(user) # assume
chart = build_chart(metrics) # assume
return layout(header(user), chart) # assume
# 매 implement leaves 의 last.
```
### DDD top-down decomposition
```
Bounded Context: Order Management
├─ Aggregate: Order
│ ├─ Entity: OrderLine
│ └─ Value Object: Money, Address
├─ Aggregate: Cart
└─ Domain Service: Pricing
```
### Microservice capability decomposition
```yaml
# top-down: business capability → service
Capability: Checkout
Sub-capability: Cart Management → cart-service
Sub-capability: Payment → payment-service
Sub-capability: Order Persistence → order-service
Sub-capability: Notification → notification-service
```
### Test-first top-down (London-school TDD)
```python
def test_charge_order_calls_gateway(mocker):
gateway = mocker.Mock()
repo = mocker.Mock()
svc = OrderService(gateway, repo) # 매 collaborator 추측
svc.charge(Order(id=1, total=100))
gateway.charge.assert_called_once_with(100)
# 매 mock 의 design 의 driver — 매 collaborator interface 의 top-down emerge.
```
### Recursive descent parser (top-down classic)
```python
def parse_expr(tokens):
left = parse_term(tokens)
while tokens.peek() in ("+", "-"):
op = tokens.next()
right = parse_term(tokens)
left = BinOp(op, left, right)
return left
def parse_term(tokens):
left = parse_factor(tokens)
# ...
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Greenfield, unknown domain | **Top-Down** (explore via decomposition) |
| Known primitives, integration heavy | Bottom-Up |
| Library 의 design | Bottom-Up (primitive first) |
| Application / product 의 design | Top-Down → Hybrid |
| Refactor existing code | Inside-Out (seam first) |
**기본값**: Top-Down 으로 strategy → bottom-up primitive 의 meet-in-middle.
## 🔗 Graph
- 부모: [[아키텍처 패턴 지식]] · [[객체 지향 소프트웨어 아키텍처 설계]]
- 변형: [[Bottom-Up Approach]]
- 응용: [[DDD]] · [[Hexagonal_Architecture]] · [[Refactoring Techniques (리팩토링 기법)]]
- Adjacent: [[추상화(Abstraction)]] · [[High-Cohesion-Low-Coupling]]
## 🤖 LLM 활용
**언제**: 매 새로운 system 의 design 의 시작, 매 unknown domain 의 explore, 매 architectural conversation 의 frame.
**언제 X**: 매 well-known primitive 의 mechanical assembly, 매 retrofit / legacy refactor (seam-first 가 더 안전).
## ❌ 안티패턴
- **Pseudocode 가 implementation 화**: 매 leaf 의 implement 안 함. 매 wishful 의 영원히 wish.
- **Premature decomposition**: 매 너무 일찍 fix layer boundary → 매 나중에 leaky.
- **No bottom check**: 매 leaf primitive 가 매 expressible 인지 verify 안 함 → 매 mismatch.
## 🧪 검증 / 중복
- Verified (Wirth 1971 "Program Development by Stepwise Refinement"; Evans DDD 2003).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — top-down 의 stepwise refinement / wishful thinking / DDD-microservice 의 application |