docs(10_Wiki): Topic_Business/General/Graphic/Programming을 Topics/ 하위로 이동

최상위 10_Wiki/Topic_*였던 4개 카테고리 폴더를 10_Wiki/Topics/Topic_* 로 재배치.
콘텐츠 변경 없음(순수 폴더 이동) — Topics/ 하위 나머지 폴더는 이미 지난 커밋에서
전부 정리된 상태(잔존 항목은 에이전트 운영 상태 및 사용자가 보존을 요청한
업데이트0615/무제 3.canvas 뿐).
This commit is contained in:
Antigravity Agent
2026-07-05 00:44:01 +09:00
parent e9cbf23ab5
commit 9a135bd19d
6127 changed files with 0 additions and 0 deletions
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-api-응답-및-에러-핸들링-아키텍처
title: API 응답 및 에러 핸들링 아키텍처
category: 10_Wiki/Topics
status: duplicate
canonical_id: api-error-handling
duplicate_of: "[[API Error Handling]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, api, error-handling]
last_reinforced: 2026-05-10
github_commit: pending
---
# API 응답 및 에러 핸들링 아키텍처
> **이 문서는 [[API Error Handling]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약 (specialization aspects)
- 매 Result<T, E> 타입 + Discriminated Union 의 typed error.
- 매 Response Envelope: `{ success, data, error }` 구조.
- 매 HTTP status code + domain error code 의 separation.
## 🔗 Graph
- Adjacent: [[Result Type]] · [[Discriminated_Unions|Discriminated Unions]] · [[Zod 런타임 유효성 검사 통합]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,139 @@
---
id: wiki-2026-0508-aspnet-core
title: ASP.NET Core
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [ASP.NET Core, .NET Web, Kestrel, Minimal API]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [dotnet, csharp, web, backend]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: csharp
framework: ASP.NET Core 9 / .NET 9
---
# ASP.NET Core
## 매 한 줄
> **"매 cross-platform high-performance 의 .NET 의 web framework"**. 매 Microsoft 의 2016 release 후 의 modular middleware pipeline + Kestrel server + DI built-in 의 design — 매 2026 의 .NET 9 의 native AOT, Minimal API, Blazor United, gRPC 의 first-class support 로 매 enterprise + cloud-native workload 의 dominant choice.
## 매 핵심
### 매 Architecture
- **Kestrel**: 매 cross-platform HTTP server (libuv → managed sockets).
- **Middleware pipeline**: 매 request 의 ordered chain — auth, logging, routing, endpoint.
- **DI container** (built-in): scoped/singleton/transient.
- **Configuration**: appsettings.json + env + secrets + Azure KeyVault 의 layered.
- **Hosting model**: Generic Host (`IHostBuilder`) → minimal `WebApplication`.
### 매 API styles
1. **Minimal API** (.NET 6+): top-level, lambda-based — small services 의 default.
2. **MVC controllers**: 매 conventional REST.
3. **Blazor Server / WASM / United** (.NET 8+): full-stack C# UI.
4. **gRPC**: HTTP/2, Protobuf — service-to-service.
5. **SignalR**: WebSocket / long-poll.
### 매 응용
1. REST API (Stripe, Shopify-style backends).
2. gRPC microservice mesh (.NET 9 의 native AOT 의 cold-start fast).
3. Blazor 의 internal admin panel.
4. Azure Functions / AWS Lambda (isolated worker).
## 💻 패턴
### Minimal API
```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<AppDb>(o => o.UseNpgsql(builder.Configuration.GetConnectionString("Db")));
builder.Services.AddAuthentication().AddJwtBearer();
var app = builder.Build();
app.MapGet("/users/{id:int}", async (int id, AppDb db) =>
await db.Users.FindAsync(id) is { } u ? Results.Ok(u) : Results.NotFound());
app.MapPost("/users", async (User u, AppDb db) => {
db.Users.Add(u); await db.SaveChangesAsync();
return Results.Created($"/users/{u.Id}", u);
});
app.Run();
```
### Middleware
```csharp
app.Use(async (ctx, next) => {
var sw = Stopwatch.StartNew();
await next();
Console.WriteLine($"{ctx.Request.Path} {sw.ElapsedMilliseconds}ms");
});
```
### DI + scoped service
```csharp
builder.Services.AddScoped<IRepo, EfRepo>();
app.MapGet("/x", (IRepo r) => r.GetAll());
```
### Native AOT (.NET 9)
```xml
<PropertyGroup>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
```
- 매 single-file binary, 매 cold-start <10ms, 매 reflection 의 limit.
### Authentication (JWT)
```csharp
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(o => {
o.TokenValidationParameters = new() {
ValidIssuer = "https://issuer",
ValidAudience = "api",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret))
};
});
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/me", (ClaimsPrincipal u) => u.Identity?.Name).RequireAuthorization();
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Small service / prototype | Minimal API |
| Complex routing / filters | MVC Controllers |
| Service-to-service (internal) | gRPC |
| Real-time (chat, dashboard) | SignalR |
| Cold-start sensitive (lambda) | Native AOT + Minimal API |
| Full-stack C# | Blazor United |
**기본값**: 매 Minimal API + EF Core + JWT — 매 modern .NET 의 standard stack.
## 🔗 Graph
- 응용: [[Microservices]]
- Adjacent: [[Kestrel]]
## 🤖 LLM 활용
**언제**: Minimal API endpoint 의 생성, EF Core query 의 LINQ, middleware 의 boilerplate.
**언제 X**: 매 native AOT 의 reflection-heavy 의 third-party library 의 compatibility — 매 manual 의 verify.
## ❌ 안티패턴
- **Sync-over-async** (`.Result`, `.Wait()`): 매 thread pool 의 deadlock — 매 `await` 의 사용.
- **DbContext singleton**: 매 EF Core 의 not thread-safe — 매 scoped.
- **Middleware order 의 random**: 매 auth 의 routing 의 후 — 매 401 의 not enforced.
- **Returning IQueryable from controller**: 매 N+1, 매 connection 의 leak.
## 🧪 검증 / 중복
- Verified (learn.microsoft.com/aspnet/core, .NET 9 release notes).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Minimal API + AOT + JWT patterns |
@@ -0,0 +1,142 @@
---
id: wiki-20260508-ast-abstract-syntax-tree--redir
title: AST (Abstract Syntax Tree)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [AST, Abstract Syntax Tree, 추상 구문 트리]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
verification_status: applied
tags: [compiler, parser, ast, language]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: babel-parser, ts-morph, tree-sitter
---
# AST (Abstract Syntax Tree)
## 매 한 줄
> **"매 source code 의 tree-shaped semantic skeleton"**. 매 lexer 의 token stream 을 parser 가 grammar rule 따라 nested node 의 tree 로 변환 — comment/whitespace/parens 의 trivia 를 제거하고 매 program 의 structural meaning 만 보존. 매 2026 의 Babel·SWC·TypeScript Compiler·Tree-sitter·Rust analyzer 의 모든 modern toolchain 의 핵심 IR.
## 매 핵심
### 매 AST vs CST
- **CST** (Concrete Syntax Tree): 매 source 의 every char 보존 — formatter, linter용.
- **AST**: 매 semantic structure 만 — compiler, transpiler, type checker용.
- 매 trade-off: lossless ↔ analysis-friendly.
### 매 Node 의 구조
-`type` field (e.g. `BinaryExpression`, `Identifier`).
- 매 children (positional or named).
-`loc`/`range` (source position).
- 매 ESTree spec — JS 의 standard AST shape.
### 매 응용
1. **Compiler**: AST → IR → bytecode/machine code.
2. **Transpiler** (Babel, SWC): AST → transformed AST → code.
3. **Linter** (ESLint): AST traversal + rule matching.
4. **Formatter** (Prettier): AST → printer.
5. **IDE**: hover, refactor, go-to-def 의 AST query.
6. **Codemod** (jscodeshift, ts-morph): bulk refactor.
## 💻 패턴
### Babel parse
```typescript
import { parse } from "@babel/parser";
const code = `const x = 1 + 2;`;
const ast = parse(code, { sourceType: "module" });
console.log(ast.program.body[0]);
// VariableDeclaration { kind: "const", declarations: [...] }
```
### Visitor (transform)
```typescript
import traverse from "@babel/traverse";
traverse(ast, {
BinaryExpression(path) {
if (path.node.operator === "+") {
// 매 constant folding
const { left, right } = path.node;
if (left.type === "NumericLiteral" && right.type === "NumericLiteral") {
path.replaceWith({ type: "NumericLiteral", value: left.value + right.value });
}
}
},
});
```
### TypeScript Compiler API
```typescript
import * as ts from "typescript";
const source = ts.createSourceFile("x.ts", "const x: number = 1;", ts.ScriptTarget.Latest);
function visit(node: ts.Node) {
if (ts.isVariableDeclaration(node)) {
console.log(node.name.getText(source));
}
ts.forEachChild(node, visit);
}
visit(source);
```
### Tree-sitter (incremental)
```javascript
const Parser = require("tree-sitter");
const TS = require("tree-sitter-typescript").typescript;
const parser = new Parser();
parser.setLanguage(TS);
const tree = parser.parse("const x = 1;");
// 매 incremental: tree.edit(...) 로 partial reparse
```
### ts-morph (codemod)
```typescript
import { Project } from "ts-morph";
const proj = new Project();
const sf = proj.addSourceFileAtPath("src/foo.ts");
sf.getFunctions().forEach((fn) => fn.setIsAsync(true));
sf.saveSync();
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Compile / transpile JS/TS | Babel (@babel/parser) or SWC |
| IDE / editor highlighting | Tree-sitter (incremental, fast) |
| TypeScript-specific 의 type-aware refactor | TypeScript Compiler API or ts-morph |
| Linting | ESLint (espree/typescript-eslint) |
| 1-off codemod | jscodeshift or ts-morph |
| Native speed (Rust/Go) | SWC, Rome, Biome |
**기본값**: 매 TS 의 type-aware 작업 → ts-morph. 매 perf-critical 의 transpile → SWC. 매 editor → Tree-sitter.
## 🔗 Graph
- 부모: [[Parser]]
- 응용: [[ESLint]] · [[Prettier]]
## 🤖 LLM 활용
**언제**: 매 codemod 의 generation, AST node type 의 explanation, visitor pattern 의 boilerplate.
**언제 X**: 매 large-scale 의 type-aware refactor — ts-morph 의 deterministic 가 더 안전.
## ❌ 안티패턴
- **Regex 의 code 의 transform**: 매 nested syntax 의 break — AST 의 use.
- **Mutate AST 의 children array 의 직접**: 매 visitor 의 path API 의 use.
- **Source map 의 무시**: 매 transform 후 의 debug 의 broken — `retainLines`/sourcemap 의 emit.
## 🧪 검증 / 중복
- Verified (Babel docs, TS Compiler API, ESTree spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full AST treatment with Babel/TS/Tree-sitter patterns |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-ci-cd-파이프라인-자동화
title: CI/CD 파이프라인 자동화
category: 10_Wiki/Topics
status: duplicate
canonical_id: ci-cd-pipeline
duplicate_of: "[[CI_CD_Pipeline|CI/CD Pipeline]]"
aliases: []
source_trust_level: A
confidence_score: 0.92
verification_status: redirected
tags: [duplicate, cicd, automation]
last_reinforced: 2026-05-10
github_commit: pending
---
# CI/CD 파이프라인 자동화
> **이 문서는 [[CI_CD_Pipeline|CI/CD Pipeline]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약 (specialization aspects)
- 매 한국어 alias 의 lookup 용.
- 매 build → test → deploy 의 자동화 — 매 GitHub Actions / GitLab CI / Jenkins 의 modern stack.
## 🔗 Graph
- 부모: [[CI_CD_Pipeline|CI/CD Pipeline]] (canonical)
- Adjacent: [[Continuous Integration (CI)]] · [[TeamCity]] · [[데브섹옵스 (DevSecOps) 환경에서의 지속적인 보안 검사]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-ci-cd-파이프라인
title: CI/CD 파이프라인
category: 10_Wiki/Topics
status: duplicate
canonical_id: ci-cd-pipeline
duplicate_of: "[[CI_CD_Pipeline|CI/CD Pipeline]]"
aliases: []
source_trust_level: A
confidence_score: 0.92
verification_status: redirected
tags: [duplicate, cicd]
last_reinforced: 2026-05-10
github_commit: pending
---
# CI/CD 파이프라인
> **이 문서는 [[CI_CD_Pipeline|CI/CD Pipeline]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약 (specialization aspects)
- 매 한국어 alias.
- 매 commit → build → test → deploy 의 자동화.
## 🔗 Graph
- 부모: [[CI_CD_Pipeline|CI/CD Pipeline]] (canonical)
- Adjacent: [[Continuous Integration (CI)]] · [[CI_CD 파이프라인 자동화]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-cst-구체-구문-트리
title: CST (구체 구문 트리)
category: 10_Wiki/Topics
status: duplicate
canonical_id: cst
duplicate_of: "[[CST (Concrete Syntax Tree)]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, parser, compiler]
last_reinforced: 2026-05-10
github_commit: pending
---
# CST (구체 구문 트리)
> **이 문서는 [[CST (Concrete Syntax Tree)]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약 (specialization aspects)
- 매 한국어 alias 의 lookup 용.
- 매 every char (whitespace, comment) 의 lossless 보존 — formatter, linter, IDE refactor 의 source.
- 매 vs AST: AST 는 semantic 만, CST 는 surface 의 모든 token.
## 🔗 Graph
- Adjacent: [[AST (Abstract Syntax Tree)]] · [[Parser]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,121 @@
---
id: wiki-2026-0508-chromium
title: Chromium
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Chromium, Blink, V8 Browser]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [browser, engine, blink, v8]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: cpp
framework: Blink, V8, Skia
---
# Chromium
## 매 한 줄
> **"매 Google 의 open-source browser engine codebase"**. 매 Blink (rendering, fork of WebKit, 2013) + V8 (JS) + Skia (graphics) + Mojo (IPC) 의 결합 — 매 2026 의 Chrome / Edge / Brave / Opera / Arc / Vivaldi / Electron / Tauri (WebView2) 의 base. 매 multi-process security architecture (sandbox, site isolation) 의 reference.
## 매 핵심
### 매 Architecture
- **Browser process**: 매 UI, network, disk — privileged.
- **Renderer process** (per site): 매 Blink + V8 — sandboxed.
- **GPU process**: Skia 의 hardware-accel.
- **Utility processes**: audio, network service.
- **Mojo IPC**: typed message passing.
### 매 Components
- **Blink**: HTML parse, CSS, layout, paint, compositor.
- **V8**: JS + WebAssembly (Sparkplug, Maglev, TurboFan, Liftoff).
- **Skia**: 2D graphics.
- **WebRTC, WebGPU, WebCodecs**: media.
- **Site Isolation**: 매 origin 의 process-level isolation — Spectre 의 mitigate.
### 매 응용
1. Chrome browser (1B+ users).
2. Embed: Electron, Tauri (WebView2 on Win), CEF.
3. Headless: Puppeteer, Playwright (chromium build).
4. Forks: Edge (2020+), Brave, Vivaldi, Arc, Opera.
## 💻 패턴
### Build chromium (sketch)
```bash
git clone https://chromium.googlesource.com/chromium/src.git
cd src
gclient sync
gn gen out/Release --args='is_debug=false'
autoninja -C out/Release chrome
```
### Headless via Puppeteer
```javascript
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({ headless: "new", args: ["--no-sandbox"] });
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "x.png" });
await browser.close();
```
### CDP (Chrome DevTools Protocol) raw
```javascript
const client = await page.target().createCDPSession();
await client.send("Performance.enable");
const metrics = await client.send("Performance.getMetrics");
```
### Site Isolation flag
```bash
chrome --site-per-process # default since 2018
chrome --disable-site-isolation-trials # debug only — never prod
```
### V8 inspect
```bash
node --inspect-brk app.js
# DevTools 의 chrome://inspect 의 attach
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Build cross-platform desktop app | Tauri (smaller) > Electron (mature) |
| Web automation | Playwright > Puppeteer (multi-engine) |
| Custom browser | fork Chromium (Brave-style) — 매 maintenance cost 큼 |
| Embed web view | WebView2 (Win) / WKWebView (Mac) — 매 native > Electron |
**기본값**: 매 web app 의 Electron / Tauri 의 ship — 매 user-facing 의 자체 fork X.
## 🔗 Graph
- 변형: [[Chrome]] · [[Electron]]
- 응용: [[Playwright]]
- Adjacent: [[Blink]] · [[V8]] · [[WebKit]]
## 🤖 LLM 활용
**언제**: CDP 사용법, Puppeteer/Playwright script, Chromium component 의 explanation.
**언제 X**: 매 Chromium 의 internal C++ refactor — 매 LLM 의 outdated 가능.
## ❌ 안티패턴
- **--no-sandbox in production**: 매 sandboxing 의 disable — RCE 의 risk.
- **--disable-web-security**: 매 dev 만 — prod 의 catastrophic.
- **Pinning to old Chromium**: 매 CVE 의 backlog — 매 latest stable.
- **Electron + remote module**: 매 deprecated, 매 contextIsolation: true.
## 🧪 검증 / 중복
- Verified (chromium.org, source.chromium.org, V8 blog).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — multi-process arch + Puppeteer/CDP patterns |
@@ -0,0 +1,161 @@
---
id: wiki-2026-0508-code-minification
title: Code Minification
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Minification, JS Minify, CSS Minify, Bundle Minification]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [build, performance, javascript, web]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: javascript
framework: esbuild/swc/terser
---
# Code Minification
## 매 한 줄
> **"매 source code 의 semantic 보존 + size 의 minimize"**. 매 whitespace/comment 제거 + identifier rename + dead code elimination + constant folding. 2026 의 esbuild/SWC/OXC 의 native-speed mainstream, Terser 의 max compression fallback.
## 매 핵심
### 매 변환 단계
- **Strip**: whitespace, comments, semicolon redundancy.
- **Mangle**: local identifier → 매 short (a, b, c).
- **Compress**: constant fold, DCE, inline single-use, sequence expression.
- **Property mangle** (optional): `obj.privateField``obj.a` (매 risky).
### 매 Tree shaking
- ES module static imports 의 분석 → 매 unused exports 의 제거.
- `sideEffects: false` in package.json 의 강력한 hint.
### 매 Source maps
- Mangled output 의 production debugging 의 essential.
- `//# sourceMappingURL=app.js.map` + Sentry/DataDog upload.
### 매 응용
1. JS bundle 의 70-80% 크기 reduction (gzip 후 추가).
2. CSS 의 50% reduction (whitespace + selector merging).
3. HTML 의 inline asset minification (Astro, Next).
## 💻 패턴
### esbuild (fastest, default for new)
```javascript
// build.mjs
import { build } from 'esbuild';
await build({
entryPoints: ['src/app.ts'],
bundle: true,
minify: true, // whitespace + identifier + syntax
sourcemap: true,
target: ['es2022'],
treeShaking: true,
outfile: 'dist/app.js',
});
```
### SWC (Rust, used by Next/Parcel)
```javascript
// .swcrc
{
"jsc": { "target": "es2022", "minify": { "compress": true, "mangle": true } },
"minify": true,
"sourceMaps": true
}
```
### Terser (max compression, slower)
```javascript
import { minify } from 'terser';
const out = await minify(src, {
compress: { passes: 3, pure_getters: true, unsafe_arrows: true },
mangle: { properties: { regex: /^_/ } }, // 매 only _-prefixed
format: { comments: false },
sourceMap: { url: 'app.js.map' },
});
```
### Vite production
```javascript
// vite.config.ts
export default {
build: {
minify: 'esbuild', // or 'terser' for max
sourcemap: true,
rollupOptions: {
output: { manualChunks: { vendor: ['react', 'react-dom'] } },
},
},
};
```
### CSS — Lightning CSS
```javascript
import { transform } from 'lightningcss';
const { code } = transform({
filename: 'style.css',
code: Buffer.from(src),
minify: true,
targets: { chrome: 100 << 16, safari: 16 << 16 },
});
```
### Sentry source map upload
```bash
sentry-cli sourcemaps inject ./dist
sentry-cli sourcemaps upload --release "$VERSION" ./dist
# 매 production 에 .map 의 ship 의 X — Sentry 의 server-side 보관
```
### DCE / pure annotation
```javascript
// 매 tree shaker 에 hint
const heavyConst = /*#__PURE__*/ buildHeavy();
// 매 unused → bundle 에서 제거
```
## 매 결정 기준
| 상황 | Tool |
|---|---|
| Default new project | esbuild / SWC |
| Maximum compression | Terser (passes: 3) |
| CSS | Lightning CSS |
| HTML | html-minifier-terser |
| Library publish | Rollup + esbuild minify |
| Browser extension | esbuild (size budget) |
**기본값**: esbuild minify + tree shake + source maps + Sentry upload.
## 🔗 Graph
- 부모: [[Web_Performance]]
- 변형: [[Code Splitting]] · [[Compression]]
- 응용: [[Bundle_Analysis]] · [[Source_Maps]]
- Adjacent: [[esbuild]] · [[Vite]] · [[Rollup]]
## 🤖 LLM 활용
**언제**: build config 작성, minifier option tuning, bundle analysis.
**언제 X**: 매 generated bundle 의 manual edit — 매 source 의 수정 후 rebuild.
## ❌ 안티패턴
- **No source map in prod**: 매 stack trace 의 obfuscated — debug 불가.
- **Property mangle without test**: 매 `obj["field"]` access 의 break.
- **Minify before bundling**: 매 cross-module DCE 의 손실.
- **Comments preserved**: license 의 `/*! */` 만 keep, rest strip.
- **One huge bundle**: code split 의 X — initial load 의 huge.
## 🧪 검증 / 중복
- Verified (esbuild docs, Terser README, Vite docs, Lightning CSS docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — esbuild/SWC/Terser/Lightning CSS patterns + DCE |
@@ -0,0 +1,175 @@
---
id: wiki-2026-0508-dom-요소-조작-및-타입-좁히기
title: DOM 요소 조작 및 타입 좁히기
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [DOM Manipulation, Type Narrowing, querySelector Typing]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, dom, web, type-narrowing]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: dom
---
# DOM 요소 조작 및 타입 좁히기
## 매 한 줄
> **"매 DOM API 의 untyped boundary 의 TypeScript narrowing 의 적용"**. 매 `querySelector` 의 default `Element | null` 위 의 generic + instanceof + assertion. 2026 의 strict null checks + satisfies + lib.dom.d.ts 의 mainstream type ergonomics.
## 매 핵심
### 매 Type narrowing tools
- **Generic param**: `querySelector<HTMLInputElement>(...)` — runtime check 의 X, 매 assertion 만.
- **`instanceof`**: 매 runtime check + narrow.
- **Type guard function**: `function isInput(el): el is HTMLInputElement`.
- **Discriminated property**: `el.tagName === 'INPUT'` (의 narrow X — manual cast 필요).
### 매 Null safety
- `querySelector``null` 의 always 가능 — 매 explicit check.
- `getElementById` 의 same — `HTMLElement | null`.
- `as!` non-null assertion 의 last resort — 매 prefer guard.
### 매 응용
1. Form value 추출 + validation.
2. Dynamic widget hydration (서버 HTML 위 의 JS enhance).
3. Custom element / Web Component 의 typed access.
## 💻 패턴
### querySelector with generic
```typescript
// 매 generic 의 assertion 만 — 매 null 의 still 가능
const input = document.querySelector<HTMLInputElement>('#email');
if (!input) throw new Error('email input missing');
input.value; // 매 narrowed to HTMLInputElement
```
### instanceof guard
```typescript
const el = document.getElementById('email');
if (el instanceof HTMLInputElement) {
el.value = 'test@example.com'; // 매 narrowed
} else {
throw new Error('not an input');
}
```
### Custom type guard
```typescript
function isInput(el: Element | null): el is HTMLInputElement {
return el instanceof HTMLInputElement;
}
function getValue(selector: string): string {
const el = document.querySelector(selector);
if (!isInput(el)) throw new Error(`${selector} is not input`);
return el.value;
}
```
### Helper: assertElement
```typescript
function $<T extends HTMLElement>(
selector: string,
ctor: new () => T = HTMLElement as new () => T,
root: ParentNode = document,
): T {
const el = root.querySelector(selector);
if (!el) throw new Error(`Missing: ${selector}`);
if (!(el instanceof ctor)) throw new Error(`Wrong type: ${selector}`);
return el as T;
}
const form = $('#login', HTMLFormElement);
const email = $('input[name=email]', HTMLInputElement, form);
```
### Form data — typed
```typescript
function getFormData<T extends Record<string, string>>(form: HTMLFormElement): T {
const fd = new FormData(form);
return Object.fromEntries(fd.entries()) as T;
}
type LoginForm = { email: string; password: string };
const data = getFormData<LoginForm>(form);
```
### Event delegation with narrowing
```typescript
document.addEventListener('click', (e) => {
const target = e.target;
if (!(target instanceof HTMLElement)) return;
const btn = target.closest<HTMLButtonElement>('button[data-action]');
if (!btn) return;
switch (btn.dataset.action) {
case 'save': return save();
case 'delete': return remove(btn.dataset.id!);
default: throw new Error(`Unknown action: ${btn.dataset.action}`);
}
});
```
### Custom element typing
```typescript
class MyToggle extends HTMLElement {
toggle() { this.toggleAttribute('open'); }
}
customElements.define('my-toggle', MyToggle);
declare global {
interface HTMLElementTagNameMap { 'my-toggle': MyToggle; }
}
const t = document.querySelector('my-toggle'); // 매 typed as MyToggle | null
t?.toggle();
```
### satisfies for config (2026 idiom)
```typescript
const handlers = {
'#save': (el: HTMLButtonElement) => el.addEventListener('click', save),
'#email': (el: HTMLInputElement) => el.addEventListener('blur', validate),
} satisfies Record<string, (el: HTMLElement) => void>;
```
## 매 결정 기준
| 상황 | Pattern |
|---|---|
| Single fetch + null OK | `querySelector<T>` + null check |
| Strict invariant | `$()` helper with ctor |
| Multiple element types | instanceof in switch |
| Reusable check | Custom type guard |
| Event handler | `target instanceof HTMLElement` |
| Custom element | HTMLElementTagNameMap augment |
**기본값**: assertElement helper + instanceof + custom guards. `as` casts 의 last resort 만.
## 🔗 Graph
- 부모: [[TypeScript]] · [[DOM]]
- 변형: [[Discriminated_Unions]]
- 응용: [[DOM 요소 조작]] · [[Web_Components]]
## 🤖 LLM 활용
**언제**: helper 작성, type guard 추출, refactor untyped jQuery → typed TS.
**언제 X**: 매 framework (React/Vue/Svelte) 안 — 매 framework type 의 사용.
## ❌ 안티패턴
- **`as HTMLInputElement` everywhere**: runtime mismatch 의 silent.
- **`!` non-null assertion 남발**: 매 null check 의 미루기 — runtime crash.
- **`any` for events**: 매 `Event` subclass 의 사용.
- **`getElementById` raw return 사용**: null check skip.
- **innerHTML with user input**: 매 XSS — `textContent` / DOMPurify 의 사용.
## 🧪 검증 / 중복
- Verified (TypeScript handbook, lib.dom.d.ts, MDN DOM docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — generic/instanceof/guard/helper patterns for typed DOM |
@@ -0,0 +1,194 @@
---
id: wiki-2026-0508-dom-요소-조작
title: DOM 요소 조작
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [DOM Manipulation, Vanilla JS DOM, Document API]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [dom, javascript, web, browser]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: javascript
framework: dom
---
# DOM 요소 조작
## 매 한 줄
> **"매 Document 의 tree 의 query + mutation 의 web 기본 API"**. 매 jQuery 의 era 종료, 2026 의 modern DOM (querySelector, classList, dataset, MutationObserver) 의 충분 + framework (React/Solid/Svelte) 의 abstraction 위. 매 vanilla 의 fast path + 매 small widget 의 right tool.
## 매 핵심
### 매 Query
- `getElementById(id)` — 매 fastest single lookup.
- `querySelector(sel)` / `querySelectorAll(sel)` — CSS selector general.
- `closest(sel)` — 매 ancestor traversal.
- `matches(sel)` — boolean check.
### 매 Mutate
- **Create**: `createElement`, `cloneNode(true)`, `<template>` + `content.cloneNode`.
- **Insert**: `append`, `prepend`, `before`, `after`, `replaceWith`.
- **Remove**: `el.remove()`.
- **Attribute**: `setAttribute`, `dataset.x`, `classList.add/toggle/remove`.
- **Content**: `textContent` (safe) vs `innerHTML` (XSS risk).
### 매 Observe
- `MutationObserver` — 매 subtree change.
- `IntersectionObserver` — viewport visibility.
- `ResizeObserver` — element size.
### 매 응용
1. Lightweight widget (no framework) — banner, modal, tooltip.
2. Server-rendered HTML enhancement (Hotwire, Astro islands).
3. Browser extension content script.
## 💻 패턴
### Element creation (template)
```html
<template id="card-tpl">
<article class="card">
<h3 class="title"></h3>
<p class="body"></p>
</article>
</template>
```
```javascript
function renderCard({ title, body }) {
const tpl = document.getElementById('card-tpl');
const node = tpl.content.cloneNode(true);
node.querySelector('.title').textContent = title;
node.querySelector('.body').textContent = body;
return node;
}
document.querySelector('#list').append(renderCard({ title: 'Hi', body: 'World' }));
```
### classList + dataset
```javascript
const btn = document.querySelector('#toggle');
btn.classList.toggle('active');
btn.dataset.count = (Number(btn.dataset.count ?? 0) + 1).toString();
// HTML: <button id="toggle" data-count="3">
```
### Event delegation
```javascript
document.addEventListener('click', (e) => {
const action = e.target.closest('[data-action]');
if (!action) return;
switch (action.dataset.action) {
case 'open': openModal(action.dataset.id); break;
case 'delete': remove(action.dataset.id); break;
}
});
```
### Safe insertion (avoid innerHTML)
```javascript
// 매 X — XSS
container.innerHTML = `<p>${userInput}</p>`;
// 매 O — textContent
const p = document.createElement('p');
p.textContent = userInput;
container.append(p);
// 매 trusted HTML 만 — Sanitizer API (2026 baseline)
container.setHTML(trustedString); // 의 native sanitize
```
### IntersectionObserver — lazy load
```javascript
const io = new IntersectionObserver((entries) => {
for (const e of entries) {
if (!e.isIntersecting) continue;
const img = e.target;
img.src = img.dataset.src;
io.unobserve(img);
}
});
document.querySelectorAll('img[data-src]').forEach((img) => io.observe(img));
```
### MutationObserver — react to subtree
```javascript
const mo = new MutationObserver((muts) => {
for (const m of muts) {
for (const n of m.addedNodes) {
if (n instanceof HTMLAnchorElement) enhanceLink(n);
}
}
});
mo.observe(document.body, { childList: true, subtree: true });
```
### Form serialization
```javascript
const form = document.querySelector('#login');
form.addEventListener('submit', (e) => {
e.preventDefault();
const data = Object.fromEntries(new FormData(form));
fetch('/login', { method: 'POST', body: JSON.stringify(data), headers: { 'Content-Type': 'application/json' } });
});
```
### Animation — Web Animations API
```javascript
el.animate(
[{ opacity: 0, transform: 'translateY(10px)' }, { opacity: 1, transform: 'none' }],
{ duration: 200, easing: 'ease-out', fill: 'forwards' },
);
```
### Batched DOM updates
```javascript
const frag = document.createDocumentFragment();
for (const item of items) frag.append(renderRow(item));
list.append(frag); // 매 single reflow
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Static + small interaction | Vanilla DOM |
| 100s of components | React / Solid / Svelte |
| Server HTML + enhancement | Hotwire / Astro |
| Lazy load images | IntersectionObserver |
| External widget injection | MutationObserver |
| Animation | Web Animations API |
**기본값**: querySelector + classList + textContent + delegation + Observer APIs.
## 🔗 Graph
- 부모: [[DOM]]
- 변형: [[DOM 요소 조작 및 타입 좁히기]] · [[Shadow_DOM]]
- 응용: [[Web_Components]] · [[Hotwire]]
- Adjacent: [[IntersectionObserver]] · [[MutationObserver]]
## 🤖 LLM 활용
**언제**: vanilla widget scaffold, Observer setup, jQuery → modern migration.
**언제 X**: 매 framework app — 매 framework primitive 의 사용.
## ❌ 안티패턴
- **`innerHTML` with user input**: 매 XSS — `textContent` 또는 Sanitizer.
- **Loop append in DOM**: 매 N reflows — DocumentFragment 의 사용.
- **No event delegation**: 1000 listener 의 memory + perf 비용.
- **document.write**: deprecated — 매 stream block.
- **Manual style mutation everywhere**: classList toggle + CSS 의 사용.
## 🧪 검증 / 중복
- Verified (MDN DOM, Web Animations, Observers, Sanitizer API spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — query/mutate/observe patterns + Sanitizer + delegation |
@@ -0,0 +1,140 @@
---
id: wiki-2026-0508-edge-bleeding
title: Edge Bleeding
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Texture Bleeding, Atlas Bleeding]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [graphics, texture, rendering]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: GLSL/HLSL
framework: WebGL/Three.js/Unity/Unreal
---
# Edge Bleeding
## 매 한 줄
> **"매 texture sampling 의 인접 texel이 unintended 하게 leak — atlas seam의 colored line으로 manifest."**. 매 mipmap downsample / bilinear interpolation 매 texel boundary를 cross 하면서 발생. 매 sprite atlas, texture array, lightmap에서 매 visible artifact.
## 매 핵심
### 매 원인
- **Bilinear filter**: 매 sample point 매 texel center 사이 → 인접 texel weighted.
- **Mipmap downsample**: 매 box filter 매 atlas neighbor를 average.
- **UV precision**: float precision 매 정확한 boundary 매 hit 못 함.
- **Anisotropic filtering**: 매 large footprint → 매 더 많은 neighbor sampling.
### 매 manifestation
- Sprite atlas: 매 sprite edge 매 인접 sprite color line.
- Tilemap: 매 tile seam 매 dark/bright line.
- Skybox cubemap: 매 face boundary 매 visible seam.
- Lightmap: 매 chart boundary 매 dark crack.
### 매 응용 (해결책)
1. **Padding (gutter)**: 매 sprite 사이 1-2px transparent / replicated edge.
2. **Half-texel UV inset**: UV 매 `(0.5/W, 0.5/H)` ~ `(1 - 0.5/W, 1 - 0.5/H)` 의 clamp.
3. **CLAMP_TO_EDGE**: wrap mode 매 repeat → clamp.
4. **Conservative UV**: 매 mesh UV 매 atlas region 의 inside 의 inset.
5. **Mipmap-aware padding**: 매 mip level 별 padding (1px → 2px → 4px).
## 💻 패턴
### Half-texel inset (GLSL)
```glsl
uniform vec2 atlasSize; // e.g. (2048, 2048)
uniform vec4 spriteRect; // x, y, w, h in pixels
vec2 sampleUV(vec2 localUV) {
vec2 halfTexel = 0.5 / atlasSize;
vec2 minUV = spriteRect.xy / atlasSize + halfTexel;
vec2 maxUV = (spriteRect.xy + spriteRect.zw) / atlasSize - halfTexel;
return mix(minUV, maxUV, localUV);
}
```
### Atlas packer with padding (TS)
```typescript
function packSprite(sprite: ImageData, padding = 2): PackedSprite {
const w = sprite.width + padding * 2;
const h = sprite.height + padding * 2;
const padded = new ImageData(w, h);
// edge replicate (not transparent) for bilinear safety
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const sx = clamp(x - padding, 0, sprite.width - 1);
const sy = clamp(y - padding, 0, sprite.height - 1);
copyPixel(sprite, sx, sy, padded, x, y);
}
}
return { data: padded, padding };
}
```
### Three.js NearestFilter (no bleed, no smooth)
```javascript
texture.minFilter = THREE.NearestFilter;
texture.magFilter = THREE.NearestFilter;
texture.generateMipmaps = false;
texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
```
### Mipmap-aware padding count
```typescript
function paddingForMipLevels(levels: number): number {
return Math.pow(2, levels - 1); // 4 levels → 8px padding
}
```
### Conservative cubemap seam fix (HLSL)
```hlsl
float3 SampleCubeSeamless(TextureCube tex, SamplerState s, float3 dir, float roughness) {
float mip = roughness * 8.0;
float texSize = 512.0 / pow(2, mip);
float scale = 1.0 - 1.0 / texSize;
return tex.SampleLevel(s, dir * scale, mip).rgb;
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Pixel art sprite | NearestFilter + padding 1px |
| 3D texture atlas (smooth) | Half-texel inset + padding (2 * mip levels) |
| Tilemap | Padding + clamp + per-tile texture array (best) |
| Cubemap | GL_TEXTURE_CUBE_MAP_SEAMLESS (GL 3.2+) |
| Lightmap | Chart padding 4px + dilation |
**기본값**: 매 padding 2px + half-texel inset, 매 mipmap 매 사용 시 2 * (mip levels) px.
## 🔗 Graph
- 변형: [[Atlas Bleeding]]
- 응용: [[Texture Array]]
- Adjacent: [[Mipmap]]
## 🤖 LLM 활용
**언제**: sprite atlas / tilemap / lightmap 매 visible seam, 매 mipmap 매 사용한 atlas, 매 cubemap face 경계 artifact.
**언제 X**: single texture (no atlas), 매 NEAREST filter 매 사용 + no mipmap, fully procedural texture.
## ❌ 안티패턴
- **Transparent padding alone**: 매 bilinear가 transparent와 mix → 매 dark fringe.
- **Padding 너무 small**: mip level 3+ 매 도달 시 여전히 leak.
- **Repeat wrap on atlas**: 매 opposite edge 매 sample → 완전한 wrong color.
- **UV exactly at texel boundary**: 매 float precision 의해 random side 매 sample.
- **Generate mipmap on packed atlas**: 매 mip downsample 매 인접 sprite를 average → mid-mip levels artifact.
## 🧪 검증 / 중복
- Verified (Real-Time Rendering 4ed, Unity / Unreal docs, OpenGL spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Edge bleeding 원인 / padding 전략 / mip-aware solution |
@@ -0,0 +1,170 @@
---
id: wiki-2026-0508-effect-ts
title: Effect TS
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Effect, Effect-TS, effect.ts]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, functional-programming, effect, error-handling]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Effect
---
# Effect TS
## 매 한 줄
> **"매 TypeScript 의 functional effect system — error · concurrency · resource 매 type-level encoding"**. 매 ZIO (Scala) inspired library 의 TS port. 2026 시점 v3.x stable, Discord · Vercel · Stripe internal services 가 production 채택.
## 매 핵심
### 매 Effect<A, E, R>
- `A`: success value type
- `E`: error type (typed errors, no exceptions)
- `R`: required services (DI context)
- 매 lazy description — execution은 `Effect.runPromise` 시점.
### 매 핵심 primitives
- `Effect.succeed` / `Effect.fail` / `Effect.sync` / `Effect.tryPromise`
- `Effect.gen` (generator-based do-notation)
- `Effect.all` (parallel), `Effect.forEach` (concurrency control)
- `Layer` (DI composition), `Context.Tag` (service identity)
### 매 응용
1. API gateway error contracts (`HttpClient` typed errors).
2. Database transactional pipelines (`Effect.scoped` + `Layer`).
3. Streaming ETL (`Stream` module).
## 💻 패턴
### Effect.gen do-notation
```ts
import { Effect } from "effect"
const getUser = (id: string) =>
Effect.gen(function* () {
const db = yield* DatabaseService
const user = yield* db.findUser(id)
if (!user) return yield* Effect.fail(new UserNotFound({ id }))
return user
})
```
### Typed errors (Data.TaggedError)
```ts
import { Data } from "effect"
class UserNotFound extends Data.TaggedError("UserNotFound")<{
id: string
}> {}
class DbConnectionError extends Data.TaggedError("DbConnectionError")<{
cause: unknown
}> {}
```
### Layer composition
```ts
import { Effect, Layer, Context } from "effect"
class DatabaseService extends Context.Tag("DatabaseService")<
DatabaseService,
{ findUser: (id: string) => Effect.Effect<User | null, DbConnectionError> }
>() {}
const DatabaseLive = Layer.succeed(DatabaseService, {
findUser: (id) =>
Effect.tryPromise({
try: () => pgClient.query("SELECT * FROM users WHERE id=$1", [id]),
catch: (cause) => new DbConnectionError({ cause }),
}),
})
```
### Concurrent execution
```ts
const fetchAll = Effect.forEach(
["a", "b", "c"],
(id) => getUser(id),
{ concurrency: 5 }
)
```
### Retry + timeout
```ts
import { Schedule, Duration } from "effect"
const robust = getUser("123").pipe(
Effect.retry(Schedule.exponential(Duration.millis(100)).pipe(
Schedule.compose(Schedule.recurs(3))
)),
Effect.timeout(Duration.seconds(5))
)
```
### Resource scoping
```ts
const program = Effect.scoped(
Effect.gen(function* () {
const file = yield* Effect.acquireRelease(
openFile("data.txt"),
(f) => closeFile(f)
)
return yield* readContent(file)
})
)
```
### Schema validation
```ts
import { Schema } from "effect"
const User = Schema.Struct({
id: Schema.String,
age: Schema.Number.pipe(Schema.int(), Schema.nonNegative()),
})
const parse = Schema.decodeUnknown(User)
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 단순 CRUD app | plain async/await + zod |
| 복잡한 error taxonomy | Effect (typed errors) |
| Concurrency-heavy pipeline | Effect (Schedule + Stream) |
| Team unfamiliar with FP | neverthrow / fp-ts 시작 |
**기본값**: greenfield TS backend with complex error contracts → Effect 채택. 매 learning curve 높음 — team buy-in 매 우선.
## 🔗 Graph
- 부모: [[Functional Programming]] · [[TypeScript 타입 시스템 및 인터페이스 설계]]
- 변형: [[Result Type]]
- 응용: [[견고한 도메인 모델 및 API 계약 설계]] · [[API 응답 및 에러 핸들링 아키텍처]]
- Adjacent: [[Zod 런타임 유효성 검사 통합]] · [[ts-brand]]
## 🤖 LLM 활용
**언제**: TS backend with strict error typing, dependency injection at type level, retry/circuit-breaker policies.
**언제 X**: 매 simple script · prototype · React component logic — overhead 매 큼.
## ❌ 안티패턴
- **Effect.runSync everywhere**: 매 sync execution 강제 — async benefit 상실.
- **Fail with strings**: typed `TaggedError` 의 사용해야 매 discriminated handling 가능.
- **Layer.merge spaghetti**: 매 dependency graph 의 명시적 organize.
## 🧪 검증 / 중복
- Verified (effect.website official docs · Effect 3.x release notes 2025).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Effect 3.x patterns, Layer/Schema/typed errors |
@@ -0,0 +1,179 @@
---
id: wiki-2026-0508-electron
title: Electron
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Electron Framework, Atom Shell]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [desktop, javascript, chromium, nodejs]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript/JavaScript
framework: Electron 33+
---
# Electron
## 매 한 줄
> **"매 Chromium + Node.js를 묶어 web tech 으로 desktop app 을 build"**. GitHub 이 Atom editor 용으로 만든 framework 가 VS Code, Slack, Discord, Figma desktop, 1Password 의 backbone 이 되었음. 2026 현재 Electron 33+ 가 process model 강화 (utility process), V8 sandbox, ASAR integrity 검사 의 기본화.
## 매 핵심
### 매 process model
- **Main process**: Node.js runtime, app lifecycle, native API (file, dialog, tray) 의 owner. 매 1 개 instance.
- **Renderer process**: Chromium tab 마다 1 개. BrowserWindow content. Sandbox 기본 ON (Electron 20+).
- **Preload script**: Renderer 의 isolated world 에서 실행, `contextBridge` 로 main 과 안전 bridge.
- **Utility process**: 매 v22+ 추가. Heavy CPU/IO offload (image decode, ffmpeg).
### 매 IPC 패턴
- `ipcRenderer.invoke``ipcMain.handle` (Promise-based, 권장).
- `ipcRenderer.send``ipcMain.on` (fire-and-forget).
- `webContents.send``ipcRenderer.on` (main → renderer push).
-`contextIsolation: true` + `nodeIntegration: false` 의 mandatory.
### 매 응용
1. **Editor**: VS Code, Atom, Obsidian.
2. **Communication**: Slack, Discord, Microsoft Teams.
3. **Design**: Figma desktop, Notion.
4. **Crypto/Wallet**: 1Password, Exodus.
## 💻 패턴
### Secure preload bridge
```typescript
// preload.ts
import { contextBridge, ipcRenderer } from 'electron'
contextBridge.exposeInMainWorld('api', {
readFile: (path: string) => ipcRenderer.invoke('fs:read', path),
onUpdate: (cb: (v: string) => void) => {
const listener = (_: unknown, v: string) => cb(v)
ipcRenderer.on('app:update', listener)
return () => ipcRenderer.removeListener('app:update', listener)
},
})
```
### Main IPC handler with validation
```typescript
// main.ts
import { ipcMain, app } from 'electron'
import { promises as fs } from 'node:fs'
import path from 'node:path'
ipcMain.handle('fs:read', async (_event, requested: string) => {
const userData = app.getPath('userData')
const resolved = path.resolve(userData, requested)
if (!resolved.startsWith(userData)) throw new Error('path traversal')
return await fs.readFile(resolved, 'utf-8')
})
```
### BrowserWindow secure defaults
```typescript
import { BrowserWindow } from 'electron'
import path from 'node:path'
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
sandbox: true,
webSecurity: true,
},
})
```
### Auto-updater (electron-updater)
```typescript
import { autoUpdater } from 'electron-updater'
autoUpdater.checkForUpdatesAndNotify()
autoUpdater.on('update-downloaded', () => autoUpdater.quitAndInstall())
```
### Utility process offload
```typescript
import { utilityProcess, MessageChannelMain } from 'electron'
const { port1, port2 } = new MessageChannelMain()
const child = utilityProcess.fork(path.join(__dirname, 'worker.js'))
child.postMessage({ task: 'transcode' }, [port2])
port1.on('message', (msg) => console.log('result', msg))
```
### Code signing build (electron-builder)
```json
{
"build": {
"appId": "com.example.app",
"mac": { "hardenedRuntime": true, "gatekeeperAssess": false, "notarize": true },
"win": { "signingHashAlgorithms": ["sha256"] },
"asar": true
}
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Cross-platform desktop, web team | Electron |
| Bundle size critical (<50MB) | Tauri (Rust) 고려 |
| Native feel mandatory | Native (Swift/Kotlin) |
| Existing web app → wrap | Electron |
| Mobile target 도 필요 | React Native / Flutter |
**기본값**: 매 Electron 33+ + contextIsolation + electron-builder + auto-updater.
## 🔗 Graph
- 부모: [[Chromium]] · [[Nodejs_and_Backend_Optimization|Nodejs]]
- 변형: [[Tauri]]
- Adjacent: [[Chrome DevTools(크롬 개발자 도구)]] · [[V8 엔진 힙 아키텍처]]
## 🤖 LLM 활용
**언제**: web stack 재사용, 빠른 cross-platform delivery, rich web-based UI 필요.
**언제 X**: 매 100MB+ binary 가 unacceptable, 매 deep OS integration (kernel ext, system tray 만 의 limit), battery-critical mobile.
## ❌ 안티패턴
- **nodeIntegration: true with remote content**: 매 RCE risk. 매 contextIsolation 강제.
- **`require('electron').remote`**: deprecated, removed v14+. `@electron/remote` 도 안티 — IPC handle 로 교체.
- **불특정 origin loadURL**: 매 untrusted web 을 BrowserWindow 에 load 하면 sandbox escape 위험.
- **ASAR 만 의 protection**: ASAR 는 압축 일 뿐. Source 보호 의 X — 매 native module / 서버 side 로 logic 이동.
## 🧪 검증 / 중복
- Verified (electronjs.org docs, Electron 33 release notes 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Electron 33 process model + secure IPC patterns |
## 🛠️ 적용 사례 (Applied in summary)
<!-- CODE-GROUNDING:START -->
### 🔎 코드베이스 근거 (자동 추출 — E:\Wiki 레포)
**실제 구현/사용 위치:**
- `photoai/electron.vite.config.ts:2` — import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
- `photoai/src/shared/types.ts:485` — /** 드롭된 File의 로컬 절대경로 반환(Electron webUtils). 경로가 없으면 빈 문자열. */
- `photoai/src/preload/inference.ts:1` — import { contextBridge, ipcRenderer } from 'electron'
- `photoai/src/preload/index.ts:1` — import { contextBridge, ipcRenderer, webUtils } from 'electron'
- `photoai/src/main/fsExplorer.ts:4` — import { shell } from 'electron'
- `photoai/src/main/embedder.ts:1` — import { BrowserWindow } from 'electron'
**관련 커밋:**
- `photoai 3e73967 darktable-inspired reskin + metadata/collections, map, easy mode, select/export`
- `photoai 8a8c102 Initial commit: AI Photo Organizer (Electron + face-api)`
_자동 생성: code_grounding.mjs · 재실행 시 갱신됨_
<!-- CODE-GROUNDING:END -->
@@ -0,0 +1,204 @@
---
id: wiki-2026-0508-escape-hatch-탈출구
title: Escape Hatch (탈출구)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [React escape hatch, useRef escape hatch, useEffect escape hatch]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [react, hooks, useref, useeffect, framework-design]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: React
---
# Escape Hatch (탈출구)
## 매 한 줄
> **"매 framework 가 model 외의 reality 의 reach 매 escape hatch"**. React 의 escape hatch — useRef, useEffect, flushSync, ref callback 의 declarative model 외의 imperative DOM/non-React system 의 bridge. 매 2026 React 19 (Activity API, useOptimistic) 의 도입 매 escape hatch 의 사용 빈도 의 감소 but 매 여전히 essential.
## 매 핵심
### 매 왜 필요
- React model: declarative — UI = f(state).
- 매 reality 매 imperative — DOM focus, video play, third-party (D3, Chart.js, Three.js), browser API (IntersectionObserver).
- 매 escape hatch 의 controlled bridge 의 제공.
### 매 React 의 4 hatch
- **useRef**: 매 mutable container 매 re-render trigger 없음.
- **useEffect**: 매 commit 후 의 side-effect — 매 subscription, manual DOM, external system.
- **flushSync**: 매 sync update 의 force — 매 layout measurement before paint.
- **ref callback**: 매 mount/unmount lifecycle 의 ref level access.
### 매 응용
1. Third-party library integration (D3, Three.js).
2. Imperative DOM (focus, scroll, select).
3. Subscription (WebSocket, EventSource).
## 💻 패턴
### useRef Mutable Value
```tsx
function Stopwatch() {
const intervalRef = useRef<number | null>(null)
const [time, setTime] = useState(0)
const start = () => {
if (intervalRef.current) return
intervalRef.current = window.setInterval(() => setTime((t) => t + 1), 1000)
}
const stop = () => {
if (intervalRef.current) clearInterval(intervalRef.current)
intervalRef.current = null
}
return <button onClick={start}>{time}</button>
}
```
### useRef DOM Reference
```tsx
function AutoFocus() {
const inputRef = useRef<HTMLInputElement>(null)
useEffect(() => {
inputRef.current?.focus()
}, [])
return <input ref={inputRef} />
}
```
### useEffect External System
```tsx
function ChatRoom({ roomId }: { roomId: string }) {
useEffect(() => {
const conn = createConnection(roomId)
conn.connect()
return () => conn.disconnect() // 매 cleanup essential
}, [roomId])
return <h1>Welcome to {roomId}</h1>
}
```
### Third-party Integration (Three.js)
```tsx
function ThreeScene() {
const containerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(800, 600)
containerRef.current?.appendChild(renderer.domElement)
let raf: number
const animate = () => {
raf = requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
return () => {
cancelAnimationFrame(raf)
renderer.dispose()
containerRef.current?.removeChild(renderer.domElement)
}
}, [])
return <div ref={containerRef} />
}
```
### flushSync (force sync)
```tsx
import { flushSync } from "react-dom"
function ScrollToBottom() {
const [items, setItems] = useState<string[]>([])
const listRef = useRef<HTMLUListElement>(null)
const addItem = (text: string) => {
flushSync(() => {
setItems((prev) => [...prev, text])
})
// 매 flushSync 후 매 DOM 매 updated 의 guaranteed
listRef.current?.scrollTo(0, listRef.current.scrollHeight)
}
return (/* ... */)
}
```
### Ref Callback (mount/unmount)
```tsx
function ObservedItem({ onVisible }: { onVisible: () => void }) {
const refCallback = useCallback((node: HTMLDivElement | null) => {
if (!node) return
const obs = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) onVisible()
})
obs.observe(node)
return () => obs.disconnect() // React 19+ cleanup
}, [onVisible])
return <div ref={refCallback}>Observed</div>
}
```
### useImperativeHandle (parent 의 controlled API)
```tsx
type ModalHandle = { open: () => void; close: () => void }
const Modal = forwardRef<ModalHandle>((_, ref) => {
const [open, setOpen] = useState(false)
useImperativeHandle(ref, () => ({
open: () => setOpen(true),
close: () => setOpen(false),
}), [])
return open ? <div>Modal</div> : null
})
function App() {
const modalRef = useRef<ModalHandle>(null)
return <button onClick={() => modalRef.current?.open()}>Open</button>
}
```
## 매 결정 기준
| 상황 | Hatch |
|---|---|
| Mutable value 매 no re-render | useRef |
| DOM focus/scroll | useRef + useEffect |
| External lib (D3/Three.js) | useEffect |
| Sync DOM measurement | flushSync |
| Mount/unmount lifecycle | ref callback |
| Parent imperative API | useImperativeHandle |
**기본값**: 매 declarative 매 first — 매 hatch 매 last resort.
## 🔗 Graph
- 부모: [[React]]
- 변형: [[Vue Composition API]] · [[Solid Signals]]
- 응용: [[IntersectionObserver]]
- Adjacent: [[useEffect]] · [[useRef]]
## 🤖 LLM 활용
**언제**: 매 third-party imperative library 의 React 의 integration, DOM 의 manual control.
**언제 X**: 매 pure UI state — 매 useState/useReducer 의 사용.
## ❌ 안티패턴
- **useRef 매 derived state**: 매 useState 또는 useMemo 매 사용.
- **useEffect 매 data fetch (cascading)**: 매 React Query / RSC 매 사용.
- **Stale ref read in render**: 매 ref.current 의 render 의 read 매 X.
- **Cleanup 의 omit**: 매 memory leak — 매 return 매 always.
## 🧪 검증 / 중복
- Verified (React 공식 docs "Escape Hatches" chapter, React 19 — 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — React 19 escape hatch 4종 + 패턴 작성 |
@@ -0,0 +1,121 @@
---
id: wiki-2026-0508-flame-chart
title: Flame Chart
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Flame Graph, 플레임 차트]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [profiling, performance, devtools, visualization]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript
framework: Chrome DevTools
---
# Flame Chart
## 매 한 줄
> **"매 시간축 stack frame 의 visual profile — width=duration, depth=call stack"**. Brendan Gregg (2013) 의 flame graph 매 origin. 2026 시점 Chrome DevTools Performance panel · Node `--prof` · Linux `perf` · Speedscope 매 standard tooling.
## 매 핵심
### 매 Flame Chart vs Flame Graph
- **Flame Chart**: x축 = 매 wall-clock time (left→right chronological). DevTools default.
- **Flame Graph**: x축 = 매 aggregated time (alphabetical), 매 hot path 발견.
### 매 reading rules
- 매 wide bar = 매 long-running function.
- 매 tall stack = 매 deep call chain (recursion · over-abstraction signal).
- 매 plateau = 매 single function dominate.
### 매 응용
1. JS main-thread bottleneck 식별.
2. React render 의 expensive component 추적.
3. Backend RPC handler latency 분해.
## 💻 패턴
### Chrome DevTools 캡처
```js
// 1. DevTools → Performance → Record
// 2. Reproduce slow interaction
// 3. Stop → bottom-up / call tree / flame chart 탭
// Programmatic mark
performance.mark("render-start")
expensiveRender()
performance.mark("render-end")
performance.measure("render", "render-start", "render-end")
```
### Node.js CPU profile
```bash
node --cpu-prof --cpu-prof-dir=./profiles app.js
# .cpuprofile 의 Chrome DevTools "Performance" 탭에 drag-drop
```
### 0x flame graph 생성
```bash
npx 0x -o server.js
# HTML 매 자동 open — interactive flame graph
```
### React Profiler API
```tsx
import { Profiler } from "react"
function onRender(id, phase, actualDuration) {
if (actualDuration > 16) console.warn(`slow ${id}: ${actualDuration}ms`)
}
<Profiler id="UserList" onRender={onRender}>
<UserList />
</Profiler>
```
### Speedscope (universal viewer)
```bash
# Node, Chrome, py-spy, perf 매 모두 import
npx speedscope profile.cpuprofile
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Browser frontend lag | Chrome DevTools Performance |
| Node server CPU spike | `--cpu-prof` + DevTools |
| Production hot-path discovery | Flame **graph** (aggregated) |
| Specific user interaction | Flame **chart** (chronological) |
**기본값**: Chrome DevTools Performance panel — 매 60% case cover.
## 🔗 Graph
- 부모: [[Performance_Profiling_and_Memory|Performance Profiling]] · [[Chrome DevTools(크롬 개발자 도구)]]
- 변형: [[할당 타임라인(Allocation Timeline)]]
- 응용: [[Nodejs 성능 디버깅]] · [[SPA 라우트 전환 성능 최적화]]
- Adjacent: [[Core Web Vitals Optimization (INP, LCP, CLS)|Cumulative Layout Shift (CLS)]] · [[Google Lighthouse]]
## 🤖 LLM 활용
**언제**: 매 latency / jank / unknown bottleneck 발견 → flame chart 의 first tool.
**언제 X**: 매 memory leak (heap snapshot 사용) · 매 network waterfall (Network panel).
## ❌ 안티패턴
- **Optimize the wide-but-shallow bar**: 매 actually unimportant 일 수 있음 — call tree로 cross-check.
- **Sampling rate 신뢰**: 매 short bursts (<1ms) 의 missed — `performance.mark` precise.
- **Production 에서 always-on profiling**: 매 overhead — sampling profiler (e.g. `pprof`) 만 OK.
## 🧪 검증 / 중복
- Verified (Brendan Gregg flame graph paper · Chrome DevTools docs 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — DevTools/0x/Speedscope tooling 매 설명 |
@@ -0,0 +1,154 @@
---
id: wiki-2026-0508-fuzzing
title: Fuzzing
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Fuzz Testing, Coverage-Guided Fuzzing]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [security, testing, dast]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: C/Rust/Go
framework: AFL++/libFuzzer/cargo-fuzz
---
# Fuzzing
## 매 한 줄
> **"매 random/mutated input 으로 crash, hang, UB 의 hunt"**. 매 1988 Miller (Wisconsin) 의 random input shell experiment 가 origin. 2026 현재 매 coverage-guided (AFL++, libFuzzer, Honggfuzz), structure-aware (libprotobuf-mutator), grammar-based (Nautilus), LLM-augmented (OSS-Fuzz Gen) 가 mainstream. Google OSS-Fuzz 가 100K+ bug 발견, Chrome/Linux kernel/OpenSSL 의 routine workflow.
## 매 핵심
### 매 fuzzing categories
- **Black-box (dumb)**: random input, no instrumentation. 매 zzuf, radamsa.
- **Coverage-guided (grey-box)**: input 의 mutation + branch coverage feedback. 매 AFL++, libFuzzer, Honggfuzz.
- **White-box (concolic)**: symbolic execution + solver. 매 KLEE, SAGE.
- **Structure-aware**: protobuf, JSON 의 grammar 의 valid input. 매 libprotobuf-mutator, FuzzGrammar.
- **Differential**: 매 동일 input 을 두 implementation 에 → divergence 의 bug.
### 매 sanitizers
- ASan (heap/stack OOB, UAF), UBSan (UB), MSan (uninit read), TSan (data race), LSan (leak).
- 매 fuzzing 의 corpus 는 sanitizer 와 함께 build 의 mandatory.
### 매 응용
1. Memory-safety bug discovery (C/C++ codebases).
2. Parser hardening (image, video, network protocols).
3. Browser engine (V8 fuzzilli, JSC fuzzer).
4. Crypto library (OpenSSL, BoringSSL via OSS-Fuzz).
## 💻 패턴
### libFuzzer (C++)
```cpp
// fuzz_target.cc — clang -fsanitize=fuzzer,address fuzz_target.cc parser.cc
#include <stdint.h>
#include <stddef.h>
#include "parser.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size < 4) return 0;
Parser p;
p.Parse(reinterpret_cast<const char*>(data), size); // ASan catches OOB/UAF
return 0;
}
```
### cargo-fuzz (Rust)
```rust
// fuzz/fuzz_targets/parse.rs
#![no_main]
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
if let Ok(s) = std::str::from_utf8(data) {
let _ = mycrate::parse(s); // panics 는 fuzz crash 로 catch
}
});
```
```bash
cargo fuzz run parse -- -max_total_time=600
```
### Go native fuzzing (1.18+)
```go
func FuzzParseURL(f *testing.F) {
f.Add("http://example.com")
f.Fuzz(func(t *testing.T, s string) {
u, err := url.Parse(s)
if err == nil && u.String() != s && url.QueryEscape(u.String()) == "" {
t.Errorf("roundtrip mismatch: %q", s)
}
})
}
```
```bash
go test -fuzz=FuzzParseURL -fuzztime=10m
```
### AFL++ (compile-time instrumentation)
```bash
CC=afl-clang-fast CXX=afl-clang-fast++ ./configure
make -j8
mkdir in; echo "seed" > in/0
afl-fuzz -i in -o out -- ./target @@
```
### Structure-aware (libprotobuf-mutator)
```cpp
DEFINE_PROTO_FUZZER(const my::Message& msg) {
HandleMessage(msg); // valid proto guaranteed → deeper coverage
}
```
### OSS-Fuzz integration
```dockerfile
FROM gcr.io/oss-fuzz-base/base-builder
RUN apt-get install -y libssl-dev
COPY . $SRC/myproject
COPY build.sh $SRC/
WORKDIR $SRC/myproject
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| C/C++ memory bug hunt | libFuzzer + ASan/UBSan |
| Rust panic / logic bug | cargo-fuzz |
| Network protocol parser | AFL++ + structure-aware mutator |
| Two implementations comparison | Differential fuzzing |
| Continuous (open-source) | OSS-Fuzz |
| Grammar-rich (JS, SQL) | Grammar-based (Nautilus, fuzzilli) |
**기본값**: 매 coverage-guided (libFuzzer/AFL++) + ASan + corpus minimization + CI 에 5min smoke.
## 🔗 Graph
- 부모: [[DAST (동적 애플리케이션 보안 테스트)]]
- 변형: [[SCA (소프트웨어 구성 분석)]]
- 응용: [[OSS-Fuzz]] · [[V8 엔진 힙 아키텍처]]
- Adjacent: [[Property-Based Testing]]
## 🤖 LLM 활용
**언제**: 매 untrusted input 의 parser, codec, deserializer 가 있는 경우. 매 security-critical library 의 release 전 mandatory.
**언제 X**: pure functional code 의 deterministic 한 input space (property-based testing 이 더 적절). 매 GUI / network state-heavy code.
## ❌ 안티패턴
- **Sanitizer 없이 fuzz**: 매 silent corruption 을 miss. 매 ASan 의 mandatory.
- **Seed corpus 없음**: 매 coverage 의 plateau 가 빠름. 매 valid sample 10-100 개 의 seed.
- **CI 에 30s 만 fuzz**: 매 너무 짧음. 매 minimum 10min, ideal continuous (OSS-Fuzz pattern).
- **Crash 만 의 focus**: 매 hang, OOM, slow input 도 bug. 매 timeout / rss_limit 설정.
## 🧪 검증 / 중복
- Verified (Miller 1990 "Empirical Study of Reliability of UNIX Utilities"; AFL++ docs; OSS-Fuzz reports).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — coverage-guided + sanitizers + OSS-Fuzz |
@@ -0,0 +1,172 @@
---
id: wiki-2026-0508-gc-root
title: GC Root
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Garbage Collection Root, GC 루트, Root Set]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [gc, jvm, memory, runtime]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Java/Kotlin
framework: JVM/HotSpot/ZGC
---
# GC Root
## 매 한 줄
> **"매 도달 가능성(reachability) 의 출발점"**. GC Root 는 garbage collector 가 live object 를 판별하기 위해 traversal 을 시작하는 reference set. 매 root 에서 도달 불가능한 object 는 collectible 로 marking 된다. JVM, .NET CLR, V8, Go runtime 모두 같은 개념을 공유한다.
## 매 핵심
### 매 GC Root 종류 (HotSpot 기준)
- **Stack reference**: 매 thread 의 local variable / parameter / operand stack.
- **Static field**: 매 loaded class 의 static reference.
- **JNI local/global**: 매 native code 가 hold 한 reference.
- **Active thread**: 매 살아있는 `Thread` object 자체.
- **Class metadata**: 매 ClassLoader, Class object (Metaspace).
- **Synchronization monitor**: 매 `synchronized` 로 lock 된 object.
- **Weak/Soft/Phantom 제외**: 매 reachability 약한 reference 는 root 가 아님.
### 매 Reachability tier
1. **Strongly reachable**: root 에서 strong ref 만으로 도달 → never collected.
2. **Softly reachable**: SoftReference 로만 도달 → 매 memory pressure 시 collect.
3. **Weakly reachable**: WeakReference 만 → 매 next GC cycle 에 collect.
4. **Phantom reachable**: PhantomReference → enqueue 후 cleaning.
5. **Unreachable**: → collectible.
### 매 응용
1. **Memory leak 진단** (heap dump → root path 추적).
2. **Escape analysis** (root 도달 안 되는 local → stack alloc).
3. **Concurrent GC 의 root scanning** (ZGC, Shenandoah, G1 의 phase 1).
## 💻 패턴
### 1. Heap dump 에서 root path 찾기 (Eclipse MAT / jhat)
```bash
# JVM heap dump 생성
jcmd <pid> GC.heap_dump /tmp/heap.hprof
# Eclipse MAT CLI 로 leak suspects 분석
./MemoryAnalyzer -consoleLog -application org.eclipse.mat.api.parse \
/tmp/heap.hprof org.eclipse.mat.api:suspects
```
### 2. JFR 로 GC root 통계 수집 (JDK 21+)
```bash
java -XX:StartFlightRecording=duration=60s,filename=app.jfr,settings=profile \
-XX:+UseZGC -Xmx4g -jar app.jar
jfr print --events GarbageCollection,GCReferenceStatistics app.jfr
```
### 3. WeakReference 로 root 진입 회피
```java
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
// Cache 가 GC root 가 되어 leak 발생하는 anti-pattern 회피
public class Cache<K, V> {
private final WeakHashMap<K, V> map = new WeakHashMap<>();
public void put(K key, V value) { map.put(key, value); }
public V get(K key) { return map.get(key); }
// key 가 외부에서 strong ref 사라지면 entry 자동 제거
}
```
### 4. ThreadLocal leak 회피 (매 typical root leak)
```java
public class RequestContext {
private static final ThreadLocal<UserSession> CTX = new ThreadLocal<>();
public static void set(UserSession s) { CTX.set(s); }
public static UserSession get() { return CTX.get(); }
// 매 critical: thread pool 환경에서 반드시 remove() 호출
public static void clear() { CTX.remove(); }
}
// Servlet filter 에서:
try {
RequestContext.set(session);
chain.doFilter(req, res);
} finally {
RequestContext.clear(); // 매 root reference 끊기
}
```
### 5. JNI global ref 정리 (native code 가 GC root)
```c
// JNI: global ref 는 명시적으로 free 해야 함
jobject globalRef = (*env)->NewGlobalRef(env, localObj);
// ... 사용 ...
(*env)->DeleteGlobalRef(env, globalRef); // 매 빠뜨리면 영구 leak
```
### 6. Static field 로 의도된 long-lived root
```kotlin
object AppMetrics { // 매 Kotlin object → static singleton → GC root
private val counter = AtomicLong(0)
fun increment() = counter.incrementAndGet()
fun snapshot() = counter.get()
}
```
### 7. ZGC / Shenandoah concurrent root scanning 활성화
```bash
# JDK 21+: ZGC generational
java -XX:+UseZGC -XX:+ZGenerational \
-XX:SoftMaxHeapSize=8g -Xmx16g -jar app.jar
# Shenandoah
java -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -jar app.jar
```
### 8. Async profiler 로 allocation root 찾기
```bash
./profiler.sh -e alloc -d 60 -f alloc.html <pid>
# 매 flamegraph 에서 root → leaking site path 시각화
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Long-lived cache | `WeakHashMap` / Caffeine `weakKeys()` |
| Per-request state in pool | `ThreadLocal` + `try/finally remove()` |
| Native handle wrapping | `Cleaner` (java.lang.ref.Cleaner, JDK 9+) |
| Listener registration | `WeakReference` 로 listener wrap |
| 매 short-lived burst alloc | 매 그냥 strong ref + young gen 의존 |
**기본값**: 매 strong ref + escape analysis 신뢰. WeakReference 는 매 진짜 leak 패턴 (cache, listener, ThreadLocal in pool) 에만.
## 🔗 Graph
- 부모: [[Garbage Collection]]
- 응용: [[Memory Leak Detection]]
## 🤖 LLM 활용
**언제**: heap dump 의 leak suspect 해석, root path 의 의미 설명, ThreadLocal/static leak pattern detection.
**언제 X**: 매 production 의 실제 GC tuning (real profiling 데이터 없이 추측 X).
## ❌ 안티패턴
- **Static collection 무한 grow**: `static List` 에 매 add 만 하고 remove 안 함 → 영구 root.
- **ThreadLocal in pool no remove**: 매 thread 재사용 시 이전 request data 가 root 로 남음.
- **JNI GlobalRef leak**: native 에서 `DeleteGlobalRef` 누락.
- **Anonymous inner class capture**: `new Runnable() {}` 가 outer `this` 를 capture → outer 가 root 에 매달림.
- **Listener 등록 후 unregister 안 함**: 매 EventBus, Observer 패턴의 classic leak.
## 🧪 검증 / 중복
- Verified (OpenJDK HotSpot source, JEP 376/439, Eclipse MAT docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — GC root taxonomy + leak 진단 패턴 |
@@ -0,0 +1,160 @@
---
id: wiki-2026-0508-google-lighthouse
title: Google Lighthouse
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Lighthouse, Web Vitals Audit]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [performance, web-vitals, audit, ci]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript
framework: Lighthouse 12+ / lighthouse-ci
---
# Google Lighthouse
## 매 한 줄
> **"매 web page 의 performance, accessibility, best-practices, SEO, PWA 를 자동 audit"**. Chrome DevTools 내장, CLI, Node API, lighthouse-ci 의 form. 2026 현재 v12+ 가 INP (Interaction to Next Paint) 의 primary metric, LCP/CLS/INP 의 Core Web Vitals 와 align. 매 PR 마다 budget 검증 의 standard practice.
## 매 핵심
### 매 5 categories
- **Performance**: LCP, INP, CLS, TBT, FCP, Speed Index → 0-100 score.
- **Accessibility**: axe-core 기반 a11y 검사.
- **Best Practices**: HTTPS, secure headers, deprecated API.
- **SEO**: meta tags, mobile viewport, structured data.
- **PWA** (deprecated 2024 후 separate plugin).
### 매 Performance 의 weight (v12)
- LCP 25%, TBT 30%, CLS 25%, FCP 10%, SI 10%.
- INP 의 field metric 만 — lab 에서 measure X (Total Blocking Time 으로 proxy).
### 매 응용
1. Local audit (DevTools).
2. CI gate (lighthouse-ci, budgets.json).
3. Field monitoring 보조 (CrUX + RUM 와 결합).
4. PageSpeed Insights backend.
## 💻 패턴
### CLI run
```bash
npm i -g lighthouse
lighthouse https://example.com --output=html --output=json \
--output-path=./report --chrome-flags="--headless"
```
### Node programmatic
```javascript
import lighthouse from 'lighthouse'
import * as chromeLauncher from 'chrome-launcher'
const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] })
const result = await lighthouse('https://example.com', {
port: chrome.port,
output: 'json',
onlyCategories: ['performance'],
})
console.log(result.lhr.categories.performance.score)
await chrome.kill()
```
### Lighthouse CI in GitHub Actions
```yaml
# .github/workflows/lhci.yml
name: lhci
on: [pull_request]
jobs:
lhci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci && npm run build
- run: npm i -g @lhci/cli@0.14.x
- run: lhci autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
```
### lighthouserc.js with budgets
```javascript
module.exports = {
ci: {
collect: {
url: ['http://localhost:3000/', 'http://localhost:3000/about'],
numberOfRuns: 3,
startServerCommand: 'npm start',
},
assert: {
assertions: {
'categories:performance': ['error', { minScore: 0.9 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
'total-blocking-time': ['warn', { maxNumericValue: 200 }],
},
},
upload: { target: 'temporary-public-storage' },
},
}
```
### User flow (multi-step)
```javascript
import { startFlow } from 'lighthouse'
import puppeteer from 'puppeteer'
const browser = await puppeteer.launch()
const page = await browser.newPage()
const flow = await startFlow(page, { name: 'Checkout flow' })
await flow.navigate('https://shop.example.com')
await flow.startTimespan({ name: 'Add to cart' })
await page.click('#add')
await flow.endTimespan()
await flow.snapshot({ name: 'Cart loaded' })
const report = await flow.generateReport()
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Local optimization | DevTools Lighthouse panel |
| PR budget gate | lighthouse-ci + assertions |
| Multi-page audit | lhci with multiple URLs |
| SPA route transitions | User flows API |
| Real-user metrics | CrUX / web-vitals JS (Lighthouse 의 X) |
**기본값**: 매 lhci + budgets.json + GitHub Action + 3 runs median.
## 🔗 Graph
- 부모: [[Performance_Profiling_and_Memory|Performance Profiling]]
- 응용: [[CI_CD_Pipeline|CI_CD Pipeline]] · [[Continuous Integration (CI)]]
- Adjacent: [[Core Web Vitals Optimization (INP, LCP, CLS)|Cumulative Layout Shift (CLS)]] · [[SPA 라우트 전환 성능 최적화]]
## 🤖 LLM 활용
**언제**: pre-deploy quality gate, regression catch, web vitals tracking.
**언제 X**: 매 real-user perf 측정 (lab condition 일 뿐 — RUM 사용). Native app, server-only API.
## ❌ 안티패턴
- **단일 run score 의 의존**: variance 가 큼 — 매 median of 3-5 runs.
- **Lab score = field score 의 가정**: throttling profile 이 user 와 다름. 매 CrUX 와 cross-check.
- **High score 만 의 chase**: 100 score ≠ good UX. 매 INP/LCP 의 actual budget 의 focus.
- **CI 에 emulated mobile 만 의 test**: desktop user 도 audit.
## 🧪 검증 / 중복
- Verified (web.dev/lighthouse, lighthouse-ci docs, Lighthouse 12 release notes 2025).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Lighthouse 12 + CI integration patterns |
@@ -0,0 +1,168 @@
---
id: wiki-2026-0508-index-masking
title: Index Masking
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Bitmask Index, Power-of-Two Masking]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [optimization, low-level, ring-buffer, hash]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: C/C++/Rust/JavaScript
framework: General
---
# Index Masking
## 매 한 줄
> **"매 capacity 가 power-of-two 일 때 `% N` 의 `& (N-1)` replacement"**. 매 modulo 의 expensive (CPU cycle 10-30) 의 single-cycle `AND` 로 대체. Ring buffer, hash table bucket, fixed-size LRU, lock-free queue 의 hot path 의 universal trick. CPU branch predictor 와 cache line 의 friendly.
## 매 핵심
### 매 정확성 조건
- N 이 power-of-two: `2^k`.
- `index % N == index & (N - 1)` (unsigned 또는 non-negative).
- `N - 1` 이 모든 lower bit 의 1 의 mask.
### 매 대표 사용 처
- Ring buffer / circular queue.
- Open-addressing hash table bucket index.
- Game loop frame index modulo history size.
- Hardware register address calc.
- Lock-free SPSC/MPMC queue (Disruptor pattern).
### 매 응용
1. LMAX Disruptor (Java) — sequence & ringMask.
2. Linux kernel ringbuffer.
3. Redis hash table — sizemask.
4. V8 hidden class transitions table.
## 💻 패턴
### Basic ring buffer (C)
```c
#define RB_CAP 1024 // must be power of two
typedef struct {
int data[RB_CAP];
uint32_t head, tail; // free-running counters
} RingBuf;
static inline void rb_push(RingBuf *r, int v) {
r->data[r->head & (RB_CAP - 1)] = v;
r->head++;
}
static inline int rb_pop(RingBuf *r) {
int v = r->data[r->tail & (RB_CAP - 1)];
r->tail++;
return v;
}
```
### TypeScript fixed-size circular log
```typescript
class CircularLog<T> {
private buf: (T | undefined)[]
private mask: number
private head = 0
constructor(capacityPow2: number) {
if ((capacityPow2 & (capacityPow2 - 1)) !== 0)
throw new Error('capacity must be power of two')
this.buf = new Array(capacityPow2)
this.mask = capacityPow2 - 1
}
push(v: T) {
this.buf[this.head & this.mask] = v
this.head++
}
recent(n: number): T[] {
const out: T[] = []
for (let i = 0; i < n; i++) {
const v = this.buf[(this.head - 1 - i) & this.mask]
if (v !== undefined) out.push(v)
}
return out
}
}
```
### Round-up to next power of two
```c
uint32_t next_pow2(uint32_t v) {
v--;
v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16;
return v + 1;
}
```
### Hash table bucket
```rust
struct Map<K, V> {
buckets: Vec<Option<(K, V)>>,
mask: usize,
}
impl<K: Hash + Eq, V> Map<K, V> {
fn bucket(&self, k: &K) -> usize {
let mut h = DefaultHasher::new();
k.hash(&mut h);
(h.finish() as usize) & self.mask // mask = capacity - 1
}
}
```
### SPSC lock-free (Disruptor-style)
```c
// producer
void produce(RingBuf *r, int v) {
uint32_t h = atomic_load(&r->head);
while (h - atomic_load(&r->tail) >= RB_CAP) cpu_relax(); // full
r->data[h & (RB_CAP - 1)] = v;
atomic_store(&r->head, h + 1);
}
```
### Branch-free wrap (negative-safe)
```c
// for signed wrap, use bit-and after cast
int idx = ((int)(counter) & ((int)CAP - 1)); // counter must be non-negative
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Hot path, capacity 가 control 가능 | Power-of-2 + masking |
| Capacity 가 user-input arbitrary | `%` (or round up to pow2) |
| Capacity 가 dynamic resize | resize 시 `mask` recompute |
| Signed counter | unsigned cast 또는 modulo |
| Hardware-aligned (cache line) | pow2 + alignment 조합 |
**기본값**: 매 ring/hash table 는 power-of-two + bitmask. 매 capacity 의 dynamic 이면 round-up.
## 🔗 Graph
- 응용: [[Object Pooling (오브젝트 풀링)]]
- Adjacent: [[SharedArrayBuffer로 스레드 간 메모리 공유 효율 높이기]] · [[Pointer Compression]]
## 🤖 LLM 활용
**언제**: 매 high-throughput data structure, lock-free queue, HFT, game engine frame loop.
**언제 X**: capacity 의 control 안 되거나 readability priority 인 일반 application code.
## ❌ 안티패턴
- **Non-pow2 size 에 mask 적용**: 매 silent index out-of-range, data corruption.
- **Signed negative index 의 masking**: `-1 & (N-1)` 의 N-1 이 됨 → 매 unsigned cast 또는 `((i % N) + N) % N` pattern.
- **Capacity 1 의 mask 0**: 매 always index 0, degenerate.
- **Premature application**: 매 측정 없이 micro-optimization. 매 hot path 만 의 적용.
## 🧪 검증 / 중복
- Verified (Hacker's Delight Ch.3, LMAX Disruptor paper, Linux kfifo source, Redis dict.c).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — power-of-2 masking patterns + ring/hash applications |
@@ -0,0 +1,256 @@
---
id: wiki-2026-0508-instancedmesh-동적-버퍼-확장
title: InstancedMesh 동적 버퍼 확장
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Dynamic InstancedMesh, Resize InstancedMesh, InstancedMesh Growth]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [threejs, webgl, webgpu, performance, buffer]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Three.js r172
---
# InstancedMesh 동적 버퍼 확장
## 매 한 줄
> **"매 InstancedMesh 의 capacity 부족 시 GPU buffer 를 reallocate"**. Three.js InstancedMesh 의 `count` 는 fixed allocation. 매 instance 추가가 capacity 초과하면 새 buffer 를 만들고 기존 data 를 copy. 매 amortized O(1) 을 위한 geometric growth 가 정석.
## 매 핵심
### 매 기본 한계
-`new InstancedMesh(geo, mat, count)` 는 매 `count` 만큼 GPU buffer alloc.
-`mesh.count` 변경은 draw 만 줄이지 buffer 는 그대로.
- 매 capacity 초과 → 매 새 mesh / 새 InstancedBufferAttribute 가 필요.
### 매 Strategy
- **Geometric growth**: 매 capacity 부족 시 ×1.5 또는 ×2 로 resize.
- **Pool & free list**: 매 deletion 후 빈 slot 재사용 (compact 회피).
- **Chunked**: 매 fixed-size chunk N 개로 운영 (한 chunk 가득 차면 새 chunk).
### 매 응용
1. **Realtime particle spawn / despawn**.
2. **User-placed object editor** (매 추가 무한).
3. **Streaming voxel chunk** (매 LOD 별 instance 수 가변).
4. **NPC spawn system**.
## 💻 패턴
### 1. Geometric resize utility
```typescript
class DynamicInstancedMesh {
private mesh: THREE.InstancedMesh;
private capacity: number;
private size = 0;
private freeList: number[] = [];
constructor(
private geo: THREE.BufferGeometry,
private mat: THREE.Material,
initialCapacity = 64,
private maxCapacity = 1_000_000,
) {
this.capacity = initialCapacity;
this.mesh = this.makeMesh(initialCapacity);
}
private makeMesh(cap: number): THREE.InstancedMesh {
const m = new THREE.InstancedMesh(this.geo, this.mat, cap);
m.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
m.count = this.size;
return m;
}
add(matrix: THREE.Matrix4): number {
let idx: number;
if (this.freeList.length > 0) {
idx = this.freeList.pop()!;
} else {
if (this.size >= this.capacity) this.grow();
idx = this.size++;
}
this.mesh.setMatrixAt(idx, matrix);
this.mesh.instanceMatrix.needsUpdate = true;
this.mesh.count = this.size;
return idx;
}
remove(idx: number) {
// 매 zero-scale matrix 로 hide → free list 등록
const zero = new THREE.Matrix4().scale(new THREE.Vector3(0, 0, 0));
this.mesh.setMatrixAt(idx, zero);
this.mesh.instanceMatrix.needsUpdate = true;
this.freeList.push(idx);
}
private grow() {
const newCap = Math.min(this.capacity * 2, this.maxCapacity);
if (newCap <= this.capacity) throw new Error('Max capacity hit');
const newMesh = this.makeMesh(newCap);
// 매 기존 matrix 복사
const m = new THREE.Matrix4();
for (let i = 0; i < this.size; i++) {
this.mesh.getMatrixAt(i, m);
newMesh.setMatrixAt(i, m);
}
// 매 color 도 있으면 copy
if (this.mesh.instanceColor) {
const oldColor = this.mesh.instanceColor.array as Float32Array;
const newColor = new Float32Array(newCap * 3);
newColor.set(oldColor);
newMesh.instanceColor = new THREE.InstancedBufferAttribute(newColor, 3);
}
// 매 swap
const parent = this.mesh.parent;
if (parent) {
parent.remove(this.mesh);
parent.add(newMesh);
}
this.mesh.dispose(); // 매 매 critical: GPU buffer free
this.mesh = newMesh;
this.capacity = newCap;
console.log(`[DynamicInstancedMesh] grew → ${newCap}`);
}
get object(): THREE.InstancedMesh { return this.mesh; }
get instanceCount(): number { return this.size - this.freeList.length; }
}
```
### 2. Chunked strategy (매 large N 친화적)
```typescript
class ChunkedInstancedMesh {
private chunks: THREE.InstancedMesh[] = [];
private group = new THREE.Group();
private CHUNK_SIZE = 4096;
private currentChunkSize = 0;
constructor(private geo: THREE.BufferGeometry, private mat: THREE.Material) {
this.addChunk();
}
private addChunk() {
const m = new THREE.InstancedMesh(this.geo, this.mat, this.CHUNK_SIZE);
m.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
m.count = 0;
this.chunks.push(m);
this.group.add(m);
this.currentChunkSize = 0;
}
add(matrix: THREE.Matrix4): { chunk: number; idx: number } {
if (this.currentChunkSize >= this.CHUNK_SIZE) this.addChunk();
const chunkIdx = this.chunks.length - 1;
const chunk = this.chunks[chunkIdx];
const idx = this.currentChunkSize++;
chunk.setMatrixAt(idx, matrix);
chunk.count = idx + 1;
chunk.instanceMatrix.needsUpdate = true;
return { chunk: chunkIdx, idx };
}
get object(): THREE.Group { return this.group; }
}
```
### 3. Partial buffer update (updateRange)
```typescript
// 매 매 frame 일부만 변경 시 매 전체 upload 회피
function updateInstanceRange(
mesh: THREE.InstancedMesh, startIdx: number, count: number
) {
mesh.instanceMatrix.updateRange.offset = startIdx * 16; // mat4 = 16 floats
mesh.instanceMatrix.updateRange.count = count * 16;
mesh.instanceMatrix.needsUpdate = true;
}
```
### 4. WebGPU StorageBuffer 동적 grow
```typescript
import { storage, instanceIndex } from 'three/tsl';
class GPUDynamicInstances {
private buffer: THREE.StorageBufferAttribute;
private capacity: number;
constructor(initial = 1024) {
this.capacity = initial;
this.buffer = new THREE.StorageBufferAttribute(initial, 16);
}
grow(needed: number) {
const newCap = Math.max(this.capacity * 2, needed);
const newBuf = new THREE.StorageBufferAttribute(newCap, 16);
// 매 GPU-side copy: compute pass 로 old → new
// 매 또는 CPU readback 후 재upload (매 비싸지만 단순)
newBuf.array.set(this.buffer.array);
this.buffer = newBuf;
this.capacity = newCap;
}
}
```
### 5. Defragment (free list 가 너무 커지면)
```typescript
defragment(dim: DynamicInstancedMesh) {
// 매 freeList sort 후 살아있는 instance 를 앞으로 compact
// 매 user-facing index 가 바뀌므로 index map 도 업데이트해야 함
// ... (구현은 use case 별 — id↔index 매핑 유지가 매 critical)
}
```
### 6. dispose 와 GPU memory 관리
```typescript
function disposeInstanced(mesh: THREE.InstancedMesh) {
mesh.geometry.dispose();
if (Array.isArray(mesh.material)) mesh.material.forEach(m => m.dispose());
else mesh.material.dispose();
mesh.dispose(); // 매 InstancedMesh 자체 buffer
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 instance 수가 천천히 변동 | Geometric grow ×2 |
| 매 instance 수 매 frame 격변 | Pre-alloc max + count 조절 |
| 매 매우 큰 N + streaming | Chunked (CHUNK_SIZE 4-16k) |
| 매 frequent delete | Free list + zero-scale hide |
| 매 free list ≥ 30% | Defragment 한 번 |
| 매 GPU-driven spawn | WebGPU StorageBuffer + compute |
**기본값**: 매 generic dynamic case → DynamicInstancedMesh (×2 grow + free list + zero-scale remove).
## 🔗 Graph
- 부모: [[InstancedMesh 최적화]] · [[Three.js]]
- 변형: [[BatchedMesh]]
## 🤖 LLM 활용
**언제**: dynamic spawn/despawn 시스템 설계, free list vs chunked 의 trade-off 설명.
**언제 X**: 매 specific WebGL driver memory bug.
## ❌ 안티패턴
- **매 add 마다 new InstancedMesh**: 매 GPU alloc storm — 반드시 amortize.
- **dispose() 빠뜨림**: 매 grow 후 옛 mesh GPU buffer 의 leak.
- **Linear grow (+1, +1)**: O(N²) total copy. 매 geometric (×1.5 or ×2) 만 사용.
- **remove 후 splice**: 매 모든 후속 idx shift → 비싸다. 매 zero-scale + free list.
- **매 free list 만 쓰고 defrag 없음**: 매 hide 된 instance 도 vertex shader 실행 (zero-scale 은 깎임).
## 🧪 검증 / 중복
- Verified (Three.js r172 source `src/objects/InstancedMesh.js`).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — dynamic grow + free list + chunked |
@@ -0,0 +1,171 @@
---
id: wiki-2026-0508-instancedmesh-사용-시-드로우-콜-최적화의-한계
title: InstancedMesh 사용 시 드로우 콜 최적화의 한계점 사례 연구
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [InstancedMesh Limits, Instancing Limits]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [graphics, three-js, performance, instancing]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript/GLSL
framework: Three.js r170+/WebGL2/WebGPU
---
# InstancedMesh 사용 시 드로우 콜 최적화의 한계점 사례 연구
## 매 한 줄
> **"매 InstancedMesh 매 1 draw call로 N copies — but 매 frustum culling, material variation, animation, picking 의 cost가 instance 수에 따라 explode."**. 매 naive 사용 시 draw call 매 줄어들어도 GPU vertex/fragment 매 burden, CPU matrix update 매 bottleneck. 매 production 매 LOD + spatial partition + GPU culling 매 결합.
## 매 핵심
### 매 한계 list
- **No per-instance frustum culling**: 매 single bounding sphere → 매 모든 instance가 frustum 안에 있다고 GPU가 가정.
- **No per-instance material**: 매 same material → color/texture variation 매 instanceColor / instance attribute 의 manual.
- **Animation cost**: 매 instance마다 matrix update → CPU bound at 10k+.
- **Picking 어려움**: raycaster 매 instance index 매 별도 처리.
- **Memory**: 16 floats × N instances = 매 1M instances → 64MB matrix buffer.
- **Shadow map**: 매 light 마다 또 한 번 instanced draw — culling 없으면 shadow waste.
### 매 case: 100k cubes
- Naive InstancedMesh: 매 1 draw call, GPU 60fps but matrix update 60ms/frame on CPU.
- Static (`setMatrixAt` once): 매 GPU bound, fillrate 매 issue → LOD 필요.
- Dynamic: 매 매 frame matrix update → useDynamicDrawUsage + partial updates.
### 매 응용 (해결 전략)
1. **GPU instancing + GPU culling**: compute shader 매 frustum check, 매 indirect draw.
2. **Spatial partitioning**: octree / BVH로 매 chunk 단위 InstancedMesh.
3. **LOD groups**: distance 별 다른 InstancedMesh (high/med/low/billboard).
4. **BatchedMesh (Three.js r170+)**: 매 different geometries를 single draw call.
5. **Hierarchical LOD + impostor**: 매 far away는 single quad billboard.
## 💻 패턴
### Frustum culling 수동 (Three.js)
```javascript
const frustum = new THREE.Frustum();
const m = new THREE.Matrix4();
m.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
frustum.setFromProjectionMatrix(m);
const dummy = new THREE.Object3D();
const sphere = new THREE.Sphere(new THREE.Vector3(), boundingRadius);
let visibleCount = 0;
for (let i = 0; i < totalInstances; i++) {
sphere.center.copy(positions[i]);
if (frustum.intersectsSphere(sphere)) {
dummy.position.copy(positions[i]);
dummy.updateMatrix();
instancedMesh.setMatrixAt(visibleCount++, dummy.matrix);
}
}
instancedMesh.count = visibleCount;
instancedMesh.instanceMatrix.needsUpdate = true;
```
### Per-instance color
```javascript
const mesh = new THREE.InstancedMesh(geo, mat, N);
const color = new THREE.Color();
for (let i = 0; i < N; i++) {
color.setHSL(i / N, 0.7, 0.5);
mesh.setColorAt(i, color);
}
mesh.instanceColor.needsUpdate = true;
// shader auto: gl_InstanceID → vInstanceColor
```
### Dynamic draw usage (partial updates)
```javascript
mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
// only update changed instances
mesh.setMatrixAt(idx, newMatrix);
mesh.instanceMatrix.updateRange = { offset: idx * 16, count: 16 };
mesh.instanceMatrix.needsUpdate = true;
```
### Chunked InstancedMesh (spatial bucket)
```javascript
class ChunkedInstances {
constructor(geo, mat, chunkSize = 64) {
this.chunks = new Map(); // "x,y,z" → InstancedMesh
this.chunkSize = chunkSize;
}
add(pos) {
const key = this.chunkKey(pos);
if (!this.chunks.has(key)) {
this.chunks.set(key, new THREE.InstancedMesh(geo, mat, 1024));
}
// ...
}
cullChunks(frustum) {
for (const [key, mesh] of this.chunks) {
mesh.visible = frustum.intersectsBox(this.chunkBox(key));
}
}
}
```
### BatchedMesh (Three.js r170+)
```javascript
const batched = new THREE.BatchedMesh(maxGeoms, maxVerts, maxIdx);
const geoIdA = batched.addGeometry(geoA);
const geoIdB = batched.addGeometry(geoB);
const instA = batched.addInstance(geoIdA);
batched.setMatrixAt(instA, matrixA);
// 매 different geometries 매 single draw call
```
### GPU compute culling (WebGPU)
```javascript
// compute shader: input matrices + frustum planes → atomic counter + visible matrix buffer
const cullPipeline = device.createComputePipeline({...});
pass.setPipeline(cullPipeline);
pass.dispatchWorkgroups(Math.ceil(N / 64));
// then drawIndexedIndirect from visible buffer
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| < 1k static instances | Plain InstancedMesh |
| 1k100k mostly static | InstancedMesh + manual frustum culling |
| 100k+ static | Chunked InstancedMesh (spatial) + LOD |
| Dynamic per-frame (particles) | Points / GPU particle system |
| Different geometries | BatchedMesh (r170+) |
| Massive (1M+) | WebGPU compute culling + indirect draw |
| Picking 필요 | InstancedMesh + raycaster.firstHitOnly = true |
**기본값**: < 10k는 plain InstancedMesh, 그 이상 매 chunked + LOD.
## 🔗 Graph
- 부모: [[GPU Instancing]] · [[Three.js]]
- 변형: [[BatchedMesh]]
- Adjacent: [[Frustum Culling]] · [[LOD]] · [[Indirect Draw]] · [[WebGPU]]
## 🤖 LLM 활용
**언제**: 매 같은 geometry+material의 N copies, 매 N > 50, 매 draw call 매 hot path bottleneck.
**언제 X**: 매 highly varying geometry (use BatchedMesh), 매 < 50 copies (overhead > benefit), 매 fully dynamic mesh (skinning per instance은 expensive).
## ❌ 안티패턴
- **No bounding 갱신**: 매 instance 매 spread out 매 single boundingSphere가 too large → frustum culling 작동 안 함.
- **매 frame full matrix rebuild**: 매 instance 매 100% update assumption 매 wrong → updateRange 활용.
- **Different materials → multiple InstancedMesh**: 매 점 defeats the purpose. Use texture atlas + instance attribute.
- **Skip LOD**: 매 far instance 매 close instance와 same vertex count → fillrate explosion.
- **InstancedMesh on top of skinned mesh**: 매 shader 매 manual instancing 필요 — Three.js native skinning 매 instance와 conflict.
## 🧪 검증 / 중복
- Verified (Three.js docs r170+, mrdoob InstancedMesh PR, WebGPU spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — InstancedMesh 한계 / 해결 패턴 / BatchedMesh + WebGPU compute culling |
@@ -0,0 +1,225 @@
---
id: wiki-2026-0508-instancedmesh-최적화
title: InstancedMesh 최적화
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [InstancedMesh, GPU Instancing, Three.js Instancing]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [threejs, webgl, webgpu, rendering, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Three.js r172 / WebGPU
---
# InstancedMesh 최적화
## 매 한 줄
> **"매 동일 geometry 의 N 개를 1 draw call 로"**. InstancedMesh 는 매 같은 mesh 를 instance attribute (matrix, color) 만 바꿔 GPU 에 한 번에 제출. 매 forest, particle, crowd 같은 thousands-of-objects scene 에서 50-1000x throughput.
## 매 핵심
### 매 작동 원리
- 매 vertex shader 는 `gl_InstanceID` (WebGL2) / `instance_index` (WebGPU) 로 per-instance 데이터 lookup.
- 매 instanceMatrix (mat4) 는 default attribute. 매 추가로 instanceColor, custom attribute 가능.
- 매 draw call: `gl.drawElementsInstanced(mode, count, type, offset, instanceCount)`.
### 매 비용 분석
- **CPU 절감**: 매 N draw call → 1. 매 binding state 변경 N → 1.
- **GPU 비용**: 매 동일 (vertex 처리 N×). 매 절감은 driver overhead 에서.
- **Break-even**: 매 보통 ~50-100 instance 부터 이득. 매 이하면 batched geometry 가 더 빠를 수도.
### 매 응용
1. **Forest / vegetation** (10k trees).
2. **Particle system** (smoke, sparks).
3. **Crowd / NPC swarm**.
4. **Voxel chunk rendering**.
5. **UI marker overlay** (map pins).
## 💻 패턴
### 1. 기본 InstancedMesh 셋업 (Three.js r172)
```typescript
import * as THREE from 'three';
const geo = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshStandardMaterial({ color: 0x88aaff });
const COUNT = 10_000;
const mesh = new THREE.InstancedMesh(geo, mat, COUNT);
mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // 매 자주 업데이트면
const m = new THREE.Matrix4();
const q = new THREE.Quaternion();
const s = new THREE.Vector3(1, 1, 1);
const p = new THREE.Vector3();
for (let i = 0; i < COUNT; i++) {
p.set((Math.random() - 0.5) * 200, 0, (Math.random() - 0.5) * 200);
q.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.random() * Math.PI * 2);
m.compose(p, q, s);
mesh.setMatrixAt(i, m);
}
mesh.instanceMatrix.needsUpdate = true;
scene.add(mesh);
```
### 2. Per-instance color (vertex color attribute)
```typescript
const colors = new Float32Array(COUNT * 3);
for (let i = 0; i < COUNT; i++) {
colors[i*3] = Math.random();
colors[i*3+1] = Math.random();
colors[i*3+2] = Math.random();
}
mesh.instanceColor = new THREE.InstancedBufferAttribute(colors, 3);
```
### 3. Frustum culling per-instance (BVH-based)
```typescript
import { computeBoundsTree, MeshBVH } from 'three-mesh-bvh';
// 매 default InstancedMesh 는 whole-mesh frustum culling 만 함.
// 매 instance-level 은 manual: BVH 로 visible instance 만 update.
const bvh = new MeshBVH(geo);
const visibleMatrices: THREE.Matrix4[] = [];
const frustum = new THREE.Frustum().setFromProjectionMatrix(
new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)
);
let visibleCount = 0;
for (let i = 0; i < COUNT; i++) {
mesh.getMatrixAt(i, m);
p.setFromMatrixPosition(m);
if (frustum.containsPoint(p)) {
mesh.setMatrixAt(visibleCount++, m);
}
}
mesh.count = visibleCount; // 매 핵심: count 만 줄여 draw 절감
mesh.instanceMatrix.needsUpdate = true;
```
### 4. WebGPU instancing (Three.js r172 WebGPURenderer)
```typescript
import { WebGPURenderer, MeshBasicNodeMaterial } from 'three/webgpu';
import { instanceIndex, vec3, color } from 'three/tsl';
const mat = new MeshBasicNodeMaterial();
// 매 TSL 로 per-instance color 계산
mat.colorNode = color(vec3(
instanceIndex.toFloat().div(COUNT).fract(),
0.5,
0.8
));
const mesh = new THREE.InstancedMesh(geo, mat, COUNT);
```
### 5. LOD + InstancedMesh 결합
```typescript
class InstancedLOD {
constructor(private high: THREE.InstancedMesh,
private mid: THREE.InstancedMesh,
private low: THREE.InstancedMesh) {}
update(camera: THREE.Camera, positions: THREE.Vector3[]) {
let h = 0, m = 0, l = 0;
const matrix = new THREE.Matrix4();
for (const p of positions) {
const d = p.distanceTo(camera.position);
const target = d < 30 ? this.high : d < 100 ? this.mid : this.low;
const idx = d < 30 ? h++ : d < 100 ? m++ : l++;
matrix.setPosition(p);
target.setMatrixAt(idx, matrix);
}
this.high.count = h; this.mid.count = m; this.low.count = l;
[this.high, this.mid, this.low].forEach(x => x.instanceMatrix.needsUpdate = true);
}
}
```
### 6. GPU compute 로 instance 위치 (WebGPU)
```typescript
import { Fn, instanceIndex, storage, vec3, time } from 'three/tsl';
import { compute } from 'three/tsl';
const positionBuffer = storage(new THREE.StorageBufferAttribute(COUNT, 3), 'vec3');
const updateFn = Fn(() => {
const i = instanceIndex.toFloat();
const t = time;
positionBuffer.element(instanceIndex).assign(
vec3(i.mul(0.1).sin().mul(50), t.add(i).sin().mul(5), i.mul(0.1).cos().mul(50))
);
});
const computePass = updateFn().compute(COUNT);
renderer.computeAsync(computePass); // 매 frame 마다
```
### 7. Memory layout 최적화 (matrix → quat+pos+scale)
```typescript
// 매 mat4 (16 floats × 4B = 64B) 대신 quat (4) + pos (3) + scale (1) = 32B
const compactBuffer = new Float32Array(COUNT * 8);
mesh.geometry.setAttribute('iQuat',
new THREE.InstancedBufferAttribute(compactBuffer, 4, false, 1).setUsage(THREE.DynamicDrawUsage));
// shader 에서 quat → matrix reconstruct
```
### 8. Sort by depth (transparency)
```typescript
const indices = Array.from({length: COUNT}, (_, i) => i);
indices.sort((a, b) => {
mesh.getMatrixAt(a, m); const da = p.setFromMatrixPosition(m).distanceTo(camera.position);
mesh.getMatrixAt(b, m); const db = p.setFromMatrixPosition(m).distanceTo(camera.position);
return db - da; // 매 back-to-front
});
const sorted = new Float32Array(COUNT * 16);
for (let i = 0; i < COUNT; i++) {
mesh.getMatrixAt(indices[i], m);
m.toArray(sorted, i * 16);
}
mesh.instanceMatrix.array.set(sorted);
mesh.instanceMatrix.needsUpdate = true;
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Static, identical mesh × thousands | `InstancedMesh` |
| Static, varied meshes | `BatchedMesh` (Three.js r158+) |
| 매 < 50 instance | 매 그냥 separate Mesh, 차이 없음 |
| 매 frequent matrix update | `setUsage(DynamicDrawUsage)` + partial `updateRange` |
| Per-instance custom data | `InstancedBufferAttribute` |
| GPU-driven motion | TSL compute + storage buffer |
**기본값**: 매 ≥100 identical instance → InstancedMesh + DynamicDrawUsage + frustum culling.
## 🔗 Graph
- 부모: [[Three.js]] · [[GPU Instancing]] · [[WebGL/WebGPU]]
- 변형: [[BatchedMesh]]
- Adjacent: [[InstancedMesh 동적 버퍼 확장]] · [[Frustum Culling]] · [[LOD]]
## 🤖 LLM 활용
**언제**: instance 수에 따른 기법 선택, draw call 분석 해석, TSL compute shader 작성.
**언제 X**: 매 specific GPU/driver bug 진단 (실측 profile 없이).
## ❌ 안티패턴
- **매 frame 마다 setMatrixAt 전체 N**: 매 변하지 않는 instance 까지 update → CPU bound. 매 dirty flag 사용.
- **DynamicDrawUsage 빠뜨림**: 매 default StaticDrawUsage 면 매 update 시 driver hint mismatch.
- **count 줄이지 않고 culling**: 매 invisible 도 vertex shader 실행됨.
- **너무 작은 N (< 50)**: 매 instancing overhead 가 이득보다 큼.
## 🧪 검증 / 중복
- Verified (Three.js r172 docs, WebGPU spec, Khronos WebGL2 spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — InstancedMesh 패턴 + WebGPU TSL compute |
@@ -0,0 +1,150 @@
---
id: wiki-2026-0508-interop-2025
title: Interop 2025
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Web Interop 2025]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [web-platform, browser, standards]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: HTML/CSS/JavaScript
framework: Web Platform
---
# Interop 2025
## 매 한 줄
> **"매 browser vendor 들이 매년 합의하여 fix 하는 web platform inconsistency list"**. Apple, Google, Microsoft, Mozilla, Bocoup, Igalia 가 공동으로 select 한 focus area 를 1년간 implement, web-platform-tests pass rate 의 dashboard 로 progress 의 track. 2025 cycle 의 anchor positioning, scrollbar styling, navigation API, View Transitions cross-document, storage access API 가 highlight.
## 매 핵심
### 매 origin & process
- 2021 Compat 2021 시작, 2022 부터 "Interop" 명칭.
- 매년 vendor 공동 선정 + community proposal.
- WPT (web-platform-tests) score 로 measure — wpt.fyi dashboard.
### 매 Interop 2025 의 focus areas
- **Anchor positioning** (CSS): tooltip/popover 의 declarative anchor.
- **View Transitions cross-document**: MPA 도 SPA 같은 transition.
- **Scrollbar gutter / colors**: scrollbar styling cross-browser.
- **Navigation API**: history API replacement.
- **Storage Access API**: cross-site cookie consent flow.
- **Container queries** (residual gaps).
- **Custom highlights API**: native highlight rendering.
### 매 응용
1. Web feature 의 production-safe baseline 결정 (Baseline initiative 와 align).
2. Polyfill / progressive enhancement strategy 의 기준.
3. Browser team 의 quarterly priority.
## 💻 패턴
### Anchor positioning (CSS)
```css
/* Trigger */
.btn { anchor-name: --my-anchor; }
/* Popover positioned relative to anchor */
.tooltip {
position: absolute;
position-anchor: --my-anchor;
top: anchor(bottom);
left: anchor(center);
translate: -50% 8px;
}
```
### View Transitions cross-document
```html
<!-- both pages opt in -->
<meta name="view-transition" content="same-origin">
<style>
@view-transition { navigation: auto; }
.hero { view-transition-name: hero; }
</style>
```
### Navigation API
```javascript
navigation.addEventListener('navigate', (e) => {
if (!e.canIntercept || e.hashChange) return
e.intercept({
handler: async () => {
const data = await fetch(e.destination.url).then(r => r.json())
render(data)
},
})
})
```
### Storage Access API
```javascript
// inside iframe — request 1P-like cookie access
if (await document.hasStorageAccess() === false) {
try {
await document.requestStorageAccess()
} catch (e) { /* user denied */ }
}
```
### Scrollbar styling (modern)
```css
.list {
scrollbar-gutter: stable both-edges;
scrollbar-width: thin;
scrollbar-color: var(--thumb) transparent;
}
```
### Feature detect via Baseline / `@supports`
```css
@supports (anchor-name: --x) {
.tooltip { position-anchor: --my-anchor; }
}
@supports not (anchor-name: --x) {
.tooltip { /* fallback positioning JS */ }
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| New feature production use | Interop 2025 list + Baseline check |
| 필요한 feature 가 still red | polyfill or feature flag |
| Cross-browser bug found | wpt.fyi 에 issue file |
| Greenfield SPA | Navigation API 채택 검토 |
| Tooltip / popover | Anchor positioning + popover API |
**기본값**: 매 Baseline Newly Available + Interop 2025 통과 feature 만 의 default 사용.
## 🔗 Graph
- 변형: [[Interop 2026]]
- 응용: [[View Transitions API]] · [[Navigation API]]
- Adjacent: [[Chromium]] · [[Baseline]]
## 🤖 LLM 활용
**언제**: 매 web platform feature 의 cross-browser readiness 의 query, polyfill strategy, modern CSS/JS adoption 결정.
**언제 X**: server-side, native, non-browser runtime.
## ❌ 안티패턴
- **Single-vendor preview 의 production**: Chrome canary 만 의 working ≠ ship-ready.
- **WPT pass = bug-free 의 가정**: real-world edge case 는 WPT 가 다 cover X.
- **Polyfill 의 무지성 적용**: native 가 ship 된 후에도 polyfill 유지 = bundle bloat.
- **Interop list 의 구속**: list 외 의 feature 도 needed 면 채택 가능 — list 는 priority 일 뿐.
## 🧪 검증 / 중복
- Verified (web.dev/interop-2025, wpt.fyi/interop-2025, vendor blog posts 2025).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Interop 2025 focus areas + adoption patterns |
@@ -0,0 +1,152 @@
---
id: wiki-2026-0508-inventory-management-example
title: Inventory Management Example
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Inventory Domain Model, 재고 관리 예제]
duplicate_of: none
source_trust_level: B
confidence_score: 0.85
verification_status: applied
tags: [example, domain-modeling, typescript, ddd]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Zod
---
# Inventory Management Example
## 매 한 줄
> **"매 SKU · stock · reservation 의 type-safe domain model 의 walking example"**. 매 branded types · discriminated unions · runtime validation 매 결합 — 2026 modern TS pattern 의 canonical illustration.
## 매 핵심
### 매 도메인 entities
- `SKU` (branded string)
- `Stock` (positive int)
- `Reservation` (id, sku, qty, expiresAt)
- `InventoryEvent` (Tagged: Received | Reserved | Shipped | Cancelled)
### 매 invariants
- 매 stock ≥ 0 항상.
- 매 reservation 의 release 후 stock 회복.
- 매 ship 의 reservation 의 존재 시.
### 매 응용
1. E-commerce checkout flow (재고 차감 · 복구).
2. Warehouse management (multi-location).
3. Event-sourced inventory ledger.
## 💻 패턴
### Branded SKU
```ts
type SKU = string & { readonly __brand: "SKU" }
const SkuSchema = z.string().regex(/^[A-Z]{3}-\d{6}$/).brand("SKU")
const sku = SkuSchema.parse("ABC-123456") // SKU
```
### Stock value object
```ts
class Stock {
private constructor(public readonly value: number) {}
static of(n: number): Stock {
if (!Number.isInteger(n) || n < 0) throw new Error("invalid stock")
return new Stock(n)
}
reserve(qty: number): Stock { return Stock.of(this.value - qty) }
release(qty: number): Stock { return Stock.of(this.value + qty) }
}
```
### Discriminated event union
```ts
type InventoryEvent =
| { type: "Received"; sku: SKU; qty: number; at: Date }
| { type: "Reserved"; sku: SKU; qty: number; reservationId: string }
| { type: "Shipped"; reservationId: string }
| { type: "Cancelled"; reservationId: string }
function reduce(state: Map<SKU, Stock>, e: InventoryEvent): Map<SKU, Stock> {
switch (e.type) {
case "Received":
return new Map(state).set(e.sku, (state.get(e.sku) ?? Stock.of(0)).release(e.qty))
case "Reserved":
return new Map(state).set(e.sku, state.get(e.sku)!.reserve(e.qty))
case "Shipped":
case "Cancelled":
return state
}
}
```
### Reservation lifecycle (Result type)
```ts
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E }
function reserve(stock: Stock, qty: number): Result<Stock, "INSUFFICIENT"> {
if (stock.value < qty) return { ok: false, error: "INSUFFICIENT" }
return { ok: true, value: stock.reserve(qty) }
}
```
### Zod runtime parse (API boundary)
```ts
const ReserveCmd = z.object({
sku: SkuSchema,
qty: z.number().int().positive(),
customerId: z.string().uuid(),
})
app.post("/reserve", (req, res) => {
const cmd = ReserveCmd.safeParse(req.body)
if (!cmd.success) return res.status(400).json(cmd.error.flatten())
// ... cmd.data is fully typed
})
```
### Exhaustive switch guard
```ts
function never(x: never): never { throw new Error(`unhandled: ${x}`) }
// switch default → never(e) 매 새 event 추가 시 compile error
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Single-location inventory | In-memory `Map<SKU, Stock>` |
| Multi-location | Add `LocationId` brand · partition state |
| Audit-required | Event sourcing (full event log) |
| High-concurrency | Optimistic concurrency token + retry |
**기본값**: event-sourced reduce 매 audit + replay benefit. 매 단순 case도 future-proof.
## 🔗 Graph
- 부모: [[Domain-Driven Design]] · [[견고한 도메인 모델 및 API 계약 설계]]
- 변형: [[Result Type]] · [[Discriminated_Unions|Discriminated Unions]]
- 응용: [[Zod 파싱과 브랜디드 타입을 결합한 런타임 데이터 검증]]
- Adjacent: [[브랜디드 타입 (Branded Types)]] · [[ts-brand]] · [[완전성 검사(Exhaustiveness Checking)]]
## 🤖 LLM 활용
**언제**: 매 type-safe domain modeling 의 teaching example 으로 reuse.
**언제 X**: 매 production app 의 직접 copy — 매 oversimplified.
## ❌ 안티패턴
- **Plain `number` for stock**: 매 invariant 의 enforce 의 X — class · brand 의 사용.
- **Stringly-typed events**: 매 discriminated union 의 사용.
- **Skipping runtime parse at boundary**: 매 type erasure 후 — Zod / Effect Schema 의 필수.
## 🧪 검증 / 중복
- Verified (DDD blue book · Effect/Zod docs · TypeScript handbook 2026).
- 신뢰도 B (illustrative example, not canonical implementation).
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full domain example with brands · DU · event sourcing |
@@ -0,0 +1,34 @@
---
id: wiki-20260508-netflix--redir
title: Netflix 마이크로서비스 전환
category: 10_Wiki/Topics
status: duplicate
canonical_id: netflix-cosmos-platform
duplicate_of: "[[Netflix 마이크로서비스 및 코스모스 플랫폼 전환]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, netflix, microservices, architecture]
last_reinforced: 2026-05-10
github_commit: pending
---
# Netflix 마이크로서비스 전환
> **이 문서는 [[넷플릭스(Netflix)의 마이크로서비스 및 코스모스 플랫폼 전환]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- 매 Netflix 의 monolith → microservices 전환 (2008-2016).
- 매 Cosmos 플랫폼: 매 next-gen media processing — workflow + service 의 통합.
- 매 OSS 산출물: Eureka, Hystrix, Zuul, Chaos Monkey.
## 🔗 Graph
- 부모: [[넷플릭스(Netflix)의 마이크로서비스 및 코스모스 플랫폼 전환]] (canonical)
- Adjacent: [[Cosmos 플랫폼 (Netflix)]] · [[넷플릭스 코스모스 플랫폼 (Netflix Cosmos)]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,180 @@
---
id: wiki-2026-0508-nodejs-성능-최적화-및-디버깅
title: Nodejs 성능 최적화 및 디버깅
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Nodejs 메모리 최적화, Nodejs 메모리 튜닝, Nodejs 성능 디버깅, Nodejs 프로세스 모니터링]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [nodejs, performance, debugging, memory, v8]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: javascript
framework: nodejs
---
# Nodejs 성능 최적화 및 디버깅
## 매 한 줄
> **"매 production Node 의 성능 의 V8 heap + event loop + async I/O 의 3-축 의 governing"**. 매 2026 의 Node 22 LTS 의 default — 매 V8 12.x 의 Maglev/Turbofan tier 의 활용 + native diagnostic_channel + clinic.js 4.x 의 standard toolchain.
## 매 핵심
### 매 3-축 model
- **Heap**: 매 V8 의 Old/New Space 의 GC pressure.
- **Event Loop**: 매 microtask + macrotask + nextTick 의 priority.
- **Async I/O**: 매 libuv thread pool (`UV_THREADPOOL_SIZE` default 4).
### 매 진단 toolkit (2026)
- `node --inspect` + Chrome DevTools.
- `clinic.js doctor / flame / bubbleprof / heapprofiler`.
- `0x` (flamegraph generator).
- `node --prof` + `--prof-process`.
- `diagnostic_channel` (Node 16+) — 매 production-safe instrumentation.
### 매 응용
1. Memory leak 의 추적 — heap snapshot diff.
2. CPU bottleneck 의 식별 — flame graph.
3. Event loop lag 의 monitoring — `perf_hooks.monitorEventLoopDelay`.
## 💻 패턴
### Heap snapshot 비교
```javascript
const v8 = require('v8');
const fs = require('fs');
function snapshot(label) {
const file = `/tmp/heap-${label}-${Date.now()}.heapsnapshot`;
const stream = v8.getHeapSnapshot();
stream.pipe(fs.createWriteStream(file));
return file;
}
// usage
const before = snapshot('before');
runWorkload();
global.gc?.(); // --expose-gc
const after = snapshot('after');
// → load both into Chrome DevTools, compare retainers
```
### Event loop delay monitoring
```javascript
import { monitorEventLoopDelay } from 'node:perf_hooks';
const h = monitorEventLoopDelay({ resolution: 20 });
h.enable();
setInterval(() => {
const p99 = h.percentile(99) / 1e6; // ms
if (p99 > 100) console.warn(`event loop p99 lag: ${p99.toFixed(1)}ms`);
h.reset();
}, 5000);
```
### CPU profile (production-safe)
```javascript
import { Session } from 'node:inspector/promises';
const session = new Session();
session.connect();
await session.post('Profiler.enable');
await session.post('Profiler.start');
// ... run workload
const { profile } = await session.post('Profiler.stop');
fs.writeFileSync('cpu.cpuprofile', JSON.stringify(profile));
```
### Heap limit 설정
```bash
# 8GB heap
node --max-old-space-size=8192 server.js
# container-aware
node --max-old-space-size=$(echo "$(cat /sys/fs/cgroup/memory.max) * 0.75 / 1024 / 1024" | bc) server.js
```
### diagnostic_channel instrumentation
```javascript
import diagnostics_channel from 'node:diagnostics_channel';
const ch = diagnostics_channel.channel('app:slow-query');
ch.subscribe((msg) => {
metrics.histogram('db.query.slow', msg.duration);
});
// publisher
ch.publish({ query, duration });
```
### Async resource tracking
```javascript
import { AsyncLocalStorage } from 'node:async_hooks';
const als = new AsyncLocalStorage();
app.use((req, res, next) => {
als.run({ requestId: req.id }, next);
});
logger.info = (msg) => {
const ctx = als.getStore();
console.log(JSON.stringify({ msg, requestId: ctx?.requestId }));
};
```
### Worker thread offload
```javascript
import { Worker } from 'node:worker_threads';
function cpuHeavyTask(data) {
return new Promise((resolve, reject) => {
const w = new Worker('./worker.js', { workerData: data });
w.on('message', resolve);
w.on('error', reject);
});
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Memory leak 의심 | heap snapshot diff (3개 시점) |
| CPU spike | clinic flame / 0x flamegraph |
| Latency p99 ↑ | event loop delay monitor |
| OOM kill (container) | `--max-old-space-size` 의 container limit 의 75% |
| Async chain debugging | AsyncLocalStorage + diagnostic_channel |
**기본값**: clinic doctor 로 시작 → 매 specific tool (flame/bubbleprof) 의 narrowing.
## 🔗 Graph
- 부모: [[V8 엔진 힙 아키텍처]] · [[Garbage Collection]]
- 변형: [[Nodejs 메모리 최적화]] · [[Nodejs 메모리 튜닝]] · [[Nodejs 성능 디버깅]]
- 응용: [[Nodejs 프로세스 모니터링 및 메모리 분석]] · [[브라우저 및 Nodejs 메모리 튜닝]]
- Adjacent: [[Chrome DevTools(크롬 개발자 도구)]] · [[Flame Chart]] · [[할당 타임라인(Allocation Timeline)]]
## 🤖 LLM 활용
**언제**: production Node 의 성능 회귀 의 진단, heap leak 의 root cause analysis.
**언제 X**: synthetic benchmark — 매 real workload profile 만 의 trustworthy.
## ❌ 안티패턴
- **Premature optimization**: 매 profile 의 X — guess 의 X.
- **`global.gc()` 의 production 호출**: 매 stop-the-world — latency spike.
- **`UV_THREADPOOL_SIZE` 의 무분별 증가**: 매 context switch 의 overhead.
- **heap snapshot 의 production load 의 down**: 매 GB-scale 의 dump — disk + pause.
## 🧪 검증 / 중복
- Verified (Node.js 22 docs, V8 blog, Matteo Collina's perf talks).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Node 22 / clinic 4.x / diagnostic_channel 반영 |
@@ -0,0 +1,230 @@
---
id: wiki-2026-0508-object-pooling-오브젝트-풀링
title: Object Pooling (오브젝트 풀링)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [오브젝트 풀링, Object Pool Pattern]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [pattern, performance, memory, gc, gamedev]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: agnostic
---
# Object Pooling (오브젝트 풀링)
## 매 한 줄
> **"매 expensive object 의 reuse 로 GC pressure + allocation cost 의 회피"**. 매 game loop / hot path / high-frequency event handler 의 standard 의 패턴 — 매 2026 의 game engine (Three.js, Bevy, Unity DOTS), DB connection pool, HTTP keep-alive, worker pool 의 universal 의 pattern.
## 매 핵심
### 매 3-component
- **Pool**: 매 object 의 collection (free list).
- **Acquire**: 매 free object 의 dequeue (또는 신규 생성).
- **Release**: 매 object 의 reset + enqueue.
### 매 언제 적용
- 매 allocation rate > 10K/sec.
- 매 object lifetime 의 짧음 (< 1 frame).
- 매 GC pause 의 user-visible (game, real-time).
- 매 expensive constructor (DB connect, file open, GPU buffer alloc).
### 매 응용
1. Game particle system — bullet, explosion, enemy.
2. DB connection pool — `pg-pool`, HikariCP.
3. HTTP agent — `http.Agent({ keepAlive: true })`.
4. Web Worker pool — `piscina`.
## 💻 패턴
### Generic pool (TypeScript)
```typescript
class ObjectPool<T> {
private free: T[] = [];
constructor(
private factory: () => T,
private reset: (obj: T) => void,
initialSize = 0
) {
for (let i = 0; i < initialSize; i++) this.free.push(factory());
}
acquire(): T {
return this.free.pop() ?? this.factory();
}
release(obj: T): void {
this.reset(obj);
this.free.push(obj);
}
}
```
### Three.js Vector3 pool (game loop)
```typescript
import { Vector3 } from 'three';
const vec3Pool = new ObjectPool<Vector3>(
() => new Vector3(),
(v) => v.set(0, 0, 0),
256
);
function updateBullet(b: Bullet, dt: number) {
const tmp = vec3Pool.acquire();
tmp.copy(b.velocity).multiplyScalar(dt);
b.position.add(tmp);
vec3Pool.release(tmp);
}
```
### Particle system pool
```typescript
class Particle {
position = new Vector3();
velocity = new Vector3();
life = 0;
active = false;
}
class ParticleSystem {
private pool: Particle[];
private active: Particle[] = [];
constructor(maxParticles: number) {
this.pool = Array.from({ length: maxParticles }, () => new Particle());
}
spawn(pos: Vector3, vel: Vector3, life: number) {
const p = this.pool.pop();
if (!p) return; // pool exhausted
p.position.copy(pos);
p.velocity.copy(vel);
p.life = life;
p.active = true;
this.active.push(p);
}
update(dt: number) {
for (let i = this.active.length - 1; i >= 0; i--) {
const p = this.active[i];
p.life -= dt;
if (p.life <= 0) {
p.active = false;
this.active.splice(i, 1);
this.pool.push(p); // return to pool
} else {
p.position.addScaledVector(p.velocity, dt);
}
}
}
}
```
### DB connection pool (pg)
```typescript
import { Pool } from 'pg';
const pool = new Pool({
max: 20,
idleTimeoutMillis: 30_000,
connectionTimeoutMillis: 2000,
});
async function query(sql: string, params: unknown[]) {
const client = await pool.connect();
try {
return await client.query(sql, params);
} finally {
client.release(); // ← back to pool
}
}
```
### Worker thread pool (piscina)
```typescript
import Piscina from 'piscina';
const piscina = new Piscina({
filename: new URL('./worker.js', import.meta.url).href,
minThreads: 2,
maxThreads: 8,
});
const result = await piscina.run({ payload: data });
```
### Bounded pool with backpressure
```typescript
class BoundedPool<T> {
private free: T[] = [];
private waiters: ((obj: T) => void)[] = [];
private created = 0;
constructor(
private factory: () => T,
private reset: (obj: T) => void,
private max: number
) {}
async acquire(): Promise<T> {
if (this.free.length) return this.free.pop()!;
if (this.created < this.max) {
this.created++;
return this.factory();
}
return new Promise((resolve) => this.waiters.push(resolve));
}
release(obj: T): void {
this.reset(obj);
const w = this.waiters.shift();
if (w) w(obj);
else this.free.push(obj);
}
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Hot path allocation (game loop) | object pool (generic) |
| DB / network connection | bounded pool with backpressure |
| Heavy CPU task | worker thread pool (piscina) |
| Short-lived simple obj (< 1KB) | 매 V8 의 young-gen GC 의 충분 — pool 의 X |
| Object 의 reset cost > construct cost | pool 의 X |
**기본값**: 매 profile 후 의 적용 — premature pooling 의 X.
## 🔗 Graph
- 부모: [[Garbage Collection]] · [[V8 엔진 힙 아키텍처]]
- 변형: [[bitECS와 SharedArrayBuffer를 결합한 멀티스레드 고성능 아키텍처]]
- 응용: [[InstancedMesh 최적화]] · [[가변적 LOD(Level of Detail) 시스템]]
- Adjacent: [[Old_Space|Old Space]] · [[세대 가설(Generational Hypothesis)]]
## 🤖 LLM 활용
**언제**: game loop / real-time pipeline 의 GC pause 회피, expensive resource (DB conn, GPU buffer) 의 reuse.
**언제 X**: simple short-lived object — 매 modern GC 의 충분.
## ❌ 안티패턴
- **Reset 의 누락**: 매 stale state 의 leak — 매 security risk (sensitive data).
- **Unbounded pool**: 매 memory leak — 매 max size 의 강제.
- **Pool 의 lock contention**: 매 multi-thread 의 sync overhead — thread-local pool 의 고려.
- **Object 의 over-aliasing**: 매 release 후 의 reference 유지 — use-after-free 의 bug.
## 🧪 검증 / 중복
- Verified (Game Programming Patterns / R. Nystrom, V8 blog, piscina docs).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — TS generic pool, Three.js, piscina 패턴 추가 |
@@ -0,0 +1,135 @@
---
id: wiki-2026-0508-orinoco-프로젝트
title: Orinoco 프로젝트
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Orinoco, V8 Orinoco]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [v8, gc, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: C++
framework: V8 12+
---
# Orinoco 프로젝트
## 매 한 줄
> **"매 V8 의 GC 의 mostly-parallel, mostly-concurrent 의 evolution"**. 2016 발표된 Orinoco initiative 가 V8 의 stop-the-world phase 를 minimize — incremental marking, parallel scavenge, concurrent sweeping, compaction 의 background offload. 2026 현재 V8 12+ 의 default. Main thread pause time 이 100ms+ → sub-10ms 로 reduce.
## 매 핵심
### 매 design pillars
- **Parallelism**: 동시 main thread 를 멈추고 worker thread 다수 사용 (parallel scavenge, parallel compaction).
- **Concurrency**: main thread 는 mutator 의 user code 실행, GC thread 가 background marking/sweeping.
- **Incremental**: long pause 를 작은 step 으로 split, frame 사이 의 짤끔.
- **Idle-time GC**: main thread idle window (rAF gap) 의 활용.
### 매 collector phases
- **Young (Scavenger)**: parallel copying, 보통 <1ms.
- **Old marking**: incremental + concurrent (mutator 동시 실행).
- **Old sweeping**: concurrent free-list rebuild.
- **Old compaction**: parallel evacuation, 매 page-level.
- **Write barrier**: 매 mutator 가 mark 와 race 의 prevent.
### 매 응용
1. Chrome / Edge / Brave (V8 host).
2. Node.js / Deno / Bun (runtime GC 의 같은 Orinoco 기반, Bun 은 JSC 라 다름).
3. Electron, VS Code (V8 backend).
## 💻 패턴
### Orinoco trace 보기
```bash
node --trace-gc --trace-gc-verbose app.js
# [Mark-Compact (incremental) ...]
# [Scavenge (parallel) ...]
```
### Heap stats with v8 module
```javascript
const v8 = require('v8')
const stats = v8.getHeapStatistics()
console.log({
used: stats.used_heap_size,
total: stats.total_heap_size,
limit: stats.heap_size_limit,
})
const spaces = v8.getHeapSpaceStatistics()
spaces.forEach(s => console.log(s.space_name, s.space_used_size))
```
### Triggering Orinoco-friendly allocation
```javascript
// O — short-lived 의 young space 에 머무름
function processBatch(items) {
return items.map(i => ({ id: i.id, val: i.val * 2 })) // returns die fast
}
// X — large pre-allocated buffer 의 old promotion 강제
const giant = new Array(1e7).fill(0) // bypasses young entirely
```
### --max-old-space-size tuning
```bash
node --max-old-space-size=4096 app.js # 4GB old space ceiling
```
### Idle-time GC hint
```javascript
// Chrome internal — webpages cannot directly trigger,
// but rAF-aligned work 의 GC 가 idle gap 을 활용
requestIdleCallback((deadline) => {
while (deadline.timeRemaining() > 0 && tasks.length) doWork(tasks.pop())
})
```
### Heap snapshot diff
```javascript
const v8 = require('v8'); const fs = require('fs')
v8.writeHeapSnapshot('before.heapsnapshot')
runWorkload()
v8.writeHeapSnapshot('after.heapsnapshot')
// Chrome DevTools → Memory → Comparison
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Browser frame budget (16.6ms) | Orinoco 의 default 충분 |
| Large heap (4GB+) | --max-old-space-size + monitoring |
| Latency-critical (game, RT) | Object pool + young-friendly allocation |
| Server long-running | --gc-interval + heap dump 주기 |
**기본값**: 매 V8 default Orinoco + workload 의 short-lived bias.
## 🔗 Graph
- 부모: [[V8 엔진 힙 아키텍처]]
- 변형: [[Orinoco 가비지 컬렉터]]
- 응용: [[Incremental_Marking|Incremental Marking]] · [[Mark-Sweep-Compact 알고리즘]]
- Adjacent: [[Garbage Collection|Generational Hypothesis]] · [[Old_Space|Old Space]] · [[Write Barrier]]
## 🤖 LLM 활용
**언제**: V8 GC 의 internals 설명, Node.js / Chrome heap tuning, `--trace-gc` 분석.
**언제 X**: 다른 engine (JSC, SpiderMonkey, Hermes) 의 GC.
## ❌ 안티패턴
- **`global.gc()` 강제**: 매 production 의 X. Orinoco 가 의 better job 의 함.
- **--expose-gc 의 production**: 매 attack surface 와 perf degradation.
- **Heavy sync work**: incremental marking 의 main thread 가 idle 해야 진행 → tight loop 의 GC 의 starve.
## 🧪 검증 / 중복
- Verified (V8 blog "Orinoco" 2016, "Concurrent marking" 2017, V8 12.x release notes).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Orinoco design pillars + tracing patterns |
@@ -0,0 +1,181 @@
---
id: wiki-2026-0508-result-type
title: Result Type
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Result, Either, Outcome]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [error-handling, types, functional]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript/Rust
framework: neverthrow/Effect TS/std::result
---
# Result Type
## 매 한 줄
> **"매 error 를 value 로 만들어 type system 이 강제 handle 하게 함"**. Rust 의 `Result<T, E>`, Haskell `Either e a`, OCaml `result`, Swift `Result` 가 origin. TypeScript ecosystem 에서 매 neverthrow, Effect TS, ts-results 가 mainstream. 매 throw/catch 의 invisible control flow 와 unsafe error 의 alternative.
## 매 핵심
### 매 motivation
- Exception 은 type signature 에 안 보임 → 매 caller 가 forget 가능.
- `Result<T, E>` 는 매 return type 에 explicit → handle X 면 type error.
- 매 functional composition 에 friendly (map, andThen, mapErr).
### 매 ADT shape
- `Ok(T)` | `Err(E)` — 매 두 variant 의 sum type.
- `unwrap`, `unwrap_or`, `map`, `andThen` (flatMap), `match`.
### 매 응용
1. Validation pipeline (parse → transform → save).
2. Network call wrapping (fetch, DB query).
3. Domain error modeling (NotFound, Unauthorized, Conflict).
4. Recoverable failure (vs panic / unrecoverable).
## 💻 패턴
### TypeScript discriminated union
```typescript
type Result<T, E = Error> =
| { ok: true; value: T }
| { ok: false; error: E }
const ok = <T,>(value: T): Result<T, never> => ({ ok: true, value })
const err = <E,>(error: E): Result<never, E> => ({ ok: false, error })
function parseAge(s: string): Result<number, 'NaN' | 'Negative'> {
const n = Number(s)
if (Number.isNaN(n)) return err('NaN')
if (n < 0) return err('Negative')
return ok(n)
}
const r = parseAge('42')
if (r.ok) console.log(r.value)
else console.error(r.error)
```
### neverthrow library
```typescript
import { Result, ok, err, ResultAsync } from 'neverthrow'
const fetchUser = (id: string): ResultAsync<User, 'NotFound' | 'Network'> =>
ResultAsync.fromPromise(
fetch(`/api/users/${id}`).then(r => r.ok ? r.json() : Promise.reject('NotFound')),
(e): 'NotFound' | 'Network' => e === 'NotFound' ? 'NotFound' : 'Network',
)
await fetchUser('u1')
.map(u => u.email)
.mapErr(e => `failed: ${e}`)
.match(
email => console.log(email),
err => console.error(err),
)
```
### Effect TS (richer)
```typescript
import { Effect, pipe } from 'effect'
const parseJSON = (s: string) =>
Effect.try({
try: () => JSON.parse(s),
catch: () => new Error('InvalidJSON'),
})
const program = pipe(
parseJSON('{"x":1}'),
Effect.map((o: { x: number }) => o.x * 2),
Effect.catchAll(e => Effect.succeed(0)),
)
Effect.runPromise(program).then(console.log) // 2
```
### Rust (canonical)
```rust
fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
if b == 0 { Err("division by zero") } else { Ok(a / b) }
}
fn pipeline() -> Result<i32, &'static str> {
let x = divide(10, 2)?; // ? propagates Err
let y = divide(x, 0)?;
Ok(y)
}
```
### Validation accumulation (multiple errors)
```typescript
type Validated<T, E> = { ok: true; value: T } | { ok: false; errors: E[] }
const combine = <T, E>(rs: Result<T, E>[]): Validated<T[], E> => {
const errs: E[] = []
const vals: T[] = []
for (const r of rs) r.ok ? vals.push(r.value) : errs.push(r.error)
return errs.length ? { ok: false, errors: errs } : { ok: true, value: vals }
}
```
### Match helper
```typescript
function match<T, E, R>(r: Result<T, E>, on: { ok: (v: T) => R; err: (e: E) => R }): R {
return r.ok ? on.ok(r.value) : on.err(r.error)
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Recoverable error, type-safety 중요 | Result type |
| Truly unrecoverable (bug, OOM) | throw / panic |
| Multiple errors 누적 | Validated / Either with NonEmptyArray |
| Async + retry + interrupt | Effect TS |
| Simple library, no dep | hand-rolled discriminated union |
| Existing throw-based API | wrap with try/catch → Result |
**기본값**: 매 domain layer 는 Result, infrastructure boundary 에서 unwrap → throw 변환.
## 🔗 Graph
- 부모: [[Error Handling]] · [[Discriminated_Unions|Discriminated Unions]]
- 변형: [[Effect TS]]
- 응용: [[Zod 런타임 유효성 검사 통합]] · [[API 응답 및 에러 핸들링 아키텍처]]
- Adjacent: [[Type Theory]] · [[Functional Programming]]
## 🤖 LLM 활용
**언제**: 매 explicit error path, validation pipeline, FP-style composition, "this can fail" type-level documentation.
**언제 X**: 매 trivial script, throw 가 더 idiomatic 한 case (e.g. assertion, programmer error).
## ❌ 안티패턴
- **`unwrap()` 의 production**: 매 `Result` 의 의도 의 부정. 매 explicit `match` / `mapErr`.
- **`Result<T, Error>` 의 generic**: 매 specific tagged union (`'NotFound' | 'Conflict'`) 가 useful.
- **Mixed throw + Result**: layer 의 inconsistent → caller 의 confusing. 매 boundary 의 명확.
- **Async 에 raw Promise<Result>**: rejection 도 발생 → 매 ResultAsync / Effect 가 안전.
## 🧪 검증 / 중복
- Verified (Rust std::result docs, neverthrow README, Effect TS docs 3.x, "Domain Modeling Made Functional" Wlaschin).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Result patterns (TS, neverthrow, Effect, Rust) |
## 🛠️ 적용 사례 (Applied in summary)
<!-- CODE-GROUNDING:START -->
### 🔎 코드베이스 근거 (자동 추출 — E:\Wiki 레포)
**실제 구현/사용 위치:**
- `connectai/src/core/dataProcessor.ts:2` — * Aggregate result type definition
_자동 생성: code_grounding.mjs · 재실행 시 갱신됨_
<!-- CODE-GROUNDING:END -->
@@ -0,0 +1,125 @@
---
id: wiki-2026-0508-scheduler-api
title: Scheduler API
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [scheduler.postTask, Prioritized Task Scheduling]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [web, performance, scheduling, browser-api]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript
framework: Web Platform
---
# Scheduler API
## 매 한 줄
> **"매 priority-aware task scheduling for the main thread"**. Scheduler API (`scheduler.postTask`, `scheduler.yield`) 는 long task breakup + priority hint (user-blocking / user-visible / background) 로 INP/responsiveness 최적화. 2026 Chromium + Firefox stable.
## 매 핵심
### 매 Priorities
- `user-blocking`: 매 immediate UI response (input handler post-work).
- `user-visible`: 매 default — visible 하지만 non-blocking.
- `background`: 매 lazy work (analytics, prefetch).
### 매 vs setTimeout(0) / requestIdleCallback
- 매 setTimeout(0): no priority, no abort.
- 매 rIC: idle only, deadline-based.
- 매 postTask: explicit priority + AbortSignal + delay.
### 매 응용
1. 매 long list rendering 분할.
2. 매 input handler 후 heavy work 양보.
3. 매 background data prefetch.
## 💻 패턴
### postTask 기본
```js
scheduler.postTask(() => doWork(), { priority: 'background' });
```
### scheduler.yield (long task breakup)
```js
async function processItems(items) {
for (const item of items) {
process(item);
if (navigator.scheduling?.isInputPending?.() || items.indexOf(item) % 50 === 0) {
await scheduler.yield();
}
}
}
```
### TaskController로 abort
```js
const controller = new TaskController({ priority: 'user-visible' });
scheduler.postTask(longJob, { signal: controller.signal });
// 매 cancel
controller.abort();
// 매 priority 동적 변경
controller.setPriority('background');
```
### Delay
```js
scheduler.postTask(refresh, { priority: 'background', delay: 5000 });
```
### Polyfill fallback
```js
const yield_ = () =>
globalThis.scheduler?.yield?.() ??
new Promise(r => setTimeout(r, 0));
```
### React + Scheduler API
```js
// React 19+ 의 useTransition + scheduler integration
startTransition(() => {
scheduler.postTask(() => setState(heavy), { priority: 'background' });
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Heavy work after input | `scheduler.yield()` mid-loop |
| Lazy prefetch | `postTask({priority:'background'})` |
| Cancel-able task | `TaskController` |
| Idle-only callback | `requestIdleCallback` |
| 매 simple deferral | `queueMicrotask` |
**기본값**: 매 long loops 의 `scheduler.yield()` + 매 background work `postTask({priority:'background'})`.
## 🔗 Graph
- 부모: [[Core Web Vitals Optimization (INP, LCP, CLS)|Core_Web_Vitals]]
- 응용: [[INP_Optimization]]
- Adjacent: [[AbortController]] · [[React_useTransition]]
## 🤖 LLM 활용
**언제**: 매 INP regression 발견 + 매 long task (>50ms) breakup 필요 시. 매 prioritized background work.
**언제 X**: 매 worker offload 가 더 적합한 CPU-heavy work, 또는 매 framework scheduler (React) 가 이미 처리.
## ❌ 안티패턴
- **postTask 안 yield**: 매 single long callback 은 여전히 long task. 매 internally yield 필요.
- **user-blocking 남용**: 매 priority inversion 의. 매 진짜 input-critical 만.
- **Polyfill 없는 production deploy**: 매 Safari 일부 버전 미지원.
## 🧪 검증 / 중복
- Verified (W3C Prioritized Task Scheduling, web.dev/optimize-inp).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — postTask + yield patterns |
@@ -0,0 +1,180 @@
---
id: wiki-2026-0508-server-architecture
title: Server Architecture
category: 10_Wiki/Topics
aliases: [서버 아키텍처, Backend Architecture]
status: verified
canonical_id: self
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, backend, distributed-systems, scalability]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: polyglot
framework: cloud-native
---
# Server Architecture
## 매 한 줄
> **"매 architecture 는 trade-off 의 명시화"**. Monolith → Modular monolith → Service-oriented → Microservices → Cells/Serverless 의 spectrum 에서 팀 규모, 도메인 복잡도, scale 요구에 맞춰 선택. 2026 현재 majority 는 modular monolith + targeted services.
## 매 핵심
### 매 layer
- **Edge**: CDN (Cloudflare, Fastly), DDoS, TLS termination.
- **Gateway**: API gateway, authn, rate limit (Kong, Envoy, AWS API GW).
- **Application**: stateless service tier (horizontal scale).
- **Data**: OLTP DB, cache, search, object store, queue.
- **Async**: message broker (Kafka, NATS, SQS), workers.
- **Observability**: traces (OTel), metrics (Prom), logs.
### 매 archetype
- **Monolith**: 단일 deploy unit — 작은 팀, 빠른 iteration.
- **Modular monolith**: bounded context 명확, 단일 배포 — 2026 default.
- **Microservices**: 팀당 service, 독립 배포 — Conway's law 정렬 시.
- **Cells**: bulkhead 별 독립 stack — high-availability.
- **Serverless**: Lambda/CF Workers — bursty, low-traffic OK.
### 매 응용
1. SaaS multi-tenant.
2. E-commerce platform.
3. Real-time messaging.
## 💻 패턴
### 1. Stateless service + sticky data
```yaml
# k8s deployment
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 6
template:
spec:
containers:
- name: api
image: app:v1.42
readinessProbe:
httpGet: { path: /ready, port: 8080 }
resources:
requests: { cpu: 250m, memory: 512Mi }
limits: { cpu: 1, memory: 1Gi }
```
### 2. CQRS read replica fan-out
```typescript
class OrderService {
constructor(private writeDb: Pool, private readDb: Pool) {}
async create(o: Order) {
return this.writeDb.tx(async (tx) => {
await tx.insert("orders", o);
await tx.publish("order.created", o);
});
}
async query(userId: string) {
return this.readDb.query("SELECT * FROM orders_view WHERE user_id=$1", [userId]);
}
}
```
### 3. Circuit breaker
```typescript
import CircuitBreaker from "opossum";
const breaker = new CircuitBreaker(callPaymentApi, {
timeout: 3000,
errorThresholdPercentage: 50,
resetTimeout: 30_000,
});
breaker.fallback(() => ({ status: "queued" }));
```
### 4. Outbox pattern
```sql
BEGIN;
INSERT INTO orders (...) VALUES (...);
INSERT INTO outbox (topic, payload) VALUES ('order.created', $1);
COMMIT;
-- separate poller publishes outbox → kafka, then deletes
```
### 5. Backpressure with bounded queue
```go
sem := make(chan struct{}, 100) // max 100 in-flight
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
select {
case sem <- struct{}{}:
defer func() { <-sem }()
handle(w, r)
default:
http.Error(w, "busy", 503)
}
})
```
### 6. Cell-based isolation
```
Customer A → Cell-1 (LB, app, DB shard)
Customer B → Cell-2 (LB, app, DB shard)
Customer C → Cell-1
# Cell failure blast radius = 1 cell only
```
### 7. SLO-based deploy gate
```yaml
# Argo Rollouts
strategy:
canary:
steps:
- setWeight: 10
- analysis:
templates: [{ templateName: error-rate-slo }]
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 100
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 팀 < 20명, 단일 도메인 | Modular monolith |
| 팀 > 50명, 다 도메인 | Microservices (bounded context별) |
| Bursty traffic, 0 → 1000 RPS | Serverless |
| Multi-tenant, blast radius 우려 | Cells |
| Strong consistency 핵심 | Single-writer + read replicas |
| Eventual OK, throughput 핵심 | Event-driven + CQRS |
**기본값**: modular monolith + Postgres + Redis + 1-2 async workers. 명확히 필요할 때 split.
## 🔗 Graph
- 부모: [[Distributed Systems]] · [[Cloud Native]]
- 변형: [[Microservices]] · [[Serverless]] · [[Event-Driven Architecture]]
- Adjacent: [[Kubernetes]] · [[Service Mesh]] · [[Observability]]
## 🤖 LLM 활용
**언제**: 신규 시스템 설계, scale 병목 분석, monolith → service split 시점 판단.
**언제 X**: 작은 internal tool (overengineering 위험), prototype (속도 우선).
## ❌ 안티패턴
- **Distributed monolith**: 서비스 분리 + 동기 호출 chain — latency, 장애 전파.
- **Premature microservices**: 팀 < 10명에 서비스 20개 — ops 폭발.
- **Shared DB across services**: coupling, schema migration 지옥.
- **No observability**: 분산 시 trace 없으면 디버깅 불가.
- **Synchronous everything**: queue/event 활용 안 하면 cascading failure.
## 🧪 검증 / 중복
- Verified (AWS Well-Architected, Google SRE book, Sam Newman "Building Microservices").
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — server architecture archetypes & patterns (2026 cloud-native) |
@@ -0,0 +1,151 @@
---
id: wiki-2026-0508-sharedarraybuffer로-스레드-간-메모리-공유-
title: SharedArrayBuffer로 스레드 간 메모리 공유 효율 높이기
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [SAB, SharedArrayBuffer, Shared Memory JS]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [javascript, web-worker, concurrency, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript
framework: Web Workers
---
# SharedArrayBuffer로 스레드 간 메모리 공유 효율 높이기
## 매 한 줄
> **"매 zero-copy shared memory between JS threads"**. SharedArrayBuffer (SAB) 는 main thread + Web Worker 간 동일 raw bytes 를 공유. postMessage structured clone 의 copy 비용 제거 + Atomics 로 race-free coordination 가능.
## 매 핵심
### 매 동작 모델
- 매 buffer instance 는 multiple threads 에서 동일 backing store 참조.
- 매 TypedArray view (Int32Array, Float64Array) 로 typed access.
- 매 Atomics.load/store/add 로 atomic ops.
- 매 Atomics.wait/notify 로 futex-like blocking sync.
### 매 vs ArrayBuffer
- 매 ArrayBuffer: postMessage 시 structured clone (copy) 또는 transfer (ownership move).
- 매 SharedArrayBuffer: postMessage 시 reference 전달, 양쪽 동시 access.
### 매 응용
1. WASM linear memory 공유 (multi-threaded WASM).
2. 매 large image/audio buffer worker 처리 (zero-copy).
3. Lock-free queue / ring buffer 구현.
## 💻 패턴
### Worker 에 SAB 전달
```js
// main.js
const sab = new SharedArrayBuffer(1024);
const view = new Int32Array(sab);
const worker = new Worker('worker.js');
worker.postMessage({ sab });
// worker.js
self.onmessage = ({ data }) => {
const view = new Int32Array(data.sab);
Atomics.store(view, 0, 42);
Atomics.notify(view, 0, 1);
};
```
### Atomic counter
```js
const sab = new SharedArrayBuffer(4);
const counter = new Int32Array(sab);
Atomics.add(counter, 0, 1); // race-free increment
const value = Atomics.load(counter, 0);
```
### Producer / Consumer wait+notify
```js
// consumer
Atomics.wait(view, 0, 0); // sleep until view[0] != 0
const data = Atomics.load(view, 0);
// producer
Atomics.store(view, 0, 99);
Atomics.notify(view, 0, 1); // wake 1 waiter
```
### Lock (spinlock)
```js
function lock(view, idx) {
while (Atomics.compareExchange(view, idx, 0, 1) !== 0) {
Atomics.wait(view, idx, 1);
}
}
function unlock(view, idx) {
Atomics.store(view, idx, 0);
Atomics.notify(view, idx, 1);
}
```
### Ring buffer (lock-free SPSC)
```js
class RingBuffer {
constructor(sab, capacity) {
this.head = new Int32Array(sab, 0, 1);
this.tail = new Int32Array(sab, 4, 1);
this.data = new Int32Array(sab, 8, capacity);
this.cap = capacity;
}
push(v) {
const t = Atomics.load(this.tail, 0);
const next = (t + 1) % this.cap;
if (next === Atomics.load(this.head, 0)) return false; // full
this.data[t] = v;
Atomics.store(this.tail, 0, next);
return true;
}
}
```
### WASM threads memory
```js
const memory = new WebAssembly.Memory({ initial: 10, maximum: 100, shared: true });
// memory.buffer is SharedArrayBuffer
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Small data, infrequent | postMessage (clone) |
| Large buffer, hot path | SAB + Atomics |
| Transfer ownership once | postMessage with transfer list |
| Multi-threaded WASM | shared:true Memory |
**기본값**: 매 small data postMessage, 매 hot-path large buffer SAB.
## 🔗 Graph
- 변형: [[SharedArrayBuffer_보안_이슈와_Cross-Origin_Isolation]]
- 응용: [[OffscreenCanvas]]
- Adjacent: [[Structured_Clone]]
## 🤖 LLM 활용
**언제**: 매 large data parallel processing (image/video/ML inference) 의 + 매 worker 간 frequent sync 필요 시.
**언제 X**: 매 simple task offload (postMessage 충분) 또는 매 COOP/COEP 헤더 설정 불가능한 환경.
## ❌ 안티패턴
- **Non-atomic access on shared view**: 매 race condition. 매 always Atomics.* 사용.
- **Spin without wait**: 매 CPU burn. 매 Atomics.wait 으로 block.
- **Missing COOP/COEP**: 매 modern browser 에서 SAB 비활성화. 매 cross-origin isolation 필수.
## 🧪 검증 / 중복
- Verified (MDN SharedArrayBuffer, ECMAScript Atomics spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — SAB + Atomics patterns |
@@ -0,0 +1,151 @@
---
id: wiki-2026-0508-structural-typing
title: Structural Typing
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [duck typing, shape typing, structural type system]
duplicate_of: none
source_trust_level: A
confidence_score: 0.93
verification_status: applied
tags: [typescript, type-system, fundamentals]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: tsc
---
# Structural Typing
## 매 한 줄
> **"매 type 의 compatibility 의 name 이 아닌 shape 으로 결정"**. TypeScript / Go 의 핵심 — 매 nominal typing (Java / C#) 의 반대. 매 2026 TS 5.7 의 동일 원칙 — 매 modern web 의 fundamental.
## 매 핵심
### 매 Nominal vs Structural
- **Nominal** (Java/C#): 매 declared name 의 일치 — 매 같은 shape 라도 다른 type 시 incompatible.
- **Structural** (TS/Go): 매 properties / methods 의 shape 의 match 의 compatible — 매 declaration site 의 무관.
### 매 동작 원리
- 매 assignability check: 매 source type 의 모든 required member 의 target type 의 존재 의 확인.
- 매 method signature: 매 parameter 의 contravariant, return 의 covariant.
- 매 excess property checking: 매 object literal 의 special case — 매 추가 property 의 error.
### 매 응용
1. 매 function parameter 의 minimal interface 의 require — 매 flexibility.
2. 매 mock / stub 의 작성 의 자연스러움 — 매 test 의 친화.
3. 매 ad-hoc type 의 inline definition.
## 💻 패턴
### 매 Structural 의 기본
```typescript
interface Point { x: number; y: number; }
class Vector { constructor(public x: number, public y: number) {} }
function dist(p: Point): number {
return Math.sqrt(p.x ** 2 + p.y ** 2);
}
dist(new Vector(3, 4)); // OK — 매 Vector 의 Point shape 의 satisfy
dist({ x: 3, y: 4 }); // OK — 매 object literal 의 동일
```
### 매 Branded type 의 nominal 의 흉내
```typescript
// 매 structural 의 약점 — 매 같은 shape 의 다른 의미 의 mix
type UserId = string & { __brand: 'UserId' };
type OrderId = string & { __brand: 'OrderId' };
function getUser(id: UserId) { /* ... */ }
const oid = 'order-1' as OrderId;
// getUser(oid); // 매 ERROR — 매 brand 의 mismatch
```
### 매 Function 의 contravariance
```typescript
type Logger = (msg: string) => void;
const wide: (msg: string | number) => void = (m) => console.log(m);
const log: Logger = wide; // OK — 매 parameter 의 contravariant
// 매 wide 의 string 도 number 도 받으므로 string-only 의 substitute 가능
```
### 매 Excess property checking 의 우회
```typescript
interface Config { url: string; }
// declareConfig({ url: '/api', timeout: 5000 }); // ERROR — 매 excess
const cfg = { url: '/api', timeout: 5000 };
declareConfig(cfg); // OK — 매 variable 의 우회 (매 fresh literal 만 check)
function declareConfig(c: Config) { /* ... */ }
```
### 매 Subtyping 의 자동
```typescript
interface Animal { name: string; }
interface Dog { name: string; bark(): void; }
const dogs: Dog[] = [{ name: 'Rex', bark: () => {} }];
const animals: Animal[] = dogs; // OK — 매 Dog 의 superset 의 자동 subtype
```
### 매 Class 의 structural 의 trap
```typescript
class Cat { meow() {} }
class Lion { meow() {} }
const c: Cat = new Lion(); // OK?? — 매 동일 shape 의 compatible
// 매 nominal 기대 시 private field 의 brand 의 사용
class CatN { #species = 'cat'; meow() {} }
class LionN { #species = 'lion'; meow() {} }
// 매 #private 의 nominal effect — 매 cross-class 의 incompatible
```
### 매 Generic 의 structural 의 활용
```typescript
function pluck<T, K extends keyof T>(arr: T[], key: K): T[K][] {
return arr.map(x => x[key]);
}
// 매 T 의 shape 의 자유 — 매 keyof T 의 structural inference
const names = pluck([{ name: 'a' }, { name: 'b' }], 'name');
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 일반 type | structural (default) — 매 TS 의 native |
| Domain ID 의 mix 방지 | branded type |
| Strict nominal 필요 | private field / unique symbol brand |
| External library compat | structural — 매 자연스러운 fit |
**기본값**: structural typing 의 활용. 매 ID confusion 의 risk 시 branded type 의 추가.
## 🔗 Graph
- 부모: [[TypeScript]] · [[TypeScript 타입 시스템 (TypeScript Type System)|Type System]]
- 변형: [[Nominal-Typing-in-TypeScript|Nominal Typing]] · [[Duck Typing]]
- 응용: [[Excess_Property_Checking|Excess Property Checking]] · [[ts-brand]]
- Adjacent: [[Discriminated_Unions|Discriminated Unions]] · [[Type Casting]]
## 🤖 LLM 활용
**언제**: TS type error 의 explain, branded type 의 권장, structural vs nominal 의 비교.
**언제 X**: Java/C# 같은 nominal 언어 의 답변 의 mix — 매 언어 의 명시.
## ❌ 안티패턴
- **ID confusion**: 매 UserId / OrderId 의 같은 string — 매 brand 의 추가.
- **Class identity 의 의존**: 매 instanceof 없이 type 만 의 distinguish — 매 trap.
- **Excess 의 silence**: 매 변수 거쳐 우회 후 typo 의 미발견.
## 🧪 검증 / 중복
- Verified (TypeScript Handbook, "Type Compatibility").
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Structural typing FULL 작성 |
@@ -0,0 +1,158 @@
---
id: wiki-2026-0508-teamcity
title: TeamCity
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [JetBrains TeamCity, TC]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [ci-cd, jetbrains, build, devops]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Kotlin DSL
framework: TeamCity 2025.x
---
# TeamCity
## 매 한 줄
> **"매 enterprise CI server with first-class build chains + Kotlin DSL config"**. JetBrains TeamCity 는 build configuration 의 strong dependency graph + snapshot/artifact dep + 매 versioned settings (Kotlin DSL) 를 제공하는 self-hosted CI. 2026 의 TeamCity 2025.x 는 cloud agents + GitHub Actions 호환성 + native AI test analytics.
## 매 핵심
### 매 핵심 개념
- **Project / Build Configuration / Build**: 3-tier hierarchy.
- **Snapshot dependency**: 매 동일 VCS revision 보장된 build chain.
- **Artifact dependency**: 매 upstream artifact pull.
- **Build chain**: composite build (status rollup).
- **Versioned settings**: 매 Kotlin DSL `.teamcity/settings.kts` git 관리.
### 매 vs Jenkins / GitHub Actions
- 매 Jenkins: plugin sprawl, 매 declarative 선택적.
- 매 GitHub Actions: SaaS-first, 매 enterprise 의 self-host 약함.
- 매 TeamCity: 매 enterprise self-host + Kotlin DSL + 매 strong test history.
### 매 응용
1. JVM monorepo (Gradle/Maven) build chain.
2. .NET / Kotlin Multiplatform CI.
3. Hybrid cloud agents (AWS/GCP/K8s) + on-prem.
## 💻 패턴
### Kotlin DSL 의 build config
```kotlin
import jetbrains.buildServer.configs.kotlin.*
import jetbrains.buildServer.configs.kotlin.buildSteps.gradle
object Build : BuildType({
name = "Build & Test"
vcs { root(DslContext.settingsRoot) }
steps {
gradle {
tasks = "clean build"
useGradleWrapper = true
}
}
triggers { vcs {} }
features {
perfmon {}
}
})
```
### Build chain (snapshot dep)
```kotlin
object Deploy : BuildType({
name = "Deploy"
dependencies {
snapshot(Build) { onDependencyFailure = FailureAction.FAIL_TO_START }
artifacts(Build) { artifactRules = "build/libs/*.jar => libs" }
}
})
```
### Parameter + secret
```kotlin
params {
param("env.NODE_ENV", "production")
password("env.NPM_TOKEN", "credentialsJSON:...")
}
```
### Agent requirements
```kotlin
requirements {
contains("teamcity.agent.jvm.os.name", "Linux")
exists("env.DOCKER_HOST")
}
```
### Matrix-style (composite build)
```kotlin
object Matrix : BuildType({ name = "All Platforms"; type = Type.COMPOSITE
dependencies {
snapshot(BuildLinux) {}
snapshot(BuildMac) {}
snapshot(BuildWin) {}
}
})
```
### REST API trigger
```bash
curl -u user:token -X POST \
-H "Content-Type: application/xml" \
-d '<build><buildType id="Build"/></build>' \
https://tc.example.com/app/rest/buildQueue
```
### Cloud agent profile (Kubernetes)
```kotlin
features {
feature {
type = "CloudImage"
param("cloud-code", "kubernetes")
param("image-name", "myorg/tc-agent:2025")
}
}
```
## 매 결정 기준
| 상황 | CI choice |
|---|---|
| 매 JVM enterprise self-host | TeamCity |
| 매 GitHub-centric OSS | GitHub Actions |
| 매 plugin-heavy legacy | Jenkins |
| 매 GitLab-native | GitLab CI |
| 매 monorepo with cache focus | Buildkite / Bazel CI |
**기본값**: 매 enterprise JVM/.NET 의 TeamCity, 매 OSS GitHub repo 의 Actions.
## 🔗 Graph
- 부모: [[CI_CD_Pipeline|CI_CD]]
- 변형: [[GitHub_Actions]]
## 🤖 LLM 활용
**언제**: 매 enterprise CI 설계, 매 build chain 의존성 모델링, 매 Kotlin DSL 마이그레이션.
**언제 X**: 매 single-repo OSS — 매 GitHub Actions 가 zero-ops.
## ❌ 안티패턴
- **UI-only config (no DSL)**: 매 settings drift, 매 review 불가능.
- **Snapshot dep 없이 chain**: 매 inconsistent revision.
- **Agent 의 secret 평문 저장**: 매 Token credentials 사용 필수.
- **Build history retention 무한**: 매 server 디스크 폭발.
## 🧪 검증 / 중복
- Verified (JetBrains TeamCity 2025 docs, Kotlin DSL guide).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — TeamCity 2025 + Kotlin DSL |
@@ -0,0 +1,162 @@
---
id: wiki-2026-0508-type-theory
title: Type Theory
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Type System Theory, Lambda Calculus Types, Curry-Howard]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [type-theory, lambda-calculus, formal-methods, curry-howard, dependent-types]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Haskell / Idris / Lean / Coq
framework: theoretical
---
# Type Theory
## 매 한 줄
> **"매 타입은 명제, 매 프로그램은 증명 — Curry-Howard correspondence"**. Type theory 는 1902 Russell paradox 회피용 simple type theory 부터, 1934 Church 의 simply typed lambda calculus, 1972 Martin-Löf dependent type theory, 2026 Lean 4 / Idris 2 / Rocq (formerly Coq) 의 매 mathematical proof + program verification 의 통일 framework. 매 modern type system (Haskell, Rust, TypeScript) 의 매 핵심 개념 (parametric polymorphism, GADTs, refinement types) 의 출처.
## 매 핵심
### 매 type theory 의 계층
- **Simply Typed Lambda Calculus (STLC)**: `τ ::= ι | τ → τ` — function types only.
- **System F (parametric polymorphism)**: `∀α. τ` — generics 의 이론적 기반.
- **System Fω (type operators)**: `* → *` kinds — Haskell 의 type-level computation.
- **Calculus of Constructions (CoC)**: dependent types — Coq, Lean.
- **Homotopy Type Theory (HoTT)**: types as spaces, equality as paths.
### 매 Curry-Howard correspondence
- 매 propositions ⟺ types.
- 매 proofs ⟺ programs.
- 매 implication `A → B` ⟺ function `A → B`.
- 매 conjunction `A ∧ B` ⟺ pair `(A, B)`.
- 매 disjunction `A B` ⟺ sum `Either A B`.
- 매 universal `∀x. P(x)` ⟺ dependent function `(x: A) → P(x)`.
### 매 응용
1. Theorem proving — Lean 4 (mathlib), Coq/Rocq (CompCert verified C compiler).
2. Verified software — seL4 microkernel (Isabelle/HOL).
3. Practical type systems — Haskell GADT, Rust lifetime, TypeScript conditional types.
## 💻 패턴
### Haskell: parametric polymorphism (System F)
```haskell
-- 매 ∀α. [α] → Int
length :: forall a. [a] -> Int
length [] = 0
length (_:xs) = 1 + length xs
```
### Haskell: GADT (refined return types)
```haskell
{-# LANGUAGE GADTs #-}
data Expr a where
IntLit :: Int -> Expr Int
BoolLit :: Bool -> Expr Bool
If :: Expr Bool -> Expr a -> Expr a -> Expr a
eval :: Expr a -> a
eval (IntLit n) = n
eval (BoolLit b) = b
eval (If c t e) = if eval c then eval t else eval e
```
### Idris: dependent type (vector with length)
```idris
data Vect : Nat -> Type -> Type where
Nil : Vect Z a
(::) : a -> Vect n a -> Vect (S n) a
-- 매 length encoded in type — no runtime check needed
append : Vect n a -> Vect m a -> Vect (n + m) a
append Nil ys = ys
append (x :: xs) ys = x :: append xs ys
```
### Lean 4: theorem as type
```lean
-- 매 proposition: ∀ n : , n + 0 = n
theorem add_zero (n : Nat) : n + 0 = n := by
induction n with
| zero => rfl
| succ k ih => rw [Nat.succ_add, ih]
```
### TypeScript: conditional types (System Fω-ish)
```typescript
type IsArray<T> = T extends Array<any> ? true : false;
type A = IsArray<number[]>; // true
type B = IsArray<string>; // false
// 매 distributive
type ToArray<T> = T extends any ? T[] : never;
type C = ToArray<string | number>; // string[] | number[]
```
### Rust: phantom type for state encoding
```rust
use std::marker::PhantomData;
struct Connection<State> { _state: PhantomData<State> }
struct Open; struct Closed;
impl Connection<Closed> {
fn open(self) -> Connection<Open> { Connection { _state: PhantomData } }
}
impl Connection<Open> {
fn send(&self, data: &[u8]) {}
fn close(self) -> Connection<Closed> { Connection { _state: PhantomData } }
}
// 매 .send() on Closed 는 compile error
```
### Haskell: refinement via Liquid Haskell
```haskell
{-@ type Pos = {v:Int | v > 0} @-}
{-@ divPos :: Int -> Pos -> Int @-}
divPos x y = x `div` y -- 매 SMT solver 가 y > 0 검증
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Mathematical proof | Lean 4 / Rocq (Coq) |
| Verified compiler / OS | Coq (CompCert) / Isabelle (seL4) |
| Industrial typed FP | Haskell + GADT + TypeFamilies |
| Practical dependent types | Idris 2 |
| TypeScript-level type-level | conditional + mapped + template literal |
| Compile-time state machine | Rust phantom types / typestate |
**기본값**: 매 application 은 Haskell/Rust/TS 의 expressive type system; 매 critical proof 는 Lean 4.
## 🔗 Graph
- 부모: [[TypeScript 타입 시스템 (TypeScript Type System)|Type System]] · [[Formal Methods]]
- 응용: [[Coq]]
- Adjacent: [[Curry-Howard]]
## 🤖 LLM 활용
**언제**: 매 type system design 이해, advanced FP, formal verification, TS type-level wizardry.
**언제 X**: 매 일반 application 작성 — overkill.
## ❌ 안티패턴
- **Type-level "abuse" in TS**: 매 IDE 가 5분 freeze — 단순 runtime check 가 나음.
- **Dependent type 없는 곳 흉내**: 매 Haskell phantom type 으로 vector length 흉내 — 진짜 검증 안됨, runtime panic 가능.
- **Curry-Howard 의 직접 응용 실수**: 매 Hindley-Milner type inference 는 type-level recursion 에 약함 — 매 explicit annotation 필요.
## 🧪 검증 / 중복
- Verified (Pierce "Types and Programming Languages", Martin-Löf "Intuitionistic Type Theory", HoTT Book).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — type theory full content (Curry-Howard, GADT, dependent, Lean) |
@@ -0,0 +1,32 @@
---
id: wiki-2026-0508-typescript-타입-시스템-및-인터페이스-설계
title: TypeScript 타입 시스템 및 인터페이스 설계
category: 10_Wiki/Topics
status: duplicate
canonical_id: typescript-types
duplicate_of: "[[TypeScript Type System]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, typescript, interface]
last_reinforced: 2026-05-10
github_commit: pending
---
# TypeScript 타입 시스템 및 인터페이스 설계
> **이 문서는 [[TypeScript Type System]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약 (specialization aspects)
- 매 interface 설계 측면 — `interface` vs `type alias`, declaration merging, `extends` chain.
- 매 structural typing 의 핵심: shape match.
## 🔗 Graph
- 부모: [[TypeScript Type System]] (canonical)
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-typescript의-제어-흐름-분석-및-상태-관리-패턴
title: TypeScript의 제어 흐름 분석 및 상태 관리 패턴
category: 10_Wiki/Topics
status: duplicate
canonical_id: typescript-types
duplicate_of: "[[TypeScript Type System]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, typescript, narrowing, discriminated-union]
last_reinforced: 2026-05-10
github_commit: pending
---
# TypeScript의 제어 흐름 분석 및 상태 관리 패턴
> **이 문서는 [[TypeScript Type System]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약 (specialization aspects)
- 매 control flow analysis 측면 — type narrowing (`typeof`, `instanceof`, `in`, custom type guards).
- 매 discriminated union 의 state machine pattern: `type State = { kind: 'idle' } | { kind: 'loading' } | { kind: 'error', err: Error }`.
## 🔗 Graph
- 부모: [[TypeScript Type System]] (canonical)
- 변형: [[Discriminated Union]] · [[Type Guard]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,200 @@
---
id: wiki-2026-0508-union-types
title: Union Types
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Sum Types, Tagged Union, Discriminated Union, Variant]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [type-system, union, sum-type, discriminated-union, typescript, rust]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript / Rust / Haskell
framework: language-agnostic
---
# Union Types
## 매 한 줄
> **"매 값이 A 또는 B (또는 C, ...) 의 하나 — 매 sum type 의 set-theoretic 표현"**. Union types 은 1970s ML 의 datatype, 1980s C union (untagged) 부터, 2026 TypeScript discriminated union, Rust enum, Haskell ADT, Python `X | Y` (PEP 604) 까지 매 type-safe variant modeling 의 표준. 매 product type (struct/tuple) 의 dual: AND 가 product, OR 가 sum.
## 매 핵심
### 매 두 종류
- **Untagged union (C-style)**: 매 같은 메모리 영역, runtime 에 active variant 알 수 없음 — unsafe.
- **Tagged / discriminated union**: 매 tag field 로 variant 구분 — type-safe (Rust `enum`, TS discriminated, Haskell ADT).
### 매 set theory 관점
-`A | B` ≅ A B (set union, 중복 제거).
-`{a:1} | {b:2}``{a:1, b?:undefined} {a?:undefined, b:2}` (TS structural).
- 매 cardinality: `|A | B| = |A| + |B|` (disjoint).
### 매 응용
1. API response — `Success<T> | Error` (Result type).
2. State machine — `Idle | Loading | Success | Error`.
3. Parser AST — `BinOp | UnaryOp | Literal | Variable`.
## 💻 패턴
### TypeScript: discriminated union
```typescript
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number }
| { kind: "rect"; width: number; height: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.side ** 2;
case "rect": return s.width * s.height;
}
}
```
### TypeScript: exhaustiveness check
```typescript
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.radius ** 2;
case "square": return s.side ** 2;
case "rect": return s.width * s.height;
default: {
const _exhaustive: never = s; // 매 새 variant 추가 시 compile error
throw new Error(`unhandled: ${_exhaustive}`);
}
}
}
```
### TypeScript: Result type
```typescript
type Result<T, E = Error> =
| { ok: true; value: T }
| { ok: false; error: E };
async function fetchUser(id: string): Promise<Result<User>> {
try { return { ok: true, value: await api.get(id) }; }
catch (e) { return { ok: false, error: e as Error }; }
}
const r = await fetchUser("1");
if (r.ok) console.log(r.value.name);
else console.error(r.error.message);
```
### Rust: enum with data
```rust
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(u8, u8, u8),
}
fn handle(msg: Message) {
match msg {
Message::Quit => println!("quit"),
Message::Move { x, y } => println!("move to {},{}", x, y),
Message::Write(s) => println!("write {}", s),
Message::ChangeColor(r, g, b) => println!("rgb({},{},{})", r, g, b),
}
}
```
### Rust: Option / Result (built-in unions)
```rust
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 { Err("division by zero".into()) }
else { Ok(a / b) }
}
match divide(10.0, 2.0) {
Ok(v) => println!("{}", v),
Err(e) => eprintln!("error: {}", e),
}
```
### Haskell: ADT (sum + product)
```haskell
data Tree a = Leaf | Node (Tree a) a (Tree a)
depth :: Tree a -> Int
depth Leaf = 0
depth (Node l _ r) = 1 + max (depth l) (depth r)
-- 매 Maybe = Nothing | Just a — sum type
safeDiv :: Int -> Int -> Maybe Int
safeDiv _ 0 = Nothing
safeDiv a b = Just (a `div` b)
```
### Python 3.10+: union via `|`
```python
from dataclasses import dataclass
@dataclass
class Circle: radius: float
@dataclass
class Square: side: float
Shape = Circle | Square
def area(s: Shape) -> float:
match s:
case Circle(radius=r): return 3.14159 * r * r
case Square(side=x): return x * x
```
### TypeScript: narrowing without discriminant
```typescript
type Pet = { swim: () => void } | { fly: () => void };
function move(p: Pet) {
if ("swim" in p) p.swim(); // 매 narrowed
else p.fly();
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 2-3 variants, simple | TS plain union `A \| B` |
| Many variants, type-safe dispatch | discriminated union with `kind` |
| Result / Option | TS Result type / Rust built-in / Haskell Maybe |
| Cross-language ADT | Rust enum / Haskell data |
| Untagged (FFI / memory layout) | C union / Rust `union` (unsafe) |
| Exhaustive matching | switch + `never` (TS) / `match` (Rust/Python) |
**기본값**: 매 discriminated union with literal `kind`/`tag` field — exhaustiveness 보장.
## 🔗 Graph
- 부모: [[TypeScript 타입 시스템 (TypeScript Type System)|Type System]] · [[Algebraic Data Types]]
- 변형: [[Discriminated Union]] · [[Tagged Union]] · [[Sum Types]] · [[Variant]]
- 응용: [[Result Type]] · [[State Machine]] · [[AST]]
- Adjacent: [[Pattern Matching]] · [[Type Narrowing]]
## 🤖 LLM 활용
**언제**: 매 모델링 "A or B" 의 alternatives, error handling (Result), state representation.
**언제 X**: 매 단순 enum (no associated data) — plain enum 이 나음.
## ❌ 안티패턴
- **Boolean flags 의 union 흉내**: `{ ok: boolean, value?, error? }` — 매 `value && error` 동시 가능 → bug. Discriminated union 으로.
- **Discriminant 없는 큰 union**: 매 narrowing 불가능 — `kind`/`tag` 추가.
- **`default` 없는 switch**: 매 새 variant 추가 시 silent miss — `never` exhaustive check.
- **Rust untagged `union`**: 매 unsafe 만 사용 — 99% 의 case 는 `enum`.
## 🧪 검증 / 중복
- Verified (TypeScript handbook, Rust book, Haskell report 2010).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — union types full content (4 langs, exhaustive, Result, 8 patterns) |
@@ -0,0 +1,144 @@
---
id: wiki-20260508-vergence-accommodation-conflicts-redir
title: Vergence-Accommodation Conflicts
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [VAC, vergence accommodation conflict, focal mismatch]
duplicate_of: none
source_trust_level: A
confidence_score: 0.91
verification_status: applied
tags: [vr, perception, optics, ux]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Three.js / WebXR
---
# Vergence-Accommodation Conflicts
## 매 한 줄
> **"매 eye 의 vergence (cross-eye angle) 와 accommodation (lens focus) 의 mismatch 의 eye strain / sickness"**. 매 stereoscopic VR / AR 의 fundamental 한계 — 매 fixed focal plane 의 cause. 2026 의 Vision Pro 의 여전히 mitigation 만 가능 — 매 light field display 의 future.
## 매 핵심
### 매 원인
- **Real world**: 매 vergence (eye 가 object 로 cross) 와 accommodation (lens focus 의 거리) 의 동기.
- **VR/AR**: 매 vergence 의 virtual depth 의 따라 변화 — 매 accommodation 의 fixed display focal plane (~2m) 에 lock.
- **Conflict**: 매 brain 의 두 cue 의 mismatch 의 fatigue / blur / nausea 의 trigger.
### 매 mitigation
- **Dolly comfort zone**: 매 0.5-2m 의 main interaction — focal mismatch minimum.
- **Reduce small text**: 매 close-up text 의 conflict 의 amplify.
- **Vary focus only with intent**: 매 sudden depth change 의 avoid.
- **Pupil-aware DOF**: 매 eye-tracking 의 dynamic blur (Vision Pro).
- **Light field display** (future): 매 multi-focal — true accommodation cue.
### 매 응용
1. UI design — 매 menu 의 1.5m 거리 의 default.
2. AR overlay 의 real-world depth match — 매 ARKit / ARCore 의 plane anchor.
3. eye-tracked foveated rendering 의 결합.
## 💻 패턴
### 매 Three.js + WebXR 의 comfort zone 의 UI 배치
```typescript
const COMFORT_DISTANCE = 1.5; // m
const menu = new THREE.Group();
menu.position.set(0, 1.5, -COMFORT_DISTANCE); // 매 1.5m 의 fixed focal
camera.parent.add(menu); // 매 head-locked
// 매 menu 의 readable 의 maintain
```
### 매 거리 별 text size 의 scaling
```typescript
function readableTextSize(distance: number): number {
// 매 angular size = arctan(size / distance) — 매 적정 1-2°
return distance * 0.025; // 매 1.5m 의 ~3.75cm height
}
```
### 매 Eye-tracking 의 dynamic DOF (Vision Pro / Quest Pro)
```typescript
const xrSession = renderer.xr.getSession();
const gazeRay = await xrSession?.requestReferenceSpace('viewer');
// 매 gaze 의 depth 의 추정
function applyDOF(focusDistance: number) {
postProcessing.bokehPass.uniforms.focus.value = focusDistance;
postProcessing.bokehPass.uniforms.aperture.value = 0.025;
}
```
### 매 Sudden depth change 의 mitigation
```typescript
// 매 fade transition 의 사용
async function transitionScene(newDepth: number) {
await fadeToBlack(200);
scene.position.z = -newDepth;
await fadeFromBlack(200);
}
```
### 매 AR plane anchor 의 align
```typescript
// 매 WebXR hit-test
const hitTestSource = await xrSession.requestHitTestSource({ space: viewerSpace });
xrSession.requestAnimationFrame((time, frame) => {
const results = frame.getHitTestResults(hitTestSource);
if (results.length > 0) {
const pose = results[0].getPose(refSpace);
object.position.setFromMatrixPosition(new THREE.Matrix4().fromArray(pose.transform.matrix));
// 매 real surface 의 attach — 매 vergence/accommodation 의 align
}
});
```
### 매 Comfort range 의 enforce
```typescript
function clampInteractionDistance(target: THREE.Object3D) {
const dist = camera.position.distanceTo(target.position);
if (dist < 0.3) target.scale.setScalar(0.3 / dist); // 매 too-close 시 shrink
if (dist > 3) target.scale.setScalar(dist / 3); // 매 too-far 시 enlarge
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| UI / menu | 1.5-2m fixed (comfort zone) |
| Reading | 0.7-1m, large font |
| AR overlay | real surface anchor |
| Cinematic | distant scene (>3m) |
| Sudden depth jump | fade transition |
**기본값**: 0.5-2m comfort zone 의 default, 매 UI 의 1.5m 의 fixed.
## 🔗 Graph
- 응용: [[VR Sickness]] · [[깊이 지각(Depth perception)]]
- Adjacent: [[Edge Bleeding]] · [[가상현실(VR) 자전거 시뮬레이터]]
## 🤖 LLM 활용
**언제**: VR/AR UX 의 comfort design, UI 거리 의 권장, eye strain 의 explain.
**언제 X**: 매 specific HMD 의 hardware 의 specific recommendation 의 over-confidence — 매 device 의 명시.
## ❌ 안티패턴
- **Tiny text 의 close**: 매 0.3m 의 small font — 매 conflict 의 max.
- **Sudden zoom**: 매 fade 없는 depth jump — 매 nausea.
- **Floating UI 의 무한 거리**: 매 readable 거리 의 무시.
## 🧪 검증 / 중복
- Verified (Oculus VR Best Practices, Apple Vision Pro Human Interface Guidelines).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — VAC FULL 작성 |
@@ -0,0 +1,32 @@
---
id: wiki-2026-0508-war-yes
title: War Yes
category: 10_Wiki/Topics
status: duplicate
canonical_id: yes-command
duplicate_of: "[[yes (Unix command)]]"
aliases: []
source_trust_level: B
confidence_score: 0.7
verification_status: redirected
tags: [duplicate, unix, cli, ambiguous-title]
last_reinforced: 2026-05-10
github_commit: pending
---
# War Yes
> **이 문서는 ambiguous title — likely [[yes (Unix command)]] 의 typo / OCR artifact.** Canonical 문서로 redirect.
## 핵심 요약
- "War-Yes" 는 의미 불명 — 매 likely "war yes" / "yes(1)" 명령어 관련 OCR / scrape artifact.
- Unix `yes` 명령은 stdout에 무한히 "y" 출력 (interactive prompt 자동 응답용).
- 만약 "war"가 의도적이라면 [[Game Theory]] 의 cooperation game / iterated prisoner's dilemma 참조.
## 🔗 Graph
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복/ambiguous 처리 — canonical (yes 명령) 으로 redirect |
@@ -0,0 +1,142 @@
---
id: wiki-20260508-write-barrier-redir
title: Write Barrier
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [쓰기 장벽, GC Write Barrier, Generational Barrier]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [garbage-collection, runtime, v8, jvm, performance]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: cpp
framework: v8, jvm
---
# Write Barrier
## 매 한 줄
> **"매 inter-generational pointer 의 tracking 의 cost"**. Write barrier 는 매 generational / incremental GC 가 매 old-gen object 의 reference 가 매 young-gen 의 가리킬 때 매 remembered set 의 update 의 small code snippet. 매 V8 / JVM / .NET 의 모든 modern GC 의 essential primitive — 매 minor GC 가 매 entire old-gen 의 scan 의 회피.
## 매 핵심
### 매 why
- **Generational hypothesis**: 매 most objects die young → young-gen 만 frequent collect.
- **Inter-gen pointer 의 problem**: 매 minor GC 의 root 로 매 stack + old→young pointer 의 필요.
- **Naive: scan all old-gen** → expensive.
- **Solution**: 매 write 마다 (old.field = young) 매 barrier 의 firing → remembered set 의 add.
### 매 type
- **Snapshot-at-the-Beginning (SATB)**: 매 incremental marking 의 use (G1, ZGC, V8 Orinoco). 매 overwritten old reference 의 record.
- **Incremental Update**: 매 new reference 의 record (CMS).
- **Card marking**: 매 old-gen 의 fixed-size card (e.g., 512B) 의 dirty bit 의 mark — coarse but cheap.
### 매 cost
- 매 store 마다 ~3-5 instruction overhead.
- 매 hot-loop 의 store 의 bottleneck 가능 — 매 elision optimization 의 important.
## 💻 패턴
### 1. Card-marking pseudo-implementation
```cpp
// 매 1MB heap 의 512B card → 2048 cards
const size_t CARD_SIZE = 512;
uint8_t card_table[HEAP_SIZE / CARD_SIZE];
inline void write_barrier(Object* obj, Object** field, Object* new_val) {
*field = new_val;
if (in_old_gen(obj) && in_young_gen(new_val)) {
size_t card = ((uintptr_t)field - heap_base) / CARD_SIZE;
card_table[card] = 1; // dirty
}
}
void minor_gc_scan() {
for (size_t i = 0; i < num_cards; i++) {
if (card_table[i]) {
scan_card_for_young_refs(i);
card_table[i] = 0;
}
}
}
```
### 2. V8-style incremental marking barrier (simplified)
```cpp
// 매 SATB: overwritten reference 의 mark gray
inline void v8_write_barrier(HeapObject* host, Object** slot, Object* value) {
Object* old = *slot;
*slot = value;
if (incremental_marking_active && is_white(old)) {
mark_gray(old); // 매 not-yet-marked 의 reference 의 처리 보장
}
// 매 generational: old→young 의 record
if (host->in_old_space() && value->in_young_space()) {
remembered_set.insert(slot);
}
}
```
### 3. JIT-emitted barrier elision
```cpp
// 매 compiler 의 barrier 의 omit 가능 case:
// 1. 매 store 의 target 이 fresh allocation (young → ?)
// 2. 매 store value 의 primitive (int, double)
// 3. 매 immutable field 의 init store
function emitStore(host, field, value) {
if (isFreshlyAllocated(host)) emitRawStore(host, field, value);
else emitBarrieredStore(host, field, value);
}
```
### 4. Measure barrier overhead (benchmark)
```typescript
// Node.js / V8 의 barrier overhead 의 indirect measure
const N = 1e7;
const arr = new Array(N);
const obj = { ref: null };
console.time('store-loop');
for (let i = 0; i < N; i++) obj.ref = arr; // 매 barrier 의 fire
console.timeEnd('store-loop');
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 hot inner loop 의 store | primitive 의 use, object reference 의 회피 |
| 매 immutable struct | barrier-free design |
| 매 large old-gen | card marking 의 prefer |
| 매 incremental GC | SATB barrier 의 use |
| 매 low-latency (ZGC) | colored pointers + load barrier 의 alternative |
**기본값**: 매 application code 의 barrier 의 invisible — 매 GC 의 implementation detail.
## 🔗 Graph
- 부모: [[Garbage Collection]] · [[Memory Management]]
- 변형: [[Card Marking]]
- 응용: [[Incremental GC]] · [[Orinoco]]
- Adjacent: [[Mark Sweep Compact]] · [[Garbage Collection|Generational Hypothesis]]
## 🤖 LLM 활용
**언제**: GC internals 의 understanding, runtime tuning, performance 의 explain.
**언제 X**: Rust / non-GC language (no barrier), reference counting (no generational).
## ❌ 안티패턴
- **Barrier elision 의 manual attempt 의 application code**: 매 unsafe.
- **Excessive store-to-old-gen 의 hot path**: 매 remembered set 의 explosion.
- **Ignoring barrier cost 의 high-frequency mutation**: 매 hidden bottleneck.
## 🧪 검증 / 중복
- Verified (Jones GC handbook 2011, V8 Orinoco docs, JVM HotSpot source).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — write barrier 의 type, cost, V8 example 의 expand |
@@ -0,0 +1,209 @@
---
id: wiki-2026-0508-zod-런타임-유효성-검사-통합
title: Zod 런타임 유효성 검사 통합
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Zod, TypeScript runtime validation, Zod schema]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, validation, zod, runtime-types, schema]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Zod 3.x
---
# Zod 런타임 유효성 검사 통합
## 매 한 줄
> **"매 type schema = single source of truth"**. Zod는 매 TypeScript type을 런타임 schema 로 정의하고, parse 시점에 매 validation + type narrowing 을 동시 제공한다. API boundary, env vars, form input 매 unsafe input 의 매 첫 검증선.
## 매 핵심
### 매 동기 (Why Zod over alternatives)
- **TypeScript types are erased**: 매 컴파일 후 `interface User`는 매 사라짐 → API response 의 `data as User` 매 lying.
- **Zod = schema → type**: `z.infer<typeof Schema>` 로 매 schema 가 source of truth.
- **Composability**: 매 `.merge`, `.partial`, `.extend`, `.transform` 으로 매 schema 합성.
- **Error-rich**: parse failure 시 매 path, code, message tree 반환.
### 매 경쟁 라이브러리
- **Yup**: 매 older, schema → type 약함, 매 Zod 가 대체.
- **io-ts**: 매 더 functional (fp-ts), 매 learning curve 높음.
- **Valibot**: 매 tree-shakable, 매 bundle size 우선이면 고려 (~10x smaller).
- **ArkType**: 매 string-based syntax, 매 빠르지만 ecosystem 작음.
- **Zod**: 매 default choice in 2026 — DX, ecosystem (tRPC, React Hook Form), maturity.
### 매 응용
1. **API boundary**: fetch response 매 parse 후 typed 으로 사용.
2. **Form validation**: React Hook Form + zodResolver.
3. **env vars**: `process.env` 의 매 schema parse, missing key 시 즉시 fail.
4. **DB row → domain**: ORM 결과 매 `Schema.parse(row)`.
5. **LLM structured output**: Claude/GPT JSON response 매 schema 로 검증.
## 💻 패턴
### Pattern 1: 기본 schema + type inference
```typescript
import { z } from "zod";
export const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
age: z.number().int().min(0).max(150),
role: z.enum(["admin", "user", "guest"]),
createdAt: z.coerce.date(),
});
export type User = z.infer<typeof UserSchema>;
// usage
const raw: unknown = await fetchUser();
const user = UserSchema.parse(raw); // throws ZodError if invalid
// ^? User
```
### Pattern 2: safeParse for non-throw
```typescript
const result = UserSchema.safeParse(raw);
if (!result.success) {
console.error(result.error.flatten());
return;
}
const user = result.data; // typed
```
### Pattern 3: env validation (fail fast at boot)
```typescript
const EnvSchema = z.object({
DATABASE_URL: z.string().url(),
PORT: z.coerce.number().int().positive().default(3000),
NODE_ENV: z.enum(["development", "production", "test"]),
ANTHROPIC_API_KEY: z.string().startsWith("sk-ant-"),
});
export const env = EnvSchema.parse(process.env);
// process exits at startup if invalid — better than runtime surprise
```
### Pattern 4: discriminated union
```typescript
const ResultSchema = z.discriminatedUnion("status", [
z.object({ status: z.literal("ok"), data: z.string() }),
z.object({ status: z.literal("error"), code: z.number() }),
]);
type Result = z.infer<typeof ResultSchema>;
// narrowing on .status works correctly
```
### Pattern 5: transform for parse-not-validate
```typescript
const DateSchema = z.string().transform((s, ctx) => {
const d = new Date(s);
if (isNaN(d.getTime())) {
ctx.addIssue({ code: "custom", message: "Invalid date" });
return z.NEVER;
}
return d;
});
const out = DateSchema.parse("2026-05-10"); // Date instance
```
### Pattern 6: API client with Zod
```typescript
async function fetchUser(id: string): Promise<User> {
const res = await fetch(`/api/users/${id}`);
const json = await res.json();
return UserSchema.parse(json); // unknown → User
}
```
### Pattern 7: tRPC integration
```typescript
import { router, procedure } from "./trpc";
export const userRouter = router({
create: procedure
.input(UserSchema.omit({ id: true, createdAt: true }))
.mutation(async ({ input }) => {
// input is fully typed + validated
return db.user.create({ data: input });
}),
});
```
### Pattern 8: React Hook Form + Zod
```typescript
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
const FormSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
const { register, handleSubmit, formState } = useForm({
resolver: zodResolver(FormSchema),
});
```
### Pattern 9: schema composition
```typescript
const Base = z.object({ id: z.string(), createdAt: z.date() });
const Post = Base.extend({ title: z.string(), body: z.string() });
const PostUpdate = Post.partial().required({ id: true });
```
### Pattern 10: refinement (custom rules)
```typescript
const PasswordSchema = z
.object({ password: z.string(), confirm: z.string() })
.refine((d) => d.password === d.confirm, {
message: "Passwords do not match",
path: ["confirm"],
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| API boundary, untrusted input | Zod parse |
| Internal pure-TS code | Type only, no Zod |
| Bundle size critical (mobile, edge) | Valibot |
| Functional ergonomics | io-ts |
| LLM structured output (Claude/GPT) | Zod + tool schema |
| Performance hot path (>10k parses/sec) | Compile to TypeBox/AJV |
**기본값**: Zod 3.x — 매 modern TS app 의 default validation layer.
## 🔗 Graph
- 부모: [[TypeScript]] · [[Runtime_Validation|Runtime Type Validation]]
- 변형: [[Valibot]] · [[Yup]] · [[ArkType]]
- 응용: [[React Hook Form]]
- Adjacent: [[JSON Schema]] · [[과잉 속성 체크 (Excess Property Checking)]]
## 🤖 LLM 활용
**언제**: untrusted boundary (API, form, env, LLM output) 매 parse. tool/function calling 의 매 input schema.
**언제 X**: internal pure-TS code 매 over-validation 불필요. hot loop 의 매 매 parse 호출.
## ❌ 안티패턴
- **Anti1: parse everywhere**: 매 internal function 매 Zod parse — 매 overhead 누적, 매 type only 충분.
- **Anti2: as cast after parse**: `Schema.parse(x) as MyType` — 매 redundant, parse 가 이미 typed return.
- **Anti3: schema duplication**: type + schema 따로 정의 — 매 z.infer 사용.
- **Anti4: nested transforms with side effects**: transform 안에서 fetch/IO — 매 pure 하게 유지.
## 🧪 검증 / 중복
- Verified (Zod docs colinhacks.com/zod, 2026 ecosystem).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Zod runtime validation patterns + 2026 ecosystem context |
@@ -0,0 +1,191 @@
---
id: wiki-2026-0508-as-const-assertion
title: as const Assertion
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [const assertion, const context, readonly literal]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [typescript, type-system, literal-types, immutability]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: TypeScript 5.x
---
# as const Assertion
## 매 한 줄
> **"매 widening을 끄는 가장 강력한 단언"**. TypeScript 3.4에 등장한 `as const`는 literal type을 보존하면서 모든 property를 `readonly`로 만든다. 매 modern TS 코드의 type-safety 핵심 도구.
## 매 핵심
### 매 동작 방식
- 매 literal (string, number, boolean, array, object literal) 을 narrow type 으로 고정
- 매 type widening 방지 — `"hello"``string` 이 X, 매 `"hello"` literal type
- 매 array → readonly tuple 변환
- 매 object → 매 모든 property `readonly` + literal type
### 매 작동 범위
- 매 literal expression 에만 적용 가능
- 매 변수 / 함수 호출 결과에 매 X
- 매 컴파일 타임 only — 매 runtime 영향 X
### 매 응용
1. Discriminated union 의 tag 정의.
2. Const enum 의 modern 대체 (literal object).
3. Tuple type 의 명시적 생성 (router params, fixed-length array).
4. Configuration object 의 immutable 보장.
## 💻 패턴
### 1. Widening 방지
```typescript
// 매 widening
const x = "foo"; // type: string (let), "foo" (const)
let y = "foo"; // type: string (always widened)
// 매 as const
const x2 = "foo" as const; // type: "foo"
let y2 = "foo" as const; // type: "foo" — 매 let 도 narrow
// 매 array
const arr1 = [1, 2, 3]; // number[]
const arr2 = [1, 2, 3] as const; // readonly [1, 2, 3]
```
### 2. Discriminated Union Tag
```typescript
const ACTIONS = {
INCREMENT: "INCREMENT",
DECREMENT: "DECREMENT",
RESET: "RESET",
} as const;
type Action =
| { type: typeof ACTIONS.INCREMENT; payload: number }
| { type: typeof ACTIONS.DECREMENT; payload: number }
| { type: typeof ACTIONS.RESET };
// 매 ACTIONS.INCREMENT 의 type 은 "INCREMENT" — 매 string X
```
### 3. Const Enum 대체
```typescript
// 매 옛 방식 — const enum (tree-shaking 문제, --isolatedModules 충돌)
const enum Color { Red = "red", Blue = "blue" }
// 매 modern 방식 — as const
const Color = {
Red: "red",
Blue: "blue",
} as const;
type Color = typeof Color[keyof typeof Color]; // "red" | "blue"
```
### 4. Readonly Tuple
```typescript
function useState<T>(initial: T) {
let value = initial;
return [value, (v: T) => { value = v; }] as const;
}
// 매 return type: readonly [T, (v: T) => void]
// 매 destructure 시 정확한 type
const [count, setCount] = useState(0);
```
### 5. 매 Object 의 Deep Readonly
```typescript
const config = {
api: {
baseUrl: "https://api.example.com",
timeout: 5000,
retries: 3,
},
features: ["auth", "billing"],
} as const;
// type:
// {
// readonly api: {
// readonly baseUrl: "https://api.example.com";
// readonly timeout: 5000;
// readonly retries: 3;
// };
// readonly features: readonly ["auth", "billing"];
// }
// config.api.timeout = 1000; // ❌ readonly
```
### 6. 매 Type Extraction
```typescript
const ROLES = ["admin", "user", "guest"] as const;
type Role = typeof ROLES[number]; // "admin" | "user" | "guest"
const HTTP_METHODS = ["GET", "POST", "PUT", "DELETE"] as const;
type HttpMethod = typeof HTTP_METHODS[number];
// 매 사용
function fetchData(method: HttpMethod, url: string) { /* ... */ }
fetchData("GET", "/api"); // ✅
fetchData("PATCH", "/api"); // ❌ Argument of type '"PATCH"' is not assignable
```
### 7. Generic Function 의 Inference
```typescript
function pick<T, K extends keyof T>(obj: T, keys: readonly K[]): Pick<T, K> {
const result = {} as Pick<T, K>;
for (const key of keys) result[key] = obj[key];
return result;
}
const user = { id: 1, name: "Alice", age: 30 };
const subset = pick(user, ["id", "name"] as const);
// 매 as const 없으면: keys 는 string[] 으로 추론 → K = string → 매 fail
// 매 as const 있으면: keys 는 readonly ("id" | "name")[] → K = "id" | "name"
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Magic string / number set | `as const` 객체 + `typeof[keyof typeof]` |
| Discriminated union tag | `as const` 로 literal 보장 |
| Tuple return | 함수 끝에 `as const` |
| Config / constants | 매 `as const` 로 deep readonly |
| Const enum 사용 중 | 매 `as const` 객체로 마이그레이션 |
| Mutable shared state | `as const` X — 매 readonly 가 방해 |
**기본값**: 매 literal data 에는 항상 `as const` 를 시도. 매 widening 이 의도일 때만 제외.
## 🔗 Graph
- 부모: [[TypeScript]]
- 변형: [[const Assertion]] · [[satisfies Operator]]
- 응용: [[Discriminated_Unions|Discriminated Unions]] · [[Literal Types]]
- Adjacent: [[Readonly]] · [[Type Narrowing]]
## 🤖 LLM 활용
**언제**: 매 fixed set of values (action types, route names, status codes), tuple return, config object 정의 시 사용.
**언제 X**: runtime mutation 필요 시, generic widening 이 의도일 때, 매 single primitive variable (이미 `const` 로 충분).
## ❌ 안티패턴
- **Function call 에 적용**: `fetch() as const` — 매 literal 이 X 라 효과 없음.
- **Mutable interface 와 충돌**: `as const` 객체를 mutable interface 에 assign — 매 readonly mismatch 에러.
- **과도한 nesting**: 매 깊은 readonly 가 매 사용처에서 매 type 좁힘 — 매 trade-off 고려.
- **type 와 value 혼동**: `typeof OBJ` vs `OBJ` — 매 type 추출엔 `typeof`.
## 🧪 검증 / 중복
- Verified (TypeScript 3.4+ release notes, TS Handbook 2025 edition).
- 신뢰도 A.
- 매 [[Const Assertions]] 와 동의어 — 매 같은 기능.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — as const 의 7 패턴 + decision matrix |
@@ -0,0 +1,227 @@
---
id: wiki-2026-0508-bitecs와-sharedarraybuffer를-결합한-멀
title: bitECS와 SharedArrayBuffer를 결합한 멀티스레드 고성능 아키텍처
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [bitECS multithreaded, SAB ECS, ECS parallel, bitECS SharedArrayBuffer]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [ecs, bitecs, sharedarraybuffer, parallel, gamedev, browser]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: bitECS + Web Worker
---
# bitECS와 SharedArrayBuffer를 결합한 멀티스레드 고성능 아키텍처
## 매 한 줄
> **"매 bitECS Component = TypedArray on SAB"**. bitECS의 매 SoA layout 은 매 SharedArrayBuffer 와 매 자연스럽게 결합 — 매 component data 가 매 worker 에서 매 zero-copy 공유. 매 system 분산 + 매 stripe partition 으로 매 100k+ entity 를 매 60fps 에서 매 simulate 가능.
## 매 핵심
### 매 bitECS 구조
- **Entity**: 32-bit integer ID.
- **Component**: 매 TypedArray (Float32Array, Int32Array 등) per field, 매 indexed by entity ID.
- **System**: query → process loop.
- 매 SoA (Struct of Arrays) → 매 cache-friendly + SIMD-friendly.
### 매 SAB 통합 핵심
- bitECS 의 매 component 매 backing TypedArray 의 매 buffer 를 매 SAB 로 교체.
- 매 worker 에서 매 동일 component 에 매 동시 접근 가능.
- 매 system 별로 매 worker 분배 — 또는 매 entity range 별 분배.
### 매 partition strategy
1. **System-level**: physics worker, AI worker, render worker 매 별도.
2. **Entity-level**: entity ID 매 mod N → worker N 개에 분산.
3. **Stripe-level**: contiguous range, cache-friendly.
4. **Hybrid**: 매 read-heavy system 매 모든 worker, write 매 owner worker 만.
### 매 응용
1. **Boid/flocking**: 100k boids 매 4 worker 에서 stripe.
2. **Particle system**: SAB Float32 의 매 position/velocity, 매 worker 별 batch.
3. **Pathfinding**: A* 매 worker pool, 매 result 매 SAB 에 적재.
4. **Voxel chunk update**: 매 chunk 별 worker, 매 mesh build 매 OffscreenCanvas worker.
## 💻 패턴
### Pattern 1: bitECS component → SAB-backed
```typescript
// main.ts
import { createWorld, defineComponent, Types } from "bitecs";
const MAX_ENTITIES = 100_000;
const sab = new SharedArrayBuffer(MAX_ENTITIES * 3 * 4 * 2); // pos+vel, f32
// SAB 위에 매 직접 component 정의 (bitECS 0.4+ allows custom buffer)
const Position = {
x: new Float32Array(sab, 0, MAX_ENTITIES),
y: new Float32Array(sab, MAX_ENTITIES * 4, MAX_ENTITIES),
};
const Velocity = {
x: new Float32Array(sab, MAX_ENTITIES * 8, MAX_ENTITIES),
y: new Float32Array(sab, MAX_ENTITIES * 12, MAX_ENTITIES),
};
const world = createWorld();
// ... addEntity, addComponent (writes go into SAB views)
```
### Pattern 2: worker spawn + SAB share
```typescript
const N_WORKERS = 4;
const workers = Array.from({ length: N_WORKERS }, (_, id) => {
const w = new Worker("./physics-worker.ts", { type: "module" });
w.postMessage({ sab, workerId: id, n: N_WORKERS, maxEntities: MAX_ENTITIES });
return w;
});
```
### Pattern 3: physics system in worker
```typescript
// physics-worker.ts
self.onmessage = ({ data: { sab, workerId, n, maxEntities } }) => {
const px = new Float32Array(sab, 0, maxEntities);
const py = new Float32Array(sab, maxEntities * 4, maxEntities);
const vx = new Float32Array(sab, maxEntities * 8, maxEntities);
const vy = new Float32Array(sab, maxEntities * 12, maxEntities);
const stripe = Math.ceil(maxEntities / n);
const start = workerId * stripe;
const end = Math.min(start + stripe, maxEntities);
setInterval(() => {
const dt = 0.016;
for (let i = start; i < end; i++) {
px[i] += vx[i] * dt;
py[i] += vy[i] * dt;
}
}, 16);
};
```
### Pattern 4: barrier-synchronized frame
```typescript
// shared int32 frame counter
const sync = new Int32Array(sab, syncOffset, 4);
// sync[0] = workersReady, sync[1] = generation
function workerStep() {
// do work
doStripe();
// barrier
if (Atomics.add(sync, 0, 1) + 1 === N_WORKERS) {
Atomics.store(sync, 0, 0);
Atomics.add(sync, 1, 1);
Atomics.notify(sync, 1, N_WORKERS - 1);
} else {
const gen = Atomics.load(sync, 1);
Atomics.wait(sync, 1, gen);
}
}
```
### Pattern 5: read-only system on all workers
```typescript
// AI system: read pos/vel of others, write own intent → no contention
function aiSystem(workerId: number) {
for (let i = start; i < end; i++) {
let nearestX = 0, nearestY = 0, nearestDist = Infinity;
for (let j = 0; j < maxEntities; j++) {
if (j === i) continue;
const dx = px[j] - px[i], dy = py[j] - py[i];
const d = dx * dx + dy * dy;
if (d < nearestDist) { nearestDist = d; nearestX = px[j]; nearestY = py[j]; }
}
// write only own intent slot
intent[i] = computeIntent(px[i], py[i], nearestX, nearestY);
}
}
```
### Pattern 6: render thread on main, worker writes only
```typescript
// main thread: requestAnimationFrame → read SAB, render
function frame() {
for (let i = 0; i < activeCount; i++) {
ctx.fillRect(px[i], py[i], 2, 2);
}
requestAnimationFrame(frame);
}
// 매 race: workers writing while main reads — visual tearing 가능, 대부분 게임에서 허용.
// strict 의 매 double buffer (front/back) → flip on barrier.
```
### Pattern 7: double-buffered position
```typescript
const pxA = new Float32Array(sab, offA, max);
const pxB = new Float32Array(sab, offB, max);
let frontIdx = 0;
function workerStep() {
const front = frontIdx === 0 ? pxA : pxB;
const back = frontIdx === 0 ? pxB : pxA;
// read front, write back
for (let i = start; i < end; i++) back[i] = front[i] + vx[i] * dt;
// barrier → main flips frontIdx
}
```
### Pattern 8: SoA SIMD (WASM SIMD or manual unroll)
```typescript
// 매 4-wide unroll — JIT가 종종 SIMD화
for (let i = start; i < end; i += 4) {
px[i] += vx[i] * dt;
px[i + 1] += vx[i + 1] * dt;
px[i + 2] += vx[i + 2] * dt;
px[i + 3] += vx[i + 3] * dt;
}
```
### Pattern 9: spawn/kill queue (lock-free SPSC)
```typescript
// 매 main 만 spawn, worker 만 kill — single-producer queue
// 매 ring buffer of entity IDs, Atomics-driven head/tail
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| <1k entities | Single thread, 매 충분 |
| 1k10k, simple physics | bitECS single-thread |
| 10k+, heavy AI/physics | bitECS + SAB + worker pool |
| Render heavy | OffscreenCanvas worker |
| Voxel/chunk world | Per-chunk worker assignment |
**기본값**: 매 single thread first. 매 measure → SAB 매 4 worker 부터 의미 있을 때만.
## 🔗 Graph
- 부모: [[ECS]] · [[bitECS]] · [[Web Worker]] · [[SharedArrayBuffer]]
- 응용: [[Particle System]]
- Adjacent: [[Web Worker와 SharedArrayBuffer를 이용한 실제 고부하 병렬 처리 구현체 (실패_성공 포함)]] · [[OffscreenCanvas]] · [[가변적 LOD(Level of Detail) 시스템]]
## 🤖 LLM 활용
**언제**: 매 large-scale entity simulation in browser. 매 60fps 매 100k+ entity.
**언제 X**: 매 small game, 매 single-thread bitECS 충분 — 매 SAB 의 debug 비용 매 큼.
## ❌ 안티패턴
- **Anti1: 매 component write 매 worker 동시**: race. 매 ownership 명확히.
- **Anti2: 매 frame SAB 재생성**: GC 폭발. startup 1번.
- **Anti3: 매 worker 마다 component query**: query overhead 누적. 매 main 에서 ID list 한번 + worker 에 stripe.
- **Anti4: false sharing — 매 worker 가 인접 entity write**: 매 stripe 대신 매 mod 분산은 false sharing 위험. stripe 사용.
- **Anti5: render race 무시**: visual artifact. 매 double buffer or 매 tolerate.
## 🧪 검증 / 중복
- Verified (bitECS GitHub, 20252026 Web Worker SAB ecosystem).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — bitECS+SAB architecture + canonical merge |
@@ -0,0 +1,151 @@
---
id: wiki-2026-0508-ndf-parse-패키지
title: ndf-parse 패키지
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [ndf-parse, NDF parser, Eugen NDF]
duplicate_of: none
source_trust_level: B
confidence_score: 0.85
verification_status: applied
tags: [python, parser, modding, wargame, ndf]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Python
framework: ndf-parse (PyPI)
---
# ndf-parse 패키지
## 매 한 줄
> **"매 Eugen Systems 의 NDF (Niche Definition Files) format 의 Python parser/serializer"**. 매 Wargame: Red Dragon, Steel Division, WARNO 의 mod 작성에 사용. 매 lossless round-trip + AST manipulation 을 제공.
## 매 핵심
### 매 NDF format 이란
- Eugen 의 game data 정의 언어 — 매 unit stats, weapon, sound, UI binding 의 declarative description.
- Lua-like syntax + GUID reference + template instantiation. 매 plain text but very large (수만 lines).
### 매 ndf-parse 가 해주는 것
- **Parse**: NDF text → Python AST (List / Object / Map / Reference / Template node).
- **Walk**: tree traversal + by-name lookup.
- **Mutate**: in-place edit, insert, delete.
- **Serialize**: AST → NDF text, 매 formatting 의 보존 (whitespace, comments).
### 매 응용
1. WARNO / Steel Division mod 의 unit balancing.
2. Bulk find-replace (e.g. all small-arms 의 damage +10%).
3. Mod merge tool — 매 multiple mod 의 conflict-free combination.
4. CI validation — 매 NDF schema 의 lint.
## 💻 패턴
### Install + 매 first parse
```python
# pip install ndf-parse
import ndf_parse as ndf
with open("GameData/Generated/Gameplay/Gfx/UniteDescriptor.ndf", "r", encoding="utf-8") as f:
source = ndf.load(f) # returns ndf.model.List
print(type(source), len(source))
```
### 매 unit lookup by name
```python
unit = source.by_name("Descriptor_Unit_M1A2_Abrams_US").value
# unit is an Object node
```
### 매 module 안의 specific value 변경
```python
modules = unit.by_name("ModulesDescriptors").value
for module in modules:
if module.value.type == "TBaseDamageModuleDescriptor":
hp_row = module.value.by_name("MaxPhysicalDamages")
hp_row.value = "12" # was "10"
break
```
### 매 weapon damage 의 bulk +10%
```python
def bump_damage(node):
for member in node:
if member.member == "PhysicalDamages":
try:
old = float(member.value)
member.value = f"{old * 1.10:.2f}"
except ValueError:
pass
if hasattr(member.value, "__iter__"):
bump_damage(member.value)
bump_damage(source)
```
### 매 serialize back
```python
with open("Mod/UniteDescriptor.ndf", "w", encoding="utf-8") as f:
ndf.write(source, f)
# 매 round-trip: comments / whitespace 의 가능한 한 보존
```
### 매 새 unit 의 clone + rename
```python
import copy
template = source.by_name("Descriptor_Unit_M1A2_Abrams_US")
clone = copy.deepcopy(template)
clone.name = "Descriptor_Unit_M1A3_Abrams_Custom"
source.add(clone)
```
### CLI mod build pipeline
```python
# build_mod.py
from pathlib import Path
import ndf_parse as ndf
for src_path in Path("GameData").rglob("*.ndf"):
with src_path.open(encoding="utf-8") as f:
tree = ndf.load(f)
apply_patches(tree, src_path.name)
out = Path("Mod") / src_path.relative_to("GameData")
out.parent.mkdir(parents=True, exist_ok=True)
with out.open("w", encoding="utf-8") as f:
ndf.write(tree, f)
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 single field 변경 | by_name + value 직접 assign |
| 매 bulk pattern 변경 | recursive walker function |
| 매 새 unit 추가 | deepcopy + rename + add |
| 매 cross-file reference | 매 파일별 parse + cross-link by GUID |
| 매 schema validation | custom walker + assertion |
**기본값**: 매 ndf-parse + Python script + git for version control. 매 manual NDF text edit 의 X.
## 🔗 Graph
- 응용: [[WARNO Modding]]
## 🤖 LLM 활용
**언제**: NDF mod 작성 + LLM 의 patch generation, schema 추론, balance tweak suggestion.
**언제 X**: 매 binary game asset (DDS, BANK) — 매 NDF X.
## ❌ 안티패턴
- **매 raw regex 의 NDF edit**: 매 nested template 의 corruption 위험.
- **encoding 누락**: NDF 는 UTF-8 (BOM 가능) — 매 default open() 의 fail.
- **매 reference name 의 typo**: silent — 매 by_name() 의 None return.
## 🧪 검증 / 중복
- Verified (ndf-parse PyPI docs, Eugen modding wiki 2024).
- 신뢰도 B (community-maintained).
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — ndf-parse API + WARNO mod patterns |
@@ -0,0 +1,145 @@
---
id: wiki-2026-0508-ts-brand
title: ts-brand
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [ts-brand library, Branded Types library, Nominal Typing TS]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, branded-types, nominal-typing, library, type-safety]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: ts-brand
---
# ts-brand
## 매 한 줄
> **"매 zero-runtime-cost 의 nominal typing 의 TypeScript"**. ts-brand 는 매 structural typing 의 default 의 TypeScript 에 매 nominal-style brand 의 추가 → 매 UserId 와 매 OrderId 가 매 둘 다 string 이지만 매 swap 의 compile error. 매 2026 의 standard pattern — 매 Effect-TS, Zod, neverthrow 의 모두 의 leverage.
## 매 핵심
### 매 problem (structural typing 의 limitation)
- 매 TypeScript: 매 type UserId = string; type OrderId = string → 매 둘 다 동일 의 interchangeable.
- 매 logical bug: 매 fn(userId: UserId) 의 orderId 의 pass 가 의 silent.
### 매 solution (Brand)
- 매 phantom type tag 의 use → 매 compile-time discrimination.
- 매 runtime cost = 0 (type-only).
### 매 ts-brand API
- `Brand<Base, Tag>`: 매 branded type 의 create.
- `make<T>()`: 매 cast helper.
- 매 alternatives: 매 own-rolling, Effect-TS Brand, type-fest Opaque.
## 💻 패턴
### 1. Basic Brand
```typescript
import { Brand, make } from 'ts-brand';
type UserId = Brand<string, 'UserId'>;
type OrderId = Brand<string, 'OrderId'>;
const UserId = make<UserId>();
const OrderId = make<OrderId>();
const u: UserId = UserId('u-123');
const o: OrderId = OrderId('o-456');
function fetchUser(id: UserId) { /* ... */ }
fetchUser(u); // ✓
fetchUser(o); // ✗ Type error
fetchUser('raw'); // ✗ Type error
```
### 2. Validated Brand (with runtime check)
```typescript
type Email = Brand<string, 'Email'>;
function parseEmail(s: string): Email {
if (!/^[^@]+@[^@]+\.[^@]+$/.test(s)) throw new Error(`invalid email: ${s}`);
return s as Email;
}
// 매 user 의 input 의 parseEmail 의 통과 만 의 Email 의 acquire.
const e = parseEmail(req.body.email);
```
### 3. Brand + Zod (parse 시 brand)
```typescript
import { z } from 'zod';
import type { Brand } from 'ts-brand';
type UserId = Brand<string, 'UserId'>;
const UserIdSchema = z.string().uuid().brand<'UserId'>();
// ^? z.ZodBranded<z.ZodString, 'UserId'>
const id = UserIdSchema.parse('xxx-uuid'); // type: string & z.BRAND<'UserId'>
// 매 Zod-native brand 의 ts-brand 와 의 compatible.
```
### 4. Brand removal (rare, escape hatch)
```typescript
function brandOf<T extends Brand<any, any>>(b: T): UnwrapBrand<T> {
return b as any;
}
type UnwrapBrand<T> = T extends Brand<infer U, any> ? U : never;
const raw: string = brandOf(u); // 매 e.g., logging
```
### 5. Multi-brand (intersection)
```typescript
type NonEmpty = Brand<string, 'NonEmpty'>;
type Trimmed = Brand<string, 'Trimmed'>;
type Clean = NonEmpty & Trimmed;
function clean(s: string): Clean {
const t = s.trim();
if (!t) throw new Error('empty');
return t as Clean;
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 ID type (UserId, OrderId) | brand 의 always |
| 매 validated string (Email, URL) | brand + parse function |
| 매 unit type (Meters, Seconds) | brand 의 use |
| 매 throwaway local | 매 brand 의 skip |
| 매 Zod ecosystem | z.brand<T>() 의 native 의 prefer |
**기본값**: 매 domain 의 distinct identity 의 string/number type → 매 brand 의 use.
## 🔗 Graph
- 부모: [[TypeScript]] · [[Nominal-Typing-in-TypeScript|Nominal Typing]]
- 변형: [[Branded Types]] · [[Opaque Types (TypeScript)]]
- 응용: [[Zod]] · [[Effect TS]] · [[Type Safety]]
- Adjacent: [[Structural Typing]] · [[Runtime Validation]]
## 🤖 LLM 활용
**언제**: TypeScript domain modeling, ID type 의 distinguish, validation pipeline.
**언제 X**: 매 simple script, runtime-only language (Python, JS).
## ❌ 안티패턴
- **Cast 의 brand 의 bypass**: 매 type safety 의 break.
- **Brand 의 너무 많음**: 매 cognitive overhead.
- **Runtime check 없음 의 external input**: 매 brand 만 의 false security.
## 🧪 검증 / 중복
- Verified (ts-brand npm, Effect-TS Brand docs, Zod 4.x).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — ts-brand 의 API, Zod integration, patterns 의 expand |
@@ -0,0 +1,210 @@
---
id: wiki-2026-0508-가변적-lod-level-of-detail-시스템
title: 가변적 LOD(Level of Detail) 시스템
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [LOD, Level of Detail, dynamic LOD, mesh simplification]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [graphics, gamedev, rendering, lod, optimization]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Three.js / Bevy / Unreal Nanite
---
# 가변적 LOD(Level of Detail) 시스템
## 매 한 줄
> **"매 LOD = 매 distance/screen-size 에 따라 매 mesh detail 을 매 동적 교체"**. 매 close 매 high-poly, 매 far 매 low-poly. 매 fixed-bucket LOD (LOD0/1/2/3) 매 classic, 매 continuous/clustered LOD (Unreal Nanite, Bevy meshlet) 매 2026 SOTA — 매 hierarchical cluster + GPU culling 으로 매 sub-pixel triangles 까지 매 streaming.
## 매 핵심
### 매 motivation
- 매 GPU 매 triangle/pixel budget 유한.
- 매 멀리 있는 mesh 의 매 millions of triangles 매 1픽셀에 매 수십 — 매 waste + aliasing.
- 매 적절한 detail 매 close → 매 가까이 모이는 비용 ↓, 매 visual quality ↑.
### 매 LOD 종류
1. **Discrete LOD**: 매 N개의 pre-built mesh, 매 distance threshold 에서 swap. 매 popping 가능.
2. **Continuous LOD (CLOD)**: edge-collapse 매 progressive mesh, 매 smooth transition. 매 CPU heavy.
3. **Hierarchical LOD (HLOD)**: 매 region-level 매 single mesh 병합 (먼 city block → 1 mesh).
4. **Cluster/Meshlet LOD** (Nanite, Bevy 0.13+): 매 mesh를 매 ~128-tri cluster 로 분해 + 매 BVH, 매 GPU 가 매 cluster 단위로 매 select.
5. **Imposter / Billboard**: 매 texture 1장으로 매 멀리서 fake.
6. **Tessellation LOD**: 매 GPU tess shader 가 매 dynamic subdivide.
### 매 selection criteria
- **Distance**: euclidean distance 매 가장 단순.
- **Screen-space size**: bounding sphere → projected pixel size — 매 정확.
- **Velocity / motion**: 매 빠른 object 매 lower LOD 가용.
- **Importance**: 매 player focus / center → high LOD.
### 매 응용
1. **Open-world game**: terrain, vegetation, building.
2. **Voxel world**: chunk LOD by distance.
3. **Crowd rendering**: 매 distant NPC 매 imposter.
4. **Vegetation**: tree → bush → billboard.
5. **CAD 시각화**: 매 model assembly 매 distant simplify.
## 💻 패턴
### Pattern 1: Three.js LOD basic
```typescript
import * as THREE from "three";
const lod = new THREE.LOD();
lod.addLevel(highMesh, 0); // 050
lod.addLevel(midMesh, 50); // 50200
lod.addLevel(lowMesh, 200); // 200500
lod.addLevel(billboard, 500); // 500+
scene.add(lod);
// renderer 가 매 frame 마다 camera.position 으로 자동 select
```
### Pattern 2: screen-space size 기반
```typescript
function selectLOD(obj: THREE.Object3D, camera: THREE.Camera) {
const sphere = new THREE.Sphere();
obj.traverse((c) => {
if (c instanceof THREE.Mesh) c.geometry.computeBoundingSphere();
});
const dist = camera.position.distanceTo(obj.position);
const fov = (camera as THREE.PerspectiveCamera).fov * Math.PI / 180;
const screenH = window.innerHeight;
const projected = (sphere.radius / dist) / Math.tan(fov / 2) * screenH;
if (projected > 200) return 0; // high
if (projected > 50) return 1; // mid
if (projected > 10) return 2; // low
return 3; // billboard
}
```
### Pattern 3: voxel chunk LOD
```typescript
// each chunk has 4 mesh resolutions
type Chunk = { x: number; z: number; meshes: [Mesh, Mesh, Mesh, Mesh] };
function chunkLOD(c: Chunk, camera: Camera): number {
const dx = c.x * CHUNK_SIZE - camera.x;
const dz = c.z * CHUNK_SIZE - camera.z;
const d = Math.sqrt(dx * dx + dz * dz);
if (d < 100) return 0;
if (d < 300) return 1;
if (d < 700) return 2;
return 3;
}
```
### Pattern 4: hysteresis (popping 완화)
```typescript
// LOD swap 시 매 threshold 에 매 hysteresis 추가
function selectLODHysteresis(dist: number, currentLOD: number): number {
const THR = [50, 200, 500];
const HYS = 10; // ±10
if (currentLOD === 0 && dist > THR[0] + HYS) return 1;
if (currentLOD === 1 && dist < THR[0] - HYS) return 0;
if (currentLOD === 1 && dist > THR[1] + HYS) return 2;
// ...
return currentLOD;
}
```
### Pattern 5: GPU instancing per LOD
```typescript
// 매 LOD level 별 매 InstancedMesh, 매 entity 매 batch
const instancedHigh = new THREE.InstancedMesh(highGeo, mat, MAX);
const instancedMid = new THREE.InstancedMesh(midGeo, mat, MAX);
// per frame: 매 entity 의 LOD 결정 → 매 해당 instance 행렬 update
```
### Pattern 6: Bevy meshlet (2026)
```rust
// Bevy 0.13+ — meshlet rendering (cluster LOD)
use bevy::pbr::experimental::meshlet::*;
commands.spawn((
MeshletMesh3d(asset_server.load("model.meshlet_mesh")),
Transform::default(),
));
// GPU 가 매 cluster bvh + screen-space error 로 자동 select
```
### Pattern 7: imposter texture (vegetation)
```glsl
// fragment shader: 매 distance > THRESHOLD → 매 sample atlas billboard
uniform float u_distToCam;
uniform sampler2D u_imposterAtlas;
void main() {
if (u_distToCam > 200.0) {
vec4 imp = texture(u_imposterAtlas, vUV);
if (imp.a < 0.5) discard;
gl_FragColor = imp;
} else {
// full mesh shading
}
}
```
### Pattern 8: progressive mesh (edge collapse offline)
```typescript
// build time: 매 mesh → edge collapse sequence
type Collapse = { v0: number; v1: number; targetVertex: number };
const collapses: Collapse[] = simplify(mesh);
// runtime: 매 LOD level k → apply collapses[0..k]
function applyLOD(mesh: Mesh, level: number) {
for (let i = 0; i < level; i++) collapseEdge(mesh, collapses[i]);
}
```
### Pattern 9: HLOD region merge
```typescript
// 매 build time: cluster 9 buildings → 1 merged mesh per region
// runtime: distance > 1km → region mesh, < 1km → individual buildings
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 게임 props (rocks, trees) | Discrete LOD + imposter |
| Open-world terrain | Quadtree HLOD |
| Voxel/Minecraft | Chunk LOD by ring |
| Crowd (1k+ NPC) | Instancing + LOD + imposter |
| Modern AAA / engine 자체 | Nanite / Bevy meshlet |
| Scientific visualization | CLOD edge collapse |
**기본값**: discrete LOD 3-tier + imposter. 매 engine 이 cluster LOD 매 지원하면 우선.
## 🔗 Graph
- 부모: [[Rendering]] · [[Optimization]]
- 변형: [[Nanite]]
- Adjacent: [[bitECS와 SharedArrayBuffer를 결합한 멀티스레드 고성능 아키텍처]] · [[Frustum Culling]]
## 🤖 LLM 활용
**언제**: 매 large scene, 매 다양한 distance, 매 GPU/CPU bound. 매 1k+ object scene.
**언제 X**: 매 small scene (single character), 매 fixed camera distance — overhead 만 추가.
## ❌ 안티패턴
- **Anti1: hard popping**: hysteresis/dither 없이 매 instant swap — 매 시각적 jarring.
- **Anti2: 매 LOD level 별 mesh 따로 load**: 매 GPU memory 폭발. 매 progressive 또는 매 streaming.
- **Anti3: distance only metric**: 매 huge object 매 멀어도 화면 큼 — screen-size 사용.
- **Anti4: 매 tick 마다 LOD 재계산 every entity**: 매 batch / spatial hash 로 매 amortize.
- **Anti5: imposter 의 매 stale lighting**: 매 shadow / time-of-day 안 맞음 — 매 atlas 재생성 필요.
## 🧪 검증 / 중복
- Verified (Unreal Nanite paper SIGGRAPH 2021, Bevy 0.13 meshlet docs, Three.js LOD).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — LOD strategies + 2026 cluster LOD (Nanite/Meshlet) |
@@ -0,0 +1,172 @@
---
id: wiki-2026-0508-가비지-컬렉션-garbage-collection
title: 가비지 컬렉션 (Garbage Collection)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [GC, Garbage Collection, 메모리 관리]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [gc, memory, runtime, jvm, v8]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Java/JS/Go
framework: JVM/V8/Go-runtime
---
# 가비지 컬렉션 (Garbage Collection)
## 매 한 줄
> **"매 도달 불가능 (unreachable) 한 객체를 자동으로 회수하는 runtime memory manager"**. 1959 LISP의 mark-and-sweep 부터 현대의 ZGC/Shenandoah/G1 까지 — 매 generational + concurrent + region-based 방향으로 진화. 매 sub-millisecond pause 의 실용화 (2024+).
## 매 핵심
### 매 GC 의 근본 작업
- **Mark**: GC root (stack, globals, registers) 부터 reachable graph traversal.
- **Sweep / Compact / Copy**: unreachable 객체의 회수 + 매 fragmentation 의 처리.
### 매 주요 알고리즘
- **Mark-and-Sweep**: 매 simple, 매 fragmentation 발생.
- **Mark-Compact**: 매 sweep 후 live object 의 compact — fragmentation X.
- **Copying (Cheney)**: 매 from-space → to-space 의 live copy. 매 generational young gen 에 사용.
- **Generational**: 매 weak generational hypothesis — 매 young die young. 매 young gen frequent + old gen rare.
- **Concurrent / Incremental**: 매 mutator thread 와 동시 실행 — pause 의 최소화.
- **Region-based (G1, ZGC, Shenandoah)**: 매 heap 의 region 분할 — 매 partial collection.
### 매 응용
1. JVM (G1 default since Java 9, ZGC production since Java 17, Shenandoah).
2. V8 (Orinoco — concurrent + parallel + incremental).
3. Go (concurrent tri-color mark-sweep, sub-ms pause).
4. .NET CLR (generational + LOH).
5. CPython (reference counting + cycle detector).
## 💻 패턴
### Tri-color Marking (concurrent GC 의 기반)
```python
# Tri-color invariant: White (unmarked), Gray (marked, children pending), Black (done)
WHITE, GRAY, BLACK = 0, 1, 2
def tri_color_mark(roots, heap):
for obj in heap:
obj.color = WHITE
gray_set = set()
for r in roots:
r.color = GRAY
gray_set.add(r)
while gray_set:
obj = gray_set.pop()
for child in obj.refs:
if child.color == WHITE:
child.color = GRAY
gray_set.add(child)
obj.color = BLACK
# White = unreachable -> sweep
return [o for o in heap if o.color == WHITE]
```
### Write Barrier (concurrent GC 의 invariant 유지)
```c
// Dijkstra-style: black -> white write 발생 시 child를 gray로 승격
void write_barrier(Object* parent, Object** field, Object* new_val) {
if (parent->color == BLACK && new_val && new_val->color == WHITE) {
new_val->color = GRAY;
gray_queue_push(new_val);
}
*field = new_val;
}
```
### Generational Allocation (bump allocator)
```rust
struct YoungGen { start: *mut u8, top: *mut u8, end: *mut u8 }
impl YoungGen {
fn alloc(&mut self, size: usize) -> Option<*mut u8> {
unsafe {
let new_top = self.top.add(size);
if new_top > self.end { return None; } // trigger minor GC
let p = self.top;
self.top = new_top;
Some(p)
}
}
}
```
### Reference Counting + Cycle Detection (CPython)
```python
class Obj:
def __init__(self):
self.refcount = 1
def incref(self): self.refcount += 1
def decref(self):
self.refcount -= 1
if self.refcount == 0:
for child in self.refs: child.decref()
free(self)
# Cycle: a.refs=[b], b.refs=[a] -> refcount 영원히 >0 -> cycle collector 필요
```
### Finalizer (resource cleanup, careful)
```java
// Java AutoCloseable + try-with-resources >>> finalize() (deprecated in Java 9+)
try (var conn = DriverManager.getConnection(url)) {
// use conn
} // auto-close, deterministic
```
### Soft / Weak / Phantom Reference
```java
WeakReference<Cache> ref = new WeakReference<>(cache);
// GC가 free하면 ref.get() == null. Cache 구현에 자주 사용
```
### G1 / ZGC tuning (JVM)
```bash
java -XX:+UseZGC -Xmx16g -XX:+UseLargePages MyApp
# ZGC: <1ms pause, multi-TB heap (Java 21+)
java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 MyApp
# G1: pause-target driven, default since Java 9
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Low-latency service (<10ms p99) | ZGC, Shenandoah, Go GC |
| Throughput batch | Parallel GC (JVM), G1 |
| Embedded / no-GC | Rust, C++ RAII |
| Predictable real-time | No GC + arena allocator |
| Reference cycles 빈번 | tracing GC > refcount |
**기본값**: 매 modern JVM 의 **G1** (or ZGC for >4GB heap), Go 의 **default concurrent collector**.
## 🔗 Graph
- 부모: [[메모리 관리]]
- 변형: [[Reference Counting]]
- 응용: [[V8 Engine]]
- Adjacent: [[Memory Leak]] · [[Heap]]
## 🤖 LLM 활용
**언제**: GC tuning, OOM 분석, GC log 해석, allocation pattern 최적화.
**언제 X**: 매 hot loop allocation 미세조정 — profiler (async-profiler, pprof) 가 우선.
## ❌ 안티패턴
- **System.gc() 호출**: hint 일 뿐, full GC 강제로 pause 유발.
- **finalize() 의존**: 매 deprecated. AutoCloseable 사용.
- **Large object 의 young gen 할당 가정**: TLAB overflow → tenuring promotion 발생.
- **WeakReference cache 의 무한 신뢰**: 매 GC pressure 시 즉시 회수 — cold start.
## 🧪 검증 / 중복
- Verified (Jones et al. *The Garbage Collection Handbook* 2nd ed., OpenJDK ZGC docs 2024).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — GC algorithms + tri-color + JVM/Go tuning patterns |
@@ -0,0 +1,166 @@
---
id: wiki-2026-0508-가상현실-멀미-vr-sickness
title: 가상현실 멀미 (VR Sickness)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [VR Sickness, Cybersickness, Motion Sickness in VR]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [vr, ux, perception, motion-sickness, hmd]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: C#
framework: Unity/Unreal
---
# 가상현실 멀미 (VR Sickness)
## 매 한 줄
> **"매 vestibular (전정) 와 visual (시각) input 의 mismatch 로 발생하는 nausea / disorientation"**. 매 motion sickness 의 inverse — 매 눈은 움직임을 보지만 몸은 정지. 매 90+ FPS, low-latency tracking, comfort locomotion 으로 완화. 매 Quest 3 / Vision Pro 시대에도 여전히 핵심 UX 문제.
## 매 핵심
### 매 원인 (sensory conflict theory)
- **Vection**: 매 visual self-motion 의 인지 (정지한 vestibular 와 conflict).
- **Latency**: motion-to-photon >20ms — 매 멀미 유발.
- **Frame rate dip**: 90Hz → 60Hz drop 의 즉시 swimming sensation.
- **Field of view + speed**: 매 wide FOV + fast translation = 매 worst.
- **Postural instability**: 매 head tracking error / drift.
### 매 완화 기법
- **High refresh rate**: 90/120Hz 표준 (Quest 3 = 120Hz, Vision Pro = 90/96Hz).
- **Low motion-to-photon latency**: <20ms target.
- **Vignette / Tunneling**: 매 turn / locomotion 시 peripheral 차단.
- **Teleport locomotion**: 매 smooth movement 의 회피.
- **Snap turning**: 30/45° discrete rotation.
- **Stable horizon / cockpit**: 매 reference frame 의 제공.
- **Comfort rating**: Comfortable / Moderate / Intense — 매 store labeling.
### 매 응용
1. VR game design (Half-Life: Alyx, Beat Saber).
2. Training sim (medical, military, flight).
3. VR therapy 의 조정 (exposure therapy, PTSD).
4. Industrial design review.
## 💻 패턴
### Unity 의 vignette on locomotion (URP)
```csharp
using UnityEngine;
using UnityEngine.Rendering.Universal;
public class ComfortVignette : MonoBehaviour {
[SerializeField] Volume volume;
Vignette vignette;
public CharacterController player;
void Start() { volume.profile.TryGet(out vignette); }
void Update() {
float speed = player.velocity.magnitude;
// 매 빠를수록 매 강한 vignette
vignette.intensity.value = Mathf.Clamp01(speed / 5f) * 0.6f;
}
}
```
### Snap Turn 구현
```csharp
public class SnapTurn : MonoBehaviour {
public float snapAngle = 30f;
public Transform xrRig;
bool turning;
void Update() {
float x = Input.GetAxis("RightStickX");
if (Mathf.Abs(x) > 0.7f && !turning) {
xrRig.Rotate(0, Mathf.Sign(x) * snapAngle, 0);
turning = true;
}
if (Mathf.Abs(x) < 0.3f) turning = false;
}
}
```
### Teleport locomotion (XR Interaction Toolkit)
```csharp
// XR Interaction Toolkit 의 TeleportationProvider + TeleportationArea 사용.
// 매 thumbstick forward → arc raycast → release → fade-to-black → reposition.
public class TeleportFade : MonoBehaviour {
public ScreenFader fader;
public IEnumerator FadeTeleport(System.Action moveAction) {
yield return fader.FadeOut(0.15f);
moveAction();
yield return fader.FadeIn(0.15f);
}
}
```
### Frame rate budget guard (Unity profiler)
```csharp
void Update() {
float dt = Time.unscaledDeltaTime;
if (dt > 1f / 80f) { // 12.5ms — 90Hz budget 위반
Debug.LogWarning($"Frame {dt*1000:F1}ms — VR comfort risk");
}
}
```
### Stable cockpit reference (vehicle VR)
```csharp
// 매 driver 시점 — 매 cockpit 매 항상 보이도록.
// 매 strong reference frame 으로 vection 감소.
public class CockpitAnchor : MonoBehaviour {
public Transform vehicle;
void LateUpdate() {
transform.position = vehicle.position;
transform.rotation = vehicle.rotation;
}
}
```
### Async time warp / reprojection (built-in to Quest, Vision Pro)
```csharp
// 매 platform 자동 — frame miss 시 last frame 의 reproject.
// 매 dev 작업: 매 frame budget 안정 유지로 reproject 발동 X 가 best.
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 first-person locomotion | teleport + comfort vignette |
| 매 cockpit (car, plane) | smooth motion OK + stable reference frame |
| 매 turning | snap turn (default), smooth turn (option) |
| 매 wide FOV + fast | vignette + reduced FOV |
| 매 cinematic camera | 매 user-controlled — automated camera 의 X |
**기본값**: 매 90Hz+, teleport locomotion, snap turn 30°, comfort vignette, motion-to-photon <20ms.
## 🔗 Graph
- 부모: [[Virtual Reality]]
- 변형: [[Cybersickness]] · [[Simulator Sickness]]
## 🤖 LLM 활용
**언제**: VR UX review, comfort rating 추정, locomotion design feedback.
**언제 X**: 매 individual susceptibility 진단 — 매 user testing 필수.
## ❌ 안티패턴
- **Cinematic forced camera**: 매 user 통제 X — 즉시 멀미.
- **60Hz VR**: 매 사실상 unusable.
- **Floating UI head-locked**: 매 head movement 따라 밀착 → vection.
- **Acceleration-heavy locomotion**: jerk 의 직접 유발.
- **No comfort rating disclosure**: 매 store policy 위반 (Quest, Steam).
## 🧪 검증 / 중복
- Verified (LaViola *3D User Interfaces* 2nd ed. 2017, Meta VR Design Guidelines 2024, Apple visionOS HIG).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — sensory conflict + comfort techniques + Unity patterns |
@@ -0,0 +1,194 @@
---
id: wiki-2026-0508-객체-지향-프로그래밍-object-oriented-prog
title: 객체 지향 프로그래밍 (Object-Oriented Programming)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [OOP, Object-Oriented Programming, 객체지향]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [oop, encapsulation, polymorphism, paradigm]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Java/TS/Python
framework: agnostic
---
# 객체 지향 프로그래밍 (Object-Oriented Programming)
## 매 한 줄
> **"매 state + behavior 를 object 로 묶어 message passing 으로 협력시키는 패러다임"**. Smalltalk (1972) → C++/Java → 매 modern composition-over-inheritance + interface-driven 으로 진화. 매 2026 의 OOP 는 functional core + OO shell 의 hybrid 가 dominant.
## 매 핵심
### 매 4 기둥
- **Encapsulation**: state 의 hide + 매 invariant 의 보호.
- **Abstraction**: 매 interface 만 노출 — implementation hide.
- **Inheritance**: 매 sub-class 의 reuse — 매 fragile base class 위험.
- **Polymorphism**: subtype / parametric / ad-hoc — 매 substitutability.
### 매 modern OOP 의 best practice
- **Composition > Inheritance**: 매 has-a >> is-a.
- **Program to interface**: 매 concrete type 의 dependency X.
- **SOLID**: SRP / OCP / LSP / ISP / DIP.
- **Immutable by default**: record / data class / value object.
### 매 응용
1. UI framework (React class — but hooks shifted toward functional).
2. Game engine (Unity GameObject / Component).
3. ORM entity (JPA / SQLAlchemy / Active Record).
4. GUI (Swing, Qt, AppKit).
## 💻 패턴
### Encapsulation + invariant
```java
public class Account {
private long balanceCents; // private = hidden
public void deposit(long cents) {
if (cents <= 0) throw new IllegalArgumentException();
this.balanceCents += cents;
}
public long getBalanceCents() { return balanceCents; }
// 매 setter 없음 — invariant 보호
}
```
### Polymorphism (interface)
```typescript
interface PaymentMethod {
charge(amountCents: number): Promise<TxResult>;
}
class StripeCard implements PaymentMethod {
async charge(c: number) { /* stripe sdk */ return { ok: true }; }
}
class Paypal implements PaymentMethod {
async charge(c: number) { /* paypal sdk */ return { ok: true }; }
}
async function checkout(pm: PaymentMethod, total: number) {
return pm.charge(total); // 매 same call, different impl
}
```
### Composition over Inheritance
```typescript
// ❌ Inheritance hell
// class FlyingFish extends Fish, Bird {} — multiple inheritance 문제
// ✅ Composition
interface Swim { swim(): void }
interface Fly { fly(): void }
class Fish implements Swim { swim() { console.log("swim"); } }
class Bird implements Fly { fly() { console.log("fly"); } }
class FlyingFish implements Swim, Fly {
private swimmer = new Fish();
private flyer = new Bird();
swim() { this.swimmer.swim(); }
fly() { this.flyer.fly(); }
}
```
### Strategy Pattern
```python
from typing import Protocol
class SortStrategy(Protocol):
def sort(self, data: list[int]) -> list[int]: ...
class QuickSort:
def sort(self, data): return sorted(data)
class BubbleSort:
def sort(self, data):
d = data[:]
for i in range(len(d)):
for j in range(len(d)-i-1):
if d[j] > d[j+1]: d[j], d[j+1] = d[j+1], d[j]
return d
class Sorter:
def __init__(self, strategy: SortStrategy):
self.strategy = strategy
def run(self, data):
return self.strategy.sort(data)
```
### Dependency Injection
```java
@Service
class OrderService {
private final OrderRepo repo;
private final PaymentGateway gateway;
public OrderService(OrderRepo r, PaymentGateway g) { // constructor inject
this.repo = r; this.gateway = g;
}
}
```
### Immutable Value Object (Java record)
```java
public record Money(long cents, String currency) {
public Money {
if (cents < 0) throw new IllegalArgumentException();
}
public Money add(Money other) {
if (!currency.equals(other.currency)) throw new IllegalArgumentException();
return new Money(cents + other.cents, currency);
}
}
```
### Sealed Hierarchy (Java 17+, Kotlin, Scala)
```java
public sealed interface Shape permits Circle, Square, Triangle {}
public record Circle(double r) implements Shape {}
public record Square(double s) implements Shape {}
public record Triangle(double a, double b, double c) implements Shape {}
double area(Shape s) {
return switch (s) { // exhaustive
case Circle c -> Math.PI * c.r() * c.r();
case Square q -> q.s() * q.s();
case Triangle t -> { /* heron */ yield 0; }
};
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 stateful entity (User, Order) | OOP class + invariant |
| 매 stateless transformation | functional / pure function |
| 매 plugin / extensibility | interface + DI |
| 매 data-only | record / dataclass |
| 매 algorithm dispatch | strategy / sealed + switch |
**기본값**: 매 immutable record + composition + interface + constructor DI. 매 deep inheritance 의 X.
## 🔗 Graph
- 변형: [[Functional Programming]]
- 응용: [[Design Patterns]] · [[SOLID]]
- Adjacent: [[Domain-Driven Design]] · [[TypeScript 타입 시스템 (TypeScript Type System)|Type Systems]] · [[Encapsulation]]
## 🤖 LLM 활용
**언제**: class design review, SOLID 위반 발견, refactor toward composition.
**언제 X**: 매 simple data transformation script — function 으로 충분.
## ❌ 안티패턴
- **God Object**: 1000+ method 의 single class.
- **Yo-yo Inheritance**: 매 6 단 deep — 매 행위 추적 불가.
- **Anemic Object**: getter/setter 만, behavior 누락.
- **Setter explosion**: 매 invariant 의 무력화.
- **Tight coupling to concrete class**: 매 testability X.
## 🧪 검증 / 중복
- Verified (Gamma et al. *GoF Design Patterns* 1994, Martin *Clean Architecture* 2017).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 4 기둥 + composition + sealed hierarchy + DI |
@@ -0,0 +1,215 @@
---
id: wiki-2026-0508-견고한-도메인-모델-및-api-계약-설계
title: 견고한 도메인 모델 및 API 계약 설계
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Domain Model Design, API Contract Design, DDD]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [ddd, domain-model, api-design, contract, type-driven]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript/Java
framework: Zod/Pydantic/OpenAPI
---
# 견고한 도메인 모델 및 API 계약 설계
## 매 한 줄
> **"매 type-driven domain model + 매 versioned API contract 의 결합으로 매 invalid state 를 unrepresentable 로 만든다"**. 매 DDD aggregate + value object + Zod/Pydantic schema + OpenAPI contract — 매 2024 modern stack.
## 매 핵심
### 매 도메인 모델 의 견고함
- **Value Object**: 매 immutable + equality by value (Money, Email, OrderId).
- **Entity / Aggregate Root**: 매 identity + lifecycle + invariant 보호.
- **Make illegal states unrepresentable**: 매 sum type / discriminated union 사용.
- **Smart Constructor**: 매 raw type → validated branded type 의 single entry.
### 매 API 계약 의 견고함
- **Schema-first**: OpenAPI / JSON Schema / GraphQL SDL — 매 source of truth.
- **Backward compat**: additive change only, 매 deprecation header, version in URL/header.
- **Idempotency key**: 매 mutation 의 retry-safe 화.
- **Pagination + filter + sort 표준화**: cursor-based >>> offset-based.
### 매 응용
1. e-commerce checkout (Money, Cart, Order aggregate).
2. Banking (Account, Transaction, immutable ledger).
3. Multi-tenant SaaS (Tenant 의 invariant 격리).
4. Public API (Stripe-style versioned contract).
## 💻 패턴
### 매 Branded type (TS) — primitive obsession 의 회피
```typescript
type Brand<T, B> = T & { __brand: B };
type Email = Brand<string, "Email">;
type UserId = Brand<string, "UserId">;
const parseEmail = (s: string): Email => {
if (!/^[^@]+@[^@]+$/.test(s)) throw new Error("Invalid email");
return s as Email;
};
function send(to: Email, msg: string) { /* ... */ }
send("not-email" as Email, "x"); // unsafe cast 만 통과 — 매 explicit
send(parseEmail("a@b.com"), "x"); // safe path
```
### Value Object (Money)
```typescript
class Money {
private constructor(readonly amount: bigint, readonly currency: string) {}
static of(amount: number, currency: string) {
if (!Number.isFinite(amount)) throw new Error("non-finite");
return new Money(BigInt(Math.round(amount * 100)), currency);
}
add(other: Money) {
if (this.currency !== other.currency) throw new Error("currency mismatch");
return new Money(this.amount + other.amount, this.currency);
}
equals(other: Money) {
return this.amount === other.amount && this.currency === other.currency;
}
}
```
### 매 illegal state unrepresentable (TS discriminated union)
```typescript
type OrderState =
| { kind: "draft"; cart: CartLine[] }
| { kind: "placed"; orderId: OrderId; placedAt: Date }
| { kind: "shipped"; orderId: OrderId; tracking: string }
| { kind: "cancelled"; reason: string };
function summary(o: OrderState) {
switch (o.kind) {
case "draft": return `Draft (${o.cart.length} items)`;
case "placed": return `Placed ${o.orderId}`;
case "shipped": return `Shipped ${o.tracking}`;
case "cancelled": return `Cancelled: ${o.reason}`;
}
}
```
### Zod schema (runtime + static type)
```typescript
import { z } from "zod";
const CreateOrderSchema = z.object({
customerId: z.string().uuid(),
items: z.array(z.object({
sku: z.string().min(1),
qty: z.number().int().positive().max(1000)
})).min(1),
idempotencyKey: z.string().uuid()
});
type CreateOrderReq = z.infer<typeof CreateOrderSchema>;
app.post("/orders", (req, res) => {
const parsed = CreateOrderSchema.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ errors: parsed.error.issues });
// parsed.data is fully typed
});
```
### Aggregate Root (invariant protection)
```typescript
class Order {
private constructor(
readonly id: OrderId,
private state: OrderState,
private lines: OrderLine[]
) {}
addLine(line: OrderLine) {
if (this.state.kind !== "draft") throw new Error("cannot modify placed order");
if (this.lines.length >= 50) throw new Error("max 50 lines");
this.lines.push(line);
}
place(): void {
if (this.lines.length === 0) throw new Error("empty cart");
this.state = { kind: "placed", orderId: this.id, placedAt: new Date() };
}
}
```
### OpenAPI 의 versioned contract
```yaml
# openapi.yaml
openapi: 3.1.0
info: { title: Orders API, version: "2026-05-01" }
paths:
/v1/orders:
post:
parameters:
- in: header
name: Idempotency-Key
required: true
schema: { type: string, format: uuid }
requestBody:
content:
application/json:
schema: { $ref: '#/components/schemas/CreateOrder' }
responses:
'201': { $ref: '#/components/responses/Order' }
'409': { description: Idempotency conflict }
```
### Cursor pagination
```typescript
type Page<T> = { items: T[]; nextCursor: string | null };
async function listOrders(cursor?: string): Promise<Page<OrderDto>> {
const rows = await db.query(
"SELECT * FROM orders WHERE id > $1 ORDER BY id LIMIT 51",
[cursor ?? ""]
);
const hasMore = rows.length === 51;
const items = rows.slice(0, 50);
return {
items: items.map(toDto),
nextCursor: hasMore ? items[items.length - 1].id : null
};
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 simple CRUD | DTO + validator (Zod/Pydantic) — DDD overkill |
| 매 complex domain (banking, scheduling) | Aggregate + VO + invariant |
| 매 public API | OpenAPI contract-first + version |
| 매 internal RPC | gRPC / tRPC + protobuf / TS infer |
| 매 event-driven | event schema (Avro/protobuf) + registry |
**기본값**: 매 schema-first (Zod / OpenAPI) + branded ID + idempotency + cursor pagination.
## 🔗 Graph
- 부모: [[Domain-Driven Design]] · [[API Design]]
- 변형: [[Hexagonal Architecture]] · [[Event Sourcing]] · [[CQRS]]
- Adjacent: [[OpenAPI]] · [[gRPC]]
## 🤖 LLM 활용
**언제**: schema generation, contract review, illegal-state 발견, migration 전략.
**언제 X**: 매 internal throwaway script — 매 over-engineering.
## ❌ 안티패턴
- **Primitive Obsession**: string everywhere — UserId 와 OrderId 의 swap silent.
- **Anemic Domain**: getter/setter 만, business logic 의 service 누설.
- **Shared Mutable Aggregate**: 매 invariant 의 broken.
- **Breaking change in v1 endpoint**: 매 client 의 parallel 운영 X.
## 🧪 검증 / 중복
- Verified (Evans *DDD* 2003, Vernon *Implementing DDD* 2013, Stripe API design guide 2024).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — branded types + Zod + OpenAPI + aggregate patterns |
@@ -0,0 +1,152 @@
---
id: wiki-2026-0508-계층화-아키텍처-layered-architecture
title: 계층화 아키텍처 (Layered Architecture)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Layered Architecture, N-tier, Tiered Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, layering, separation-of-concerns, n-tier]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: agnostic
framework: Spring/.NET/Django
---
# 계층화 아키텍처 (Layered Architecture)
## 매 한 줄
> **"매 application 을 horizontal layer (presentation / business / persistence / data) 의 stack 으로 조직"**. 매 가장 흔한 default architecture — 매 simple, 매 onboarding 쉬움. 매 large-scale 에서 coupling/performance 한계 발생 → microservice/hexagonal 로 진화.
## 매 핵심
### 매 표준 layer
- **Presentation**: UI / REST controller / GraphQL resolver. 매 input 의 validation + serialization.
- **Business / Service**: domain logic, transaction boundary, orchestration.
- **Persistence / Repository**: ORM, query, cache.
- **Data**: DB, file, message broker.
### 매 strict vs relaxed
- **Strict layering**: 매 layer N 은 layer N-1 만 호출 가능. 매 testability 좋음.
- **Relaxed**: layer skip 가능 (e.g. controller → repository 직접). 매 anti-pattern 으로 간주.
### 매 응용
1. Spring Boot 의 @Controller / @Service / @Repository.
2. Django 의 view / business / model.
3. Clean Architecture 의 adapter ring 변형.
4. .NET 의 N-tier WebAPI / BLL / DAL.
## 💻 패턴
### Spring Boot 의 표준 3-layer
```java
@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderService service;
public OrderController(OrderService s) { this.service = s; }
@PostMapping
public OrderDto create(@RequestBody @Valid CreateOrderReq req) {
return service.create(req);
}
}
@Service
public class OrderService {
private final OrderRepo repo;
@Transactional
public OrderDto create(CreateOrderReq req) {
Order o = Order.from(req);
return OrderDto.from(repo.save(o));
}
}
@Repository
public interface OrderRepo extends JpaRepository<Order, Long> {}
```
### DTO ↔ Domain 매 boundary
```java
// 매 controller 는 DTO 만, service 는 domain entity 만 다룬다.
public record CreateOrderReq(String sku, int qty) {}
public record OrderDto(Long id, String sku, int qty, String status) {
public static OrderDto from(Order o) {
return new OrderDto(o.getId(), o.getSku(), o.getQty(), o.getStatus().name());
}
}
```
### Repository abstraction (testability)
```java
public interface OrderRepo {
Order save(Order o);
Optional<Order> findById(Long id);
}
// 매 unit test 의 Stub repository 의 inject:
class StubOrderRepo implements OrderRepo { /* in-memory */ }
```
### 매 cross-cutting (logging / tx / auth) 의 AOP
```java
@Aspect
@Component
class AuditAspect {
@Around("@annotation(Audited)")
public Object audit(ProceedingJoinPoint pjp) throws Throwable {
long t0 = System.nanoTime();
Object result = pjp.proceed();
log.info("{} took {}ns", pjp.getSignature(), System.nanoTime() - t0);
return result;
}
}
```
### Layer 의 dependency rule (안티: upward call)
```java
// ❌ Service 가 Controller 호출 X
// ❌ Repository 가 Service 호출 X
// ✅ 매 한 방향: presentation → service → persistence
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| CRUD-heavy MVP | 매 layered (default 선택) |
| 매 complex domain logic | hexagonal / clean architecture |
| 매 high decoupling 필요 | event-driven / CQRS |
| 매 large team / bounded context | microservice |
| 매 simple script | 매 layer X — single file |
**기본값**: 매 small/medium app 은 **3-layer (controller / service / repository)** + DI + DTO boundary.
## 🔗 Graph
- 부모: [[Software Architecture]]
- 변형: [[Hexagonal Architecture]] · [[Clean Architecture]] · [[Onion Architecture]]
- 응용: [[Spring Boot]] · [[ASP.NET Core]]
- Adjacent: [[Separation of Concerns]] · [[Dependency Injection]]
## 🤖 LLM 활용
**언제**: scaffolding generation, layer 위반 review, refactor towards layered.
**언제 X**: 매 trivial CRUD — boilerplate overhead.
## ❌ 안티패턴
- **Anemic Service**: 매 service 가 단순 repo passthrough — domain logic 누락.
- **Smart Controller**: business logic 의 controller 누수.
- **Layer skip**: controller 가 repo 직접 호출.
- **God Service**: 매 service class 가 5000+ lines — bounded context 분할 필요.
## 🧪 검증 / 중복
- Verified (Richards *Software Architecture Patterns* 2nd ed. 2022).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — layered patterns + Spring example + anti-patterns |
@@ -0,0 +1,146 @@
---
id: wiki-2026-0508-과잉-속성-체크-excess-property-checkin
title: 과잉 속성 체크 (Excess Property Checking)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Excess Property Checking, EPC, TS Excess Property]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-system, structural-typing, epc]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: TS 5.x
---
# 과잉 속성 체크 (Excess Property Checking)
## 매 한 줄
> **"매 object literal 을 직접 assign / pass 할 때만 발동하는 TS 의 추가 strictness rule"**. 매 structural typing 의 원칙적으론 OK 인 extra property 를 매 fresh object literal 에 한해 error 로 잡아 typo 방지. 매 변수 경유 시 자동 비활성화.
## 매 핵심
### 매 작동 방식
- TS 의 **structural / duck typing** 은 매 extra property OK.
- 그러나 매 **object literal 을 fresh 하게 assign 시** TS 는 추가로 surplus key 를 error 로 보고.
- 매 변수에 한 번 alias 하면 fresh 신호가 사라져 EPC 우회.
### 매 발동 조건
- 매 object literal 의 직접 assignment / argument / return.
- 매 contextual type 이 존재.
- 매 변수 경유, type assertion (`as`), spread 시 비활성화.
### 매 응용
1. Component prop typo 방지 (React).
2. API request body 의 surplus field 차단.
3. Config object 의 misnamed key 발견.
## 💻 패턴
### 매 EPC 발동 (error)
```typescript
interface User { name: string; age: number }
const u: User = { name: "Lee", age: 30, emial: "x" };
// ^^^^^ 매 EPC: 'emial' does not exist on User
```
### 매 변수 경유 우회 (error 사라짐)
```typescript
const raw = { name: "Lee", age: 30, emial: "x" };
const u: User = raw; // ✅ OK — fresh 아니라 EPC 비활성
// 매 structural compatibility 만 본다 (User 의 모든 prop 충족 → OK)
```
### 매 함수 인자 EPC
```typescript
function greet(u: User) { console.log(u.name); }
greet({ name: "A", age: 1, extra: 1 }); // ❌ EPC error
const x = { name: "A", age: 1, extra: 1 };
greet(x); // ✅ OK
```
### 매 index signature 의 escape hatch
```typescript
interface Loose {
name: string;
[key: string]: unknown;
}
const l: Loose = { name: "A", whatever: 123, deep: { x: 1 } }; // ✅ OK
```
### 매 union type 의 EPC quirk
```typescript
type A = { kind: "a"; a: number };
type B = { kind: "b"; b: number };
const x: A | B = { kind: "a", a: 1, b: 2 };
// ❌ EPC: 'b' is not in A; not in B 의 fresh form
// 매 변수 경유 시 통과 — 의도치 않은 leakage 가능
```
### 매 의도적 우회 (type assertion — 위험)
```typescript
const u: User = { name: "A", age: 1, emial: "x" } as User;
// ⚠ 매 작동하지만 매 typo 의 silent — 매 강력히 X
```
### 매 React component prop typo 방지
```typescript
type ButtonProps = { label: string; onClick: () => void };
const Button = (p: ButtonProps) => <button onClick={p.onClick}>{p.label}</button>;
<Button labl="Hi" onClick={() => {}} />; // ❌ EPC: 'labl' typo 발견
```
### 매 satisfies operator (TS 4.9+) — 매 EPC 유지 + inference
```typescript
const config = {
port: 8080,
host: "localhost",
// typoKey: 1 // ❌ EPC error if uncomment
} satisfies { port: number; host: string };
// 매 config.port: number 의 narrow type 유지 + EPC 활성
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 strict typo 검출 | 매 object literal 직접 assign + EPC 활용 |
| 매 동적 key 다수 | index signature 추가 |
| 매 narrow + EPC 동시 | `satisfies` operator |
| 매 변수 경유 필요 | type annotation 변수 + literal 사용 |
| 매 EPC 의도적 회피 | 매 보통 X — type 의 재설계 |
**기본값**: 매 object literal 의 직접 assign + `satisfies` 또는 explicit type — 매 변수 경유 의 무의식적 우회 X.
## 🔗 Graph
- 부모: [[TypeScript]] · [[구조적 타이핑(Structural Typing)]]
- 변형: [[satisfies operator]]
- 응용: [[API Contract]]
- Adjacent: [[Type Narrowing]] · [[Discriminated Union]]
## 🤖 LLM 활용
**언제**: TS error 디버깅 ("excess property"), refactor 시 EPC 의도 검증.
**언제 X**: 매 runtime validation — 매 EPC 는 컴파일타임만.
## ❌ 안티패턴
- **as Type 으로 EPC 회피**: 매 typo 의 silent.
- **변수 경유 의 우회**: 매 의도면 OK, 매 실수면 위험.
- **EPC 비활성화 의 흔한 오해**: 매 spread `{ ...x, extra: 1 }` 의 fresh — EPC 발동.
- **runtime 신뢰**: EPC 는 매 compile-time only — 매 런타임 검증 X.
## 🧪 검증 / 중복
- Verified (TypeScript Handbook — Object Types, TS 5.x source).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — EPC 발동 조건 + 우회 + satisfies |
@@ -0,0 +1,177 @@
---
id: wiki-2026-0508-관심사의-분리-separation-of-concerns
title: 관심사의 분리 (Separation of Concerns)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [SoC, Separation of Concerns, 관심사 분리]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [soc, modularity, design-principle, architecture]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: agnostic
framework: agnostic
---
# 관심사의 분리 (Separation of Concerns)
## 매 한 줄
> **"매 system 을 서로 겹치지 않는 concern 단위로 쪼개 각각이 독립 변경 가능하도록 한다"**. Dijkstra (1974) — 매 modularity 의 근본 원리. 매 layer / module / function / file 모든 scale 에 적용. 매 변경의 locality + 매 testability 를 동시에 얻는다.
## 매 핵심
### 매 SoC 의 본질
- **Concern**: 매 system 이 처리하는 distinct topic (UI, persistence, billing, auth).
- **Separation**: 매 concern 별로 코드/모듈/팀/배포 단위 분리.
- **Independent change**: concern A 의 변경이 B 의 코드 수정 X.
### 매 적용 scale
- **Function**: 매 single responsibility (SRP).
- **Module**: 매 cohesion 높음 + coupling 낮음.
- **Layer**: presentation / business / persistence (layered arch).
- **Service**: bounded context / microservice.
- **Repository**: monorepo path / multirepo.
### 매 응용
1. MVC / MVP / MVVM.
2. Clean / Hexagonal Architecture (port-adapter 분리).
3. Aspect-Oriented Programming (cross-cutting 분리).
4. Microservice (bounded context 분리).
5. CSS-in-JS vs separate stylesheet — 매 variant.
## 💻 패턴
### Function-level: 매 1 함수 = 1 개념
```typescript
// ❌ Mixed
function processOrder(input: any) {
if (!input.email) throw new Error("invalid"); // validation
const tax = input.amount * 0.1; // tax calc
db.execute("INSERT INTO orders ..."); // persistence
smtp.send(input.email, "Confirmed"); // notification
}
// ✅ Separated
function validate(input: OrderInput): Order { /* ... */ return order; }
function computeTax(order: Order): Money { /* ... */ }
async function persist(order: Order, tax: Money): Promise<OrderId> { /* ... */ }
async function notify(order: Order): Promise<void> { /* ... */ }
async function processOrder(input: OrderInput) {
const order = validate(input);
const tax = computeTax(order);
const id = await persist(order, tax);
await notify(order);
return id;
}
```
### Module: 매 dependency direction
```
src/
├── domain/ ← 매 pure logic (no IO)
├── application/ ← 매 use cases (orchestration)
├── infrastructure/ ← DB, HTTP, queue
└── interface/ ← controller, CLI
```
### MVC (web)
```python
# model.py
class User: ...
# view.py (template)
def render_user(user): ...
# controller.py
def get_user(req):
user = User.find(req.params["id"])
return render_user(user)
```
### CSS 분리 (concern: layout / theme / interaction)
```css
/* layout.css */
.container { display: grid; grid-template-columns: 240px 1fr; }
/* theme.css */
:root { --bg: #fff; --fg: #111; }
.dark { --bg: #111; --fg: #eee; }
/* interaction.css */
.btn:hover { transform: translateY(-1px); }
```
### Hexagonal port-adapter
```typescript
// domain port (concern: business)
export interface OrderRepo {
save(o: Order): Promise<void>;
findById(id: OrderId): Promise<Order | null>;
}
// adapter (concern: infra)
export class PostgresOrderRepo implements OrderRepo { /* SQL */ }
export class InMemoryOrderRepo implements OrderRepo { /* test */ }
```
### AOP (cross-cutting) — Spring
```java
@Aspect @Component
class TxAspect {
@Around("@annotation(Transactional)")
Object inTx(ProceedingJoinPoint pjp) throws Throwable {
var tx = txManager.begin();
try { var r = pjp.proceed(); tx.commit(); return r; }
catch (Throwable t) { tx.rollback(); throw t; }
}
}
// 매 business code 에서 tx 코드 누설 X
```
### Bounded context (microservice 단위)
```
billing-service/ ← 매 invoice, charge
inventory-service/ ← 매 stock
shipping-service/ ← 매 carrier integration
# 매 각자 DB, 각자 deploy, 각자 schema
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 small script | function-level SRP 만 |
| 매 medium app | layered + module 단위 |
| 매 complex domain | hexagonal + bounded context |
| 매 large org | microservice + team boundary |
| 매 cross-cutting (log, tx, auth) | AOP / middleware / interceptor |
**기본값**: 매 layered + DI + interface boundary. 매 over-fragmentation (매 1 함수 1 파일) 의 X.
## 🔗 Graph
- 부모: [[Software Design Principles]]
- 변형: [[Single Responsibility Principle (SRP)|Single Responsibility Principle]] · [[Modularity]]
- 응용: [[Layered Architecture]] · [[Hexagonal Architecture]] · [[Microservices]]
- Adjacent: [[SOLID]] · [[Aspect-Oriented Programming (AOP)|Aspect-Oriented Programming]]
## 🤖 LLM 활용
**언제**: refactor proposal, code smell detection (mixed concerns), boundary 설정.
**언제 X**: 매 throwaway script — overhead 만.
## ❌ 안티패턴
- **God Module / God File**: 매 모든 concern 의 mix.
- **Shotgun Surgery**: 매 1 변경이 매 N 파일 수정 — 매 concern 의 분산 잘못.
- **Premature decomposition**: 매 unclear boundary 의 microservice 분할 — 매 distributed monolith.
- **Leaky abstraction**: 매 infra 의 domain 누수 (e.g. ORM annotation 의 domain entity 노출).
## 🧪 검증 / 중복
- Verified (Dijkstra "On the role of scientific thought" 1974, Parnas "On the Criteria To Be Used in Decomposing Systems into Modules" 1972).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — SoC 본질 + scale + MVC + hexagonal + AOP |
@@ -0,0 +1,33 @@
---
id: wiki-20260508--aop--redir
title: 관점 지향 프로그래밍 (AOP)
category: 10_Wiki/Topics
status: duplicate
canonical_id: aspect-oriented-programming
duplicate_of: "[[Aspect-Oriented Programming (AOP)|Aspect-Oriented Programming]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, aop, paradigm]
last_reinforced: 2026-05-10
github_commit: pending
---
# 관점 지향 프로그래밍 (AOP)
> **이 문서는 [[Aspect-Oriented Programming (AOP)|Aspect-Oriented Programming]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- 매 cross-cutting concern (logging, security) 의 aspect 의 weave.
- 매 Spring AOP, AspectJ 의 example.
## 🔗 Graph
- 부모: [[Aspect-Oriented Programming (AOP)|Aspect-Oriented Programming]] (canonical)
- Adjacent: [[Separation of Concerns]] · [[OOP]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,31 @@
---
id: wiki-20260508--aop--redir-2
title: 관점 지향 프로그래밍(AOP)
category: 10_Wiki/Topics
status: duplicate
canonical_id: aspect-oriented-programming
duplicate_of: "[[Aspect-Oriented Programming (AOP)|Aspect-Oriented Programming]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, aop, paradigm]
last_reinforced: 2026-05-10
github_commit: pending
---
# 관점 지향 프로그래밍(AOP)
> **이 문서는 [[Aspect-Oriented Programming (AOP)|Aspect-Oriented Programming]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- 매 spacing variant 의 동일 concept.
## 🔗 Graph
- 부모: [[Aspect-Oriented Programming (AOP)|Aspect-Oriented Programming]] (canonical)
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,155 @@
---
id: wiki-2026-0508-구조적-타이핑-structural-typing
title: 구조적 타이핑(Structural Typing)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Structural Typing, Duck Typing (static), 구조적 타이핑]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-system, structural-typing, go-interface]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript/Go
framework: TS 5.x / Go 1.22+
---
# 구조적 타이핑(Structural Typing)
## 매 한 줄
> **"매 type compatibility 를 name 이 아닌 shape (members) 으로 판단하는 type system"**. 매 Go interface, TypeScript, OCaml object 가 대표적. 매 nominal 의 정반대 — 매 "if it walks like a duck" 의 static 버전.
## 매 핵심
### 매 nominal vs structural
- **Nominal** (Java, C#): 매 declared 동일 type / inheritance 만 호환.
- **Structural** (TS, Go interface, OCaml): 매 같은 shape 면 호환 — 매 declaration 무관.
### 매 TS 의 작동
- 매 interface / type alias 는 매 shape 만 정의.
- 매 assignment / argument 시 매 source 가 target 의 모든 required member 를 가지면 OK.
- 매 extra member 는 OK (단, EPC 는 fresh literal 에서만 차단).
### 매 Go interface 의 implicit satisfaction
- Go 는 매 `implements` 키워드 X — 매 method set 만족 시 자동 satisfy.
### 매 응용
1. Mock / test double 의 trivial implementation.
2. Adapter 의 boilerplate 절감.
3. Library 간 type 의 cross-compat.
4. Type-driven design — 매 minimal interface.
## 💻 패턴
### TS structural compatibility
```typescript
interface Named { name: string }
class Cat { name = "Tom"; meow() {} }
const x: Named = new Cat(); // ✅ Cat 이 Named 를 implements 선언 X 이지만 OK
```
### TS interface vs nominal-like brand
```typescript
// 매 nominal-style (brand)
type Email = string & { __brand: "Email" };
type UserId = string & { __brand: "UserId" };
const e: Email = "a@b.com" as Email;
const u: UserId = e; // ❌ brand mismatch — 매 nominal-like 차단
```
### Go interface 의 implicit satisfy
```go
type Reader interface { Read(p []byte) (int, error) }
type FileR struct{ /* ... */ }
func (f *FileR) Read(p []byte) (int, error) { /* ... */ return 0, nil }
var r Reader = &FileR{} // ✅ implements 선언 없음 — 매 method 매 충족
```
### Duck-typing function
```typescript
function logName(x: { name: string }) {
console.log(x.name);
}
logName({ name: "A", age: 1 }); // ✅ extra OK — fresh 시 EPC 발동 가능
const obj = { name: "A", age: 1 };
logName(obj); // ✅ 매 EPC 비활성
```
### 매 minimal interface principle (Go)
```go
// ❌ huge interface
// type Storage interface { Save, Load, Delete, List, ... }
// ✅ 매 small interface, compose by need
type Saver interface { Save(k string, v []byte) error }
type Loader interface { Load(k string) ([]byte, error) }
// 매 caller 가 필요한 것만 require
```
### Type narrowing via shape (TS)
```typescript
function area(s: { kind: "circle"; r: number } | { kind: "rect"; w: number; h: number }) {
if (s.kind === "circle") return Math.PI * s.r * s.r; // shape narrowed
return s.w * s.h;
}
```
### 매 over-structural 의 safety hole
```typescript
interface Meter { value: number }
interface Foot { value: number }
const m: Meter = { value: 5 };
const f: Foot = m; // ✅ 매 structural — 매 meter/foot mix-up — 매 brand 로 막아라
```
### satisfies + structural (TS 4.9+)
```typescript
const config = {
port: 8080,
host: "localhost"
} satisfies { port: number; host: string };
// 매 structural compat 확인 + 매 narrow type 유지 + EPC 발동
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 mocking / testing | structural — 매 trivial fake |
| 매 minimal coupling | minimal interface (Go style) |
| 매 unit safety (Email vs UserId) | brand / nominal-emulation |
| 매 cross-library | structural compat |
| 매 enum / discriminator | tagged union (kind: "...") |
**기본값**: 매 TS / Go 의 structural 활용 + 매 unit safety 가 필요한 곳만 brand. 매 모든 type 의 brand 의 X.
## 🔗 Graph
- 부모: [[TypeScript 타입 시스템 (TypeScript Type System)|Type Systems]]
- 변형: [[Nominal-Typing-in-TypeScript|Nominal Typing]] · [[Duck Typing]]
- 응용: [[TypeScript]]
- Adjacent: [[과잉 속성 체크 (Excess Property Checking)]] · [[Branded Type]] · [[Discriminated Union]]
## 🤖 LLM 활용
**언제**: type design review, interface 의 minimization, structural mismatch 디버깅.
**언제 X**: 매 runtime type check — 매 structural 은 compile-time only.
## ❌ 안티패턴
- **Big interface (fat interface)**: 매 caller 의 dependency surface 폭증.
- **Unit confusion**: 매 Meter / Foot / UserId / OrderId 의 swap silent — 매 brand 필수.
- **Structural 의 implicit reliance**: 매 refactor 시 silent breakage — 매 explicit type annotation 권장.
## 🧪 검증 / 중복
- Verified (TypeScript Handbook, Pierce *Types and Programming Languages* 2002, Go Spec).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — TS + Go structural + brand + minimal interface |
@@ -0,0 +1,188 @@
---
id: wiki-2026-0508-넷플릭스-코스모스-플랫폼-netflix-cosmos
title: 넷플릭스 코스모스 플랫폼 (Netflix Cosmos)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Netflix Cosmos, Cosmos Platform, Netflix Media Cloud]
duplicate_of: none
source_trust_level: A
confidence_score: 0.85
verification_status: applied
tags: [netflix, distributed-systems, media-processing, workflow-engine, microservices]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: Java/Kotlin
framework: Cosmos/SpringBoot/Kafka
---
# 넷플릭스 코스모스 플랫폼 (Netflix Cosmos)
## 매 한 줄
> **"매 media-aware microservice platform — 매 workflow + service + resource 의 三位一體"**. Netflix 가 2018-2020 사이 transcoding/encoding 전용 Reloaded 플랫폼을 대체하기 위해 설계, 매 모든 media operation 을 매 stateless service + persistent workflow + resource manager 의 trinity 패턴으로 표준화. 2026 년 현재 매 Netflix 의 비-스트리밍 영상 pipeline 전체가 Cosmos 위에서 동작.
## 매 핵심
### 매 정의
- 매 platform-as-a-product — 매 application team 이 Cosmos 위에 service deploy.
- 매 trinity = **Optimus** (API/service) + **Plato** (workflow) + **Stratum** (compute pool).
- 매 event-driven, 매 Kafka backbone, 매 Java + Spring Boot.
### 매 trinity component
- **Optimus**: 매 external-facing API. 매 stateless. 매 request validation + result aggregation.
- **Plato**: 매 long-running workflow engine. 매 rule-based. 매 retry, 매 saga, 매 fork-join 표현.
- **Stratum**: 매 elastic compute pool — 매 ffmpeg/encoder/ML inference 매 GPU/CPU.
### 매 응용
1. Encoding pipeline (4K HDR, AV1).
2. Studio post-production (color, VFX).
3. Subtitle/dubbing automation.
4. Trailer generation, content safety scan.
## 💻 패턴
### Optimus service skeleton (Spring Boot)
```java
@RestController
@RequestMapping("/v1/encode")
public class EncodeOptimus {
private final PlatoClient plato;
@PostMapping
public EncodeResponse submit(@RequestBody EncodeRequest req) {
validate(req);
var workflowId = plato.start("encode-workflow-v3", Map.of(
"sourceUri", req.sourceUri(),
"profiles", req.profiles()
));
return new EncodeResponse(workflowId);
}
}
```
### Plato workflow definition (rule-based DSL)
```yaml
workflow:
id: encode-workflow-v3
rules:
- when: workflow.started
do:
- probe-source
- when: probe-source.completed
do:
- fanout:
for: each profile in input.profiles
run: encode-segment
- when: all encode-segment.completed
do:
- mux-final
- publish-manifest
- when: any.failed
retry:
max: 3
backoff: exponential
onExhausted:
- notify-oncall
```
### Stratum job submission
```java
StratumJob job = StratumJob.builder()
.image("netflixoss/ffmpeg-encoder:av1-v12")
.gpu(1, "A100")
.cpu(8)
.memory("32Gi")
.input(new S3Uri("s3://prod-mezz/" + sourceKey))
.output(new S3Uri("s3://prod-encoded/" + outKey))
.args(List.of("-c:v", "libaom-av1", "-crf", "30"))
.timeout(Duration.ofMinutes(45))
.build();
CompletableFuture<JobResult> result = stratum.submit(job);
```
### Event-driven step coordination
```java
public class EncodeSegmentHandler {
@KafkaListener(topics = "cosmos.workflow.events")
public void onEvent(WorkflowEvent ev) {
if (ev.type() != EventType.STEP_STARTED) return;
if (!ev.stepName().equals("encode-segment")) return;
var profile = ev.payload().get("profile");
var jobResult = stratum.submit(buildJob(profile));
jobResult.whenComplete((r, err) -> {
if (err != null) plato.failStep(ev.stepId(), err);
else plato.completeStep(ev.stepId(), Map.of("output", r.outputUri()));
});
}
}
```
### Fanout-fanin (parallel encode)
```java
public class FanoutFaninCoordinator {
public void onProbeComplete(WorkflowContext ctx) {
List<String> profiles = ctx.input("profiles");
List<CompletableFuture<Void>> tasks = profiles.stream()
.map(p -> startEncodeSegment(ctx, p))
.toList();
CompletableFuture.allOf(tasks.toArray(new CompletableFuture[0]))
.thenRun(() -> ctx.signal("all-segments-done"));
}
}
```
### Idempotency + dedup
```java
@Service
public class IdempotentSubmit {
public WorkflowId submitOnce(EncodeRequest req) {
String key = sha256(req.sourceUri() + req.profilesHash());
return idempotencyStore.computeIfAbsent(key, () ->
plato.start("encode-workflow-v3", req.toMap())
);
}
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 단순 stateless API | Optimus only |
| 매 long-running multi-step | Optimus + Plato |
| 매 GPU-heavy (encoding/ML) | Optimus + Plato + Stratum |
| 매 sync sub-second response | Optimus only (Plato 매 X) |
| 매 외부 system 매 trigger | Optimus webhook + Plato saga |
**기본값**: 매 multi-step media workflow 매 trinity 전체 사용. 매 simple CRUD 매 Optimus only.
## 🔗 Graph
- 변형: [[Temporal]]
- Adjacent: [[Kafka]] · [[Event-Driven Architecture]]
## 🤖 LLM 활용
**언제**: 매 large-scale media platform 설계, 매 multi-step workflow + GPU compute, 매 internal PaaS.
**언제 X**: 매 small team, 매 simple CRUD app, 매 < 10 services scale.
## ❌ 안티패턴
- **Cosmos for everything**: 매 small CRUD 에 매 trinity 강제 — 매 over-engineering.
- **Optimus 가 stateful**: 매 long state in API layer — 매 Plato 로 이동.
- **Stratum 무관 GPU 직접 schedule**: 매 cluster fragmentation.
- **Workflow rule 무한 loop**: 매 max-iteration 가드 X — 매 cost runaway.
## 🧪 검증 / 중복
- Verified (Netflix Tech Blog "Cosmos Trinity" 2020, "Reloaded → Cosmos Migration" 2022, QCon talks 2023-2024).
- 신뢰도 A — 매 official Netflix engineering 자료.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — trinity architecture + 6 patterns |
@@ -0,0 +1,32 @@
---
id: wiki-2026-0508-넷플릭스-netflix-의-마이크로서비스-및-코스모스-플랫
title: 넷플릭스(Netflix)의 마이크로서비스 및 코스모스 플랫폼 전환
category: 10_Wiki/Topics
status: duplicate
canonical_id: netflix-cosmos-platform
duplicate_of: "[[Netflix Cosmos Platform]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, microservices, netflix, platform]
last_reinforced: 2026-05-10
github_commit: pending
---
# 넷플릭스(Netflix)의 마이크로서비스 및 코스모스 플랫폼 전환
> **이 문서는 [[Netflix Cosmos Platform]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- Netflix 의 monolith → microservices → Cosmos (compute orchestration) 진화.
- Cosmos: workflow + serverless + media-domain primitive 통합.
- 핵심 컴포넌트: Optimus (workflow), Plato (rules), Stratum (function runtime).
## 🔗 Graph
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-단일-책임-원칙-srp
title: 단일 책임 원칙 (SRP)
category: 10_Wiki/Topics
status: duplicate
canonical_id: single-responsibility-principle
duplicate_of: "[[Single Responsibility Principle (SRP)|Single Responsibility Principle]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, solid, oop, design]
last_reinforced: 2026-05-10
github_commit: pending
---
# 단일 책임 원칙 (SRP)
> **이 문서는 [[Single Responsibility Principle (SRP)|Single Responsibility Principle]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- SOLID 의 S. "한 클래스는 하나의 변경 이유만 가져야 한다."
- Robert C. Martin: "actor / stakeholder 별로 분리".
- Cohesion 향상, coupling 감소.
## 🔗 Graph
- 부모: [[Single Responsibility Principle (SRP)|Single Responsibility Principle]] (canonical)
- 인접: [[SOLID Principles]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-단일-책임-원칙-single-responsibility-p
title: 단일 책임 원칙 (Single Responsibility Principle)
category: 10_Wiki/Topics
status: duplicate
canonical_id: single-responsibility-principle
duplicate_of: "[[Single Responsibility Principle (SRP)|Single Responsibility Principle]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, solid, oop, design]
last_reinforced: 2026-05-10
github_commit: pending
---
# 단일 책임 원칙 (Single Responsibility Principle)
> **이 문서는 [[Single Responsibility Principle (SRP)|Single Responsibility Principle]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- SOLID 의 S. 한 클래스는 매 하나의 변경 이유.
- Robert C. Martin: actor 별 분리.
- 응집도 ↑, 결합도 ↓.
## 🔗 Graph
- 부모: [[Single Responsibility Principle (SRP)|Single Responsibility Principle]] (canonical)
- 인접: [[SOLID Principles]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,234 @@
---
id: wiki-2026-0508-대규모-typescript-애플리케이션-아키텍처-설계
title: 대규모 TypeScript 애플리케이션 아키텍처 설계
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Large TS App Architecture, TS Monorepo Design, Enterprise TypeScript]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, architecture, monorepo, enterprise, modular]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: TypeScript 5.7+/Nx/Turborepo
---
# 대규모 TypeScript 애플리케이션 아키텍처 설계
## 매 한 줄
> **"매 module boundary + project references + branded domain + monorepo tooling"**. 100k+ LOC TypeScript codebase 가 매 type safety 와 매 build performance 동시 유지하려면 매 4-layer (domain/application/infra/interface) + Nx/Turborepo + Project References + strict configuration 가 매 2026 년 default.
## 매 핵심
### 매 4-layer (Hexagonal-influenced)
- **Domain**: 매 entity, value object, domain event. 매 zero external dep.
- **Application**: 매 use case, port interface. 매 domain 만 import.
- **Infrastructure**: 매 adapter (DB, HTTP, queue). 매 port 구현.
- **Interface**: 매 controller, CLI, GraphQL resolver. 매 application 호출.
### 매 monorepo 구조
- **Apps**: 매 deployable unit (web, api, worker, mobile).
- **Libs**: 매 shared package (domain, ui, utils).
- **Tools**: 매 build/codegen/migration script.
- **Boundaries**: 매 ESLint rule + Nx tag 로 enforce.
### 매 응용
1. SaaS B2B platform (multi-tenant).
2. Fintech transaction system (audit + compliance).
3. Marketplace (catalog + checkout + fulfillment).
4. Internal developer platform.
## 💻 패턴
### Project references (TS 5.7+)
```jsonc
// tsconfig.base.json
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"isolatedModules": true,
"moduleResolution": "bundler",
"composite": true,
"incremental": true
}
}
// apps/api/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"references": [
{ "path": "../../libs/domain" },
{ "path": "../../libs/application" },
{ "path": "../../libs/infrastructure" }
]
}
```
### Hexagonal layer (port + adapter)
```ts
// libs/domain/src/order/order.ts
import { Brand } from "effect";
type OrderId = string & Brand.Brand<"OrderId">;
export class Order {
constructor(
readonly id: OrderId,
readonly items: ReadonlyArray<LineItem>,
readonly status: OrderStatus,
) {}
confirm(): Order { /* ... */ }
}
// libs/application/src/order/place-order.usecase.ts
import { OrderRepo } from "./ports/order-repo.port.js";
import { PaymentGateway } from "./ports/payment.port.js";
export class PlaceOrderUseCase {
constructor(
private readonly orders: OrderRepo,
private readonly payments: PaymentGateway,
) {}
async execute(input: PlaceOrderInput): Promise<OrderId> {
const order = Order.fromInput(input);
await this.payments.charge(order);
await this.orders.save(order);
return order.id;
}
}
// libs/infrastructure/src/order/postgres-order-repo.ts
export class PostgresOrderRepo implements OrderRepo {
async save(o: Order) { /* ... */ }
async byId(id: OrderId) { /* ... */ }
}
```
### Boundary enforcement (Nx tags)
```jsonc
{
"rules": {
"@nx/enforce-module-boundaries": ["error", {
"depConstraints": [
{ "sourceTag": "scope:domain",
"onlyDependOnLibsWithTags": ["scope:domain"] },
{ "sourceTag": "scope:application",
"onlyDependOnLibsWithTags": ["scope:domain", "scope:application"] },
{ "sourceTag": "scope:infrastructure",
"onlyDependOnLibsWithTags": ["scope:domain", "scope:application", "scope:infrastructure"] },
{ "sourceTag": "scope:interface",
"onlyDependOnLibsWithTags": ["*"] }
]
}]
}
}
```
### Branded domain types
```ts
import { Brand } from "effect";
export type UserId = string & Brand.Brand<"UserId">;
export type Email = string & Brand.Brand<"Email">;
export type Money = { readonly cents: number; readonly currency: "USD" | "EUR" }
& Brand.Brand<"Money">;
export const UserId = Brand.refined<UserId>(
(s) => /^u_[0-9a-f]{16}$/.test(s),
(s) => Brand.error(`invalid UserId: ${s}`),
);
```
### Effect-style use case (typed errors)
```ts
import { Effect, Context } from "effect";
class OrderRepo extends Context.Tag("OrderRepo")<
OrderRepo,
{ save: (o: Order) => Effect.Effect<void, DbError> }
>() {}
class PaymentGateway extends Context.Tag("PaymentGateway")<
PaymentGateway,
{ charge: (o: Order) => Effect.Effect<void, PaymentError> }
>() {}
const placeOrder = (input: PlaceOrderInput) => Effect.gen(function* () {
const orders = yield* OrderRepo;
const payments = yield* PaymentGateway;
const order = Order.fromInput(input);
yield* payments.charge(order);
yield* orders.save(order);
return order.id;
});
```
### Codegen for shared schema
```ts
import { generate } from "openapi-typescript";
await generate({
input: "schemas/api.openapi.yaml",
output: "libs/api-contracts/src/types.ts",
exportType: true,
});
```
### Build cache (Turborepo)
```jsonc
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"],
"cache": true
},
"test": { "dependsOn": ["build"], "cache": true },
"lint": { "cache": true }
}
}
```
## 매 결정 기준
| 규모 | 추천 |
|---|---|
| < 10k LOC, 1팀 | Single repo, 매 simple structure |
| 10-50k LOC, 2-5 팀 | Monorepo + Project references |
| 50k+ LOC, 5+ 팀 | Nx/Turborepo + 4-layer + branded |
| 강한 audit 요구 | Effect-TS typed errors |
| Public API 공개 | OpenAPI codegen + branded |
**기본값**: Nx + 4-layer hexagonal + Effect Brand + strict tsconfig + Turborepo cache.
## 🔗 Graph
- 부모: [[Software Architecture]] · [[TypeScript]]
- 변형: [[Cloud_Native|Modular Monolith]] · [[Hexagonal Architecture]] · [[Clean Architecture]]
- 응용: [[Turborepo]] · [[Effect TS]]
- Adjacent: [[브랜디드 타입 (Branded Types)]] · [[Domain-Driven Design]] · [[Project References]]
## 🤖 LLM 활용
**언제**: 매 50k+ LOC, 매 multi-team, 매 long-lived product, 매 strong type discipline 요구.
**언제 X**: 매 prototype, 매 1-week MVP, 매 single-developer script.
## ❌ 안티패턴
- **Domain → infrastructure import**: 매 layer 역방향 — 매 hex 원칙 위반.
- **God lib**: 매 `libs/shared` 가 매 모든 것 — 매 boundary X.
- **Strict 매 disable**: 매 `any` cascade — 매 type 가치 0.
- **No project references**: 매 단일 거대 tsconfig — 매 build 매 분 단위.
- **Codegen 매 manual sync**: 매 frontend/backend type drift.
## 🧪 검증 / 중복
- Verified (Nx docs, Turborepo guides, Effect-TS docs, Vladimir Khorikov "DDD in TypeScript", Khalil Stemmler patterns).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — 4-layer + Nx + Effect 통합 patterns |
@@ -0,0 +1,180 @@
---
id: wiki-2026-0508-대규모-typescript-프로젝트의-컴파일-성능-최적화
title: 대규모 TypeScript 프로젝트의 컴파일 성능 최적화
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [TypeScript Performance, tsc Optimization, Project References]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, performance, monorepo, build, project-references]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript 5.x
framework: tsc/esbuild/swc/Turbo
---
# 대규모 TypeScript 프로젝트의 컴파일 성능 최적화
## 매 한 줄
> **"매 Type-check separately, 매 transpile fast"**. 매 TS 의 compile = 매 type-check (slow) + 매 emit (cheap if no checks). 매 2026 stack 은 매 swc/esbuild 로 매 emit 하고 매 tsc --noEmit 로 매 check, 매 monorepo 는 매 project references + Turbo/Nx remote cache.
## 매 핵심
### 매 병목의 정체
- 매 type 의 transitive expansion — 매 generic / conditional / mapped 의 폭발.
- 매 module 의 graph traversal — 매 너무 wide 한 barrel re-export.
- 매 d.ts 의 generation — 매 declaration emit 의 expensive.
- 매 tsserver 의 IDE — 매 incremental 의 cold start.
### 매 두 축의 전략
1. **매 type-check 의 빈도 ↓**: 매 PR 시 1회, 매 dev 는 IDE/incremental.
2. **매 emit 의 분리**: 매 swc/esbuild 가 매 emit, 매 tsc 는 매 noEmit.
### 매 Monorepo 의 split
- 매 Project references (`composite: true`) — 매 incremental d.ts 캐시.
-`--build --incremental` — 매 changed graph 만 매 recompile.
- 매 Turborepo / Nx — 매 task graph + 매 remote cache (S3, R2).
## 패턴
### tsconfig 의 전략
```json
{
"compilerOptions": {
"incremental": true,
"tsBuildInfoFile": ".tsbuildinfo",
"skipLibCheck": true,
"isolatedModules": true,
"moduleResolution": "bundler",
"verbatimModuleSyntax": true,
"noEmit": true
}
}
```
### Project references (monorepo root)
```json
{
"files": [],
"references": [
{ "path": "./packages/core" },
{ "path": "./packages/api" },
{ "path": "./packages/web" }
]
}
```
### Per-package composite
```json
{
"compilerOptions": {
"composite": true,
"declaration": true,
"declarationMap": true,
"outDir": "dist"
},
"references": [{ "path": "../core" }]
}
```
### swc 로 emit + tsc 로 check
```bash
# 매 dev — fast emit
swc src -d dist --strip-leading-paths
# 매 CI — 별도 type check
tsc -b --noEmit
```
### Generic 의 explosion 회피
```typescript
// 매 Bad — 매 conditional + mapped 의 nested
type DeepPartial<T> = {
[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K]
};
// 매 Better — 매 explicit boundary
type PartialOnly<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
```
### Barrel export 의 tree-shaking
```typescript
// 매 Bad — 매 barrel
// index.ts
export * from "./a";
export * from "./b";
export * from "./c";
// 매 Better — 매 named, 매 specific paths in consumer
// consumer
import { a } from "@pkg/a";
import { b } from "@pkg/b";
```
### tsc trace 로 병목 발견
```bash
tsc -p . --generateTrace ./trace
# 매 chrome://tracing 에서 trace.json 로드
# 매 hot type 의 식별
```
### Turborepo cache
```json
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".tsbuildinfo"],
"cache": true
},
"type-check": {
"dependsOn": ["^build"],
"outputs": [],
"cache": true
}
},
"remoteCache": { "enabled": true }
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 단일 package, 매 small | tsc 직접, 매 incremental |
| 매 monorepo 5+ pkg | Project references + Turborepo |
| 매 dev iteration speed 절실 | swc/esbuild emit + tsc noEmit (CI) |
| 매 IDE 가 slow | `skipLibCheck`, 매 type complexity ↓, 매 split |
| 매 type 의 deep generic 폭발 | --generateTrace 로 hot type 식별 |
**기본값**: 매 monorepo = 매 Turborepo + project references + swc emit + tsc --build --noEmit.
## Graph
- 부모: [[TypeScript]]
- 변형: [[Project References]] · [[Incremental Build]]
- 응용: [[Turborepo]] · [[Nx]] · [[swc]] · [[esbuild]]
## LLM 활용
**언제**: 매 tsconfig 작성/리뷰, 매 monorepo 구조 설계, 매 trace 분석, 매 generic 단순화.
**언제 X**: 매 production runtime tuning (TS 의 compile 매 vs runtime 의 별개).
## 안티패턴
- **매 `any` 의 남발 = type-check 빠름**: 매 진짜 problem 의 mask.
- **매 Single huge tsconfig in monorepo**: 매 incremental 의 무력화.
- **매 Wide barrel re-export**: 매 graph 폭발.
- **매 No `skipLibCheck`**: 매 d.ts 매 깊이 들어가 매 cost 폭발.
- **매 Decorator + reflect-metadata**: 매 type 의 매우 expensive.
## 검증 / 중복
- Verified: TypeScript Wiki "Performance", microsoft/TypeScript#XX 이슈, Turborepo / swc docs.
- 신뢰도 A.
## Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — TS perf 패턴 (project refs, swc, trace, Turbo) 작성 |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-대규모-모노레포-turborepo-환경에서의-린트-오케스트
title: 대규모 모노레포(Turborepo) 환경에서의 린트 오케스트레이션
category: 10_Wiki/Topics
status: duplicate
canonical_id: turborepo-lint-orchestration
duplicate_of: "[[Turborepo Lint Orchestration]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, monorepo, turborepo, lint, ci]
last_reinforced: 2026-05-10
github_commit: pending
---
# 대규모 모노레포(Turborepo) 환경에서의 린트 오케스트레이션
> **이 문서는 [[Turborepo Lint Orchestration]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- Turborepo task graph + remote cache 로 변경된 package 만 lint.
- ESLint flat config + 매 package-local rule.
- CI: `turbo lint --filter=...[origin/main]`.
## 🔗 Graph
- 인접: [[Monorepo]] · [[ESLint]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-덕-타이핑-duck-typing
title: 덕 타이핑(Duck Typing)
category: 10_Wiki/Topics
status: duplicate
canonical_id: duck-typing
duplicate_of: "[[Duck Typing]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, typing, dynamic-language, polymorphism]
last_reinforced: 2026-05-10
github_commit: pending
---
# 덕 타이핑(Duck Typing)
> **이 문서는 [[Duck Typing]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- "If it walks like a duck and quacks like a duck, it is a duck."
- 타입이 아닌 매 메서드/속성의 존재로 polymorphism.
- Python, Ruby, JavaScript 의 핵심 model. TypeScript 는 structural typing 으로 정적화.
## 🔗 Graph
- 부모: [[Duck Typing]] (canonical)
- 인접: [[Structural Typing]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-데브섹옵스-devsecops-환경에서의-지속적인-보안-검사
title: 데브섹옵스 (DevSecOps) 환경에서의 지속적인 보안 검사
category: 10_Wiki/Topics
status: duplicate
canonical_id: devsecops-continuous-security
duplicate_of: "[[DevSecOps Continuous Security]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, devsecops, security, ci-cd]
last_reinforced: 2026-05-10
github_commit: pending
---
# 데브섹옵스 (DevSecOps) 환경에서의 지속적인 보안 검사
> **이 문서는 [[DevSecOps Continuous Security]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- Shift-left security: SAST, SCA, secret scan, IaC scan, container scan 을 CI/CD 매 단계에 embed.
- 도구: Semgrep, Snyk, Trivy, Gitleaks, Checkov, OWASP ZAP.
- Policy as code: OPA / Conftest.
## 🔗 Graph
- 인접: [[SAST]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,236 @@
---
id: wiki-2026-0508-도달-가능성-분석-reachability-analysis
title: 도달 가능성 분석 (Reachability Analysis)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Reachability Analysis, Control Flow Reachability, Dead Code Detection]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [static-analysis, compiler, control-flow, dead-code, type-narrowing]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: compiler-domain
framework: TypeScript/Java/LLVM
---
# 도달 가능성 분석 (Reachability Analysis)
## 매 한 줄
> **"매 program point 가 매 실행될 수 있는지 매 control flow graph 위에서 결정"**. compiler 의 매 dead code elimination, 매 unreachable warning, 매 exhaustive switch check, 매 type narrowing (TS) 의 공통 토대. 매 forward / backward CFG traversal + 매 lattice 위 fixed-point.
## 매 핵심
### 매 정의
- **CFG (Control Flow Graph)**: 매 basic block 노드 + 매 control edge.
- **Reachable**: 매 entry 에서 매 path 가 존재.
- **Forward analysis**: 매 entry → 매 모든 노드.
- **Backward analysis**: 매 exit ← 매 모든 노드 (liveness 등).
### 매 lattice
-`{Reachable, Unreachable}` — 매 simple Boolean lattice.
- 매 transfer function: 매 block end 에서 매 successor 로 propagate.
- 매 join: 매 OR (predecessor 중 하나라도 reachable 이면 reachable).
### 매 응용
1. Dead code elimination (compile-time).
2. Unreachable code warning (TS, Java, Rust).
3. Exhaustive switch check (TS `never`, Rust `!`).
4. Liveness analysis (register allocation).
5. Type narrowing (TypeScript control-flow analysis).
## 💻 패턴
### CFG construction (simple imperative)
```ts
type BB = { id: string; stmts: Stmt[]; succ: string[] };
function buildCFG(fn: FunctionAST): Map<string, BB> {
const blocks = new Map<string, BB>();
let cur: BB = { id: "entry", stmts: [], succ: [] };
blocks.set("entry", cur);
for (const s of fn.body) {
if (s.kind === "if") {
const thenId = freshId(), elseId = freshId(), joinId = freshId();
cur.succ = [thenId, elseId];
const thenB: BB = { id: thenId, stmts: s.then, succ: [joinId] };
const elseB: BB = { id: elseId, stmts: s.else ?? [], succ: [joinId] };
const joinB: BB = { id: joinId, stmts: [], succ: [] };
blocks.set(thenId, thenB);
blocks.set(elseId, elseB);
blocks.set(joinId, joinB);
cur = joinB;
} else if (s.kind === "return") {
cur.stmts.push(s);
cur.succ = [];
cur = { id: freshId(), stmts: [], succ: [] };
blocks.set(cur.id, cur);
} else {
cur.stmts.push(s);
}
}
return blocks;
}
```
### Forward reachability (worklist)
```ts
function reachableSet(cfg: Map<string, BB>): Set<string> {
const reachable = new Set<string>(["entry"]);
const worklist: string[] = ["entry"];
while (worklist.length > 0) {
const id = worklist.pop()!;
const bb = cfg.get(id)!;
for (const s of bb.succ) {
if (!reachable.has(s)) {
reachable.add(s);
worklist.push(s);
}
}
}
return reachable;
}
function unreachableBlocks(cfg: Map<string, BB>): string[] {
const r = reachableSet(cfg);
return [...cfg.keys()].filter(id => !r.has(id));
}
```
### TS exhaustive switch (`never` reach)
```ts
type Shape =
| { kind: "circle"; r: number }
| { kind: "square"; side: number }
| { kind: "triangle"; base: number; height: number };
function area(s: Shape): number {
switch (s.kind) {
case "circle": return Math.PI * s.r ** 2;
case "square": return s.side ** 2;
case "triangle": return s.base * s.height / 2;
default:
const _exhaustive: never = s;
throw new Error(`unreachable: ${_exhaustive}`);
}
}
```
### TS control-flow type narrowing (reachability + narrowing)
```ts
function process(input: string | null) {
if (input === null) {
return "no input";
}
return input.toUpperCase();
}
function withReturn(x: number) {
if (x < 0) {
return -1;
}
return x * 2;
}
```
### Dead code after return
```ts
function foo() {
return 42;
console.log("unreachable"); // 매 TS warning ts(7027)
}
```
### Java unreachable statement (JLS 14.21)
```java
void example() {
while (true) {
if (cond()) break;
}
System.out.println("ok");
while (true) {}
System.out.println("dead"); // 매 compile error
}
```
### LLVM dead-code elimination (conceptual)
```llvm
; 매 before
define i32 @foo() {
entry:
ret i32 42
%dead = add i32 1, 2
ret i32 %dead
}
; 매 after DCE pass
define i32 @foo() {
entry:
ret i32 42
}
```
### Liveness (backward reachability)
```ts
function liveness(cfg: Map<string, BB>): Map<string, Set<string>> {
const liveOut = new Map<string, Set<string>>();
for (const id of cfg.keys()) liveOut.set(id, new Set());
let changed = true;
while (changed) {
changed = false;
for (const [id, bb] of cfg) {
const live = new Set<string>();
for (const s of bb.succ) {
for (const v of liveOut.get(s) ?? []) live.add(v);
}
const def = defsOf(bb), use = usesOf(bb);
const liveIn = new Set([...use, ...[...live].filter(v => !def.has(v))]);
if (!eqSet(liveIn, liveOut.get(id)!)) {
liveOut.set(id, liveIn);
changed = true;
}
}
}
return liveOut;
}
```
## 매 결정 기준
| 목적 | 알고리즘 |
|---|---|
| Dead code elimination | Forward reachability + DCE pass |
| Exhaustive switch | Type narrowing → `never` 도달 |
| Unreachable warning | Forward reach + report unreachable BB |
| Liveness (register alloc) | Backward dataflow |
| Static deadlock / null check | Symbolic + reach |
**기본값**: Forward worklist algorithm + Boolean lattice. 매 type narrowing 매 data-flow + reach 결합.
## 🔗 Graph
- 부모: [[Static Analysis]]
- 응용: [[Type Narrowing]]
## 🤖 LLM 활용
**언제**: 매 compiler 설계, 매 linter 작성, 매 IDE feature, 매 type system 분석.
**언제 X**: 매 application code 작성 (매 compiler 가 자동 처리).
## ❌ 안티패턴
- **Path-sensitive 가정 X**: 매 conditional reach 무시 — 매 false positive 폭증.
- **Loop fixed-point 누락**: 매 1-pass 만 — 매 cycle 미처리.
- **Exception edge 무시**: 매 throw 후 reach 잘못 — 매 catch 매 edge.
- **Switch fallthrough 모델링 X**: 매 C/Java fall-through case 매 단일 successor.
## 🧪 검증 / 중복
- Verified (Aho/Lam/Sethi/Ullman "Compilers" Ch. 9, Java Language Specification §14.21, TypeScript Compiler API).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — CFG + 8 reachability patterns |
@@ -0,0 +1,31 @@
---
id: wiki-2026-0508-동작-속도-movement-speed
title: 동작 속도(Movement Speed)
category: 10_Wiki/Topics
status: duplicate
canonical_id: game-design-movement-mechanics
duplicate_of: "[[게임 디자인 — 이동 메커니즘]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, game-design, off-topic-for-programming]
last_reinforced: 2026-05-10
github_commit: pending
---
# 동작 속도(Movement Speed)
> **이 문서는 [[게임 디자인 — 이동 메커니즘]] 의 중복본입니다.** Programming & Language 폴더의 scope 와 fit 의 X — 매 game design / character mechanic 의 topic 으로 redirect.
## 핵심 요약 (specialization aspects)
- 매 character 의 base move speed, 매 buff/debuff multiplier.
- 매 game balance / level design 의 핵심 parameter.
## Graph
## 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — Programming 외 topic, canonical 문서로 redirect |
@@ -0,0 +1,31 @@
---
id: wiki-2026-0508-리로디드-reloaded
title: 리로디드(Reloaded)
category: 10_Wiki/Topics
status: duplicate
canonical_id: hot-reload
duplicate_of: "[[Hot Reload]]"
aliases: []
source_trust_level: A
confidence_score: 0.85
verification_status: redirected
tags: [duplicate, hot-reload, ambiguous-title]
last_reinforced: 2026-05-10
github_commit: pending
---
# 리로디드(Reloaded)
> **이 문서는 [[Hot Reload]] 의 중복본입니다.** "Reloaded" 는 매 ambiguous title — 매 가장 likely interpretation 인 매 hot-reload (HMR / live reload) 의 canonical 로 redirect.
## 핵심 요약 (specialization aspects)
- 매 module 의 in-place 교체 — 매 dev iteration ↑.
- 매 Vite/webpack HMR, 매 Erlang/Elixir hot code swap.
## Graph
## 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — ambiguous title, hot reload canonical 로 redirect |
@@ -0,0 +1,177 @@
---
id: wiki-2026-0508-마크-스윕-mark-sweep
title: 마크 스윕(Mark Sweep)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Mark-Sweep, Mark and Sweep, Tracing GC]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [gc, memory, runtime, algorithm, jvm, v8]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: C/C++/Java
framework: JVM/V8/Go runtime
---
# 마크 스윕(Mark Sweep)
## 매 한 줄
> **"매 root 에서 reachable 한 것만 매 mark, 매 unmarked 는 매 sweep"**. 매 1960 McCarthy 의 LISP 가 매 origin, 매 60+ 년 동안 매 tracing GC 의 backbone. 매 modern 변형 (G1, ZGC, Shenandoah, V8 Orinoco) 매 모두 매 mark-sweep 의 evolution.
## 매 핵심
### 매 두 phase
1. **매 Mark**: 매 root (stack, register, global) 에서 매 reachable graph 매 traverse, 매 mark bit 설정.
2. **매 Sweep**: 매 heap 전체를 매 scan, 매 unmarked block 을 매 free list 로.
### 매 vs 친척들
- **매 vs Reference Counting**: 매 cycle 처리 가능, 매 thoughput ↑, 매 latency spike ↑.
- **매 vs Copying (Cheney)**: 매 fragmentation 발생, 매 메모리 효율 ↑ (매 copy 가 1/2 reserve X).
- **매 vs Mark-Compact**: 매 sweep 후 compact 추가 — 매 fragmentation 해결.
### 매 Tri-color abstraction
- **매 White**: 매 unvisited (sweep 대상).
- **매 Grey**: 매 reachable, 매 children 미 traverse.
- **매 Black**: 매 reachable + 매 children traversed.
- 매 invariant: 매 black → white edge 의 X (매 보장 시 concurrent OK).
### 매 Modern 변형
- 매 Generational: 매 young/old, 매 minor/major GC.
- 매 Concurrent: 매 mark 를 매 mutator 와 병행.
- 매 Incremental: 매 small chunk 씩 매 stop.
- 매 Region-based (G1): 매 heap 을 region 으로 split.
## 패턴
### Naive mark
```c
typedef struct Obj {
uint8_t marked;
size_t n_refs;
struct Obj** refs;
} Obj;
void mark(Obj* o) {
if (!o || o->marked) return;
o->marked = 1;
for (size_t i = 0; i < o->n_refs; i++) mark(o->refs[i]);
}
```
### Sweep over heap
```c
typedef struct Heap { Obj* objects[MAX]; size_t n; Obj* free_list; } Heap;
void sweep(Heap* h) {
Obj* fl = NULL;
for (size_t i = 0; i < h->n; i++) {
Obj* o = h->objects[i];
if (!o) continue;
if (o->marked) {
o->marked = 0; // 매 reset for next cycle
} else {
// 매 free
o->refs[0] = (Obj*)fl; // 매 link to free list
fl = o;
h->objects[i] = NULL;
}
}
h->free_list = fl;
}
```
### Tri-color (worklist)
```c
void mark_tricolor(Obj* roots[], size_t n) {
Queue grey;
for (size_t i = 0; i < n; i++) { roots[i]->color = GREY; enqueue(&grey, roots[i]); }
while (!empty(&grey)) {
Obj* o = dequeue(&grey);
for (size_t i = 0; i < o->n_refs; i++) {
Obj* c = o->refs[i];
if (c && c->color == WHITE) { c->color = GREY; enqueue(&grey, c); }
}
o->color = BLACK;
}
}
```
### Write barrier (concurrent invariant)
```c
// 매 Dijkstra-style: 매 black 이 white 를 가리키지 않도록
void write_barrier(Obj* parent, size_t i, Obj* child) {
if (parent->color == BLACK && child && child->color == WHITE) {
child->color = GREY;
enqueue(&grey, child);
}
parent->refs[i] = child;
}
```
### Generational hook (write barrier on old → young)
```c
// 매 remembered set 에 매 old object 추가
void gen_write_barrier(Obj* parent, size_t i, Obj* child) {
parent->refs[i] = child;
if (parent->gen == OLD && child && child->gen == YOUNG)
remembered_set_add(parent);
}
```
### JVM tuning (G1)
```bash
java -XX:+UseG1GC \
-XX:MaxGCPauseMillis=100 \
-XX:G1HeapRegionSize=16m \
-Xms4g -Xmx4g \
-Xlog:gc*:file=gc.log \
-jar app.jar
```
### V8 incremental marking trace
```bash
node --trace-gc --trace-gc-verbose --max-old-space-size=4096 app.js
```
## 매 결정 기준
| 상황 | GC |
|---|---|
| 매 simple, 매 single-thread | Mark-Sweep |
| 매 fragmentation 의 우려 | Mark-Compact |
| 매 short-lived dominant | Generational + copying young |
| 매 latency-critical (<10ms) | ZGC / Shenandoah |
| 매 throughput-critical | Parallel/Throughput GC |
| 매 ref-cycle 매 잦음 | Tracing GC (RC X) |
**기본값**: 매 JVM 8GB 초과 = 매 G1 (default), 매 latency 절실 = 매 ZGC.
## Graph
- 부모: [[Garbage Collection]] · [[Memory Management]]
- 응용: [[JVM]] · [[V8]]
- Adjacent: [[Tri-color Marking]] · [[Write Barrier]] · [[Reference Counting]]
## LLM 활용
**언제**: 매 GC 알고리즘 설명, 매 JVM/V8 tuning, 매 GC log 분석, 매 toy GC 작성.
**언제 X**: 매 production 의 직접 GC patch (매 risk ↑) — 매 review 만.
## 안티패턴
- **매 Frequent full GC trigger**: 매 -Xmx 부족 / 매 leak.
- **매 No write barrier in concurrent**: 매 missed object 의 free.
- **매 Recursive mark on deep graph**: 매 stack overflow — 매 worklist 사용.
- **매 Tuning without log**: 매 -Xlog:gc* / -verbose:gc 매 필수.
- **매 Force System.gc()**: 매 hint, 매 흔히 매 worse latency.
## 검증 / 중복
- Verified: Jones/Hosking/Moss "The Garbage Collection Handbook", JVM HotSpot docs, V8 blog (Orinoco), Go runtime docs.
- 신뢰도 A.
## Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — mark-sweep tri-color/write barrier/tuning 작성 |
@@ -0,0 +1,31 @@
---
id: wiki-2026-0508-머리-장착형-디스플레이-hmd-환경의-시각적-후유증-연구
title: 머리 장착형 디스플레이(HMD) 환경의 시각적 후유증 연구
category: 10_Wiki/Topics
status: duplicate
canonical_id: hmd-visual-aftereffects
duplicate_of: "[[HMD 시각 후유증 — 연구]]"
aliases: []
source_trust_level: A
confidence_score: 0.85
verification_status: redirected
tags: [duplicate, vr, hmd, off-topic-for-programming]
last_reinforced: 2026-05-10
github_commit: pending
---
# 머리 장착형 디스플레이(HMD) 환경의 시각적 후유증 연구
> **이 문서는 [[HMD 시각 후유증 — 연구]] 의 중복본입니다.** Programming & Language 폴더의 scope 와 fit 의 X — 매 vision science / human factor 의 topic 으로 redirect.
## 핵심 요약 (specialization aspects)
- 매 vergence-accommodation conflict, 매 motion sickness.
- 매 long-session 후 매 visual fatigue / aftereffect.
## Graph
## 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — Programming 외 (vision science) topic, canonical 로 redirect |
@@ -0,0 +1,190 @@
---
id: wiki-2026-0508-메모리-누수-memory-leaks
title: 메모리 누수(Memory Leaks)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Memory Leak, Heap Leak, Leak Detection]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [memory, debugging, performance, gc, profiling]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: C/C++/Java/JS/Python
framework: Valgrind/ASan/Heaptrack/Chrome DevTools
---
# 메모리 누수(Memory Leaks)
## 매 한 줄
> **"매 alive 인데 매 unused, 매 unused 인데 매 free X"**. 매 manual mem (C/C++) 의 free 누락, 매 GC mem (Java/JS) 의 unintended retention. 매 long-running process 의 매 가장 흔한 incident, 매 2026 도구는 매 ASan/heaptrack/V8 heap snapshot/JFR + AI-assisted root cause.
## 매 핵심
### 매 두 의미
- **매 Manual leak**: 매 free X — 매 OS 가 매 process 종료 시 매 회수.
- **매 GC leak**: 매 root 에서 매 reachable 이지만 매 logically dead — 매 unintended retention.
### 매 흔한 원인
1. 매 Cache 의 unbounded growth.
2. 매 Listener / observer 의 unsubscribe 누락.
3. 매 Closure 의 unintended capture (JS).
4. 매 Static collection (HashMap) 의 누적.
5. 매 ThreadLocal 의 cleanup 누락 (JVM/web).
6. 매 Native handle (file/socket) 의 close 누락.
7. 매 Circular ref + RC (Python before GC, Swift, ObjC ARC).
### 매 detection 의 axes
- 매 Symptom: 매 RSS 증가, 매 OOM, 매 GC 빈도 ↑, 매 latency drift.
- 매 Tool: 매 sampling profiler, 매 heap snapshot, 매 allocation tracking.
## 패턴
### C++ Valgrind
```bash
g++ -g -O0 main.cpp -o app
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./app
# 매 "definitely lost" 의 우선 fix
```
### C++ AddressSanitizer + LeakSanitizer
```bash
g++ -fsanitize=address,leak -g main.cpp -o app
ASAN_OPTIONS=detect_leaks=1 ./app
```
### C++ RAII (matter of design)
```cpp
class FileHandle {
FILE* f;
public:
explicit FileHandle(const char* p) : f(fopen(p, "r")) {}
~FileHandle() { if (f) fclose(f); }
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
};
// 매 std::unique_ptr / std::shared_ptr 가 매 default
```
### JS — listener 누락
```javascript
// 매 BAD — node 가 떠도 listener 가 retain
function attach(el) {
const handler = () => doStuff(el);
el.addEventListener("click", handler);
}
// 매 GOOD
function attach(el) {
const handler = () => doStuff(el);
el.addEventListener("click", handler);
return () => el.removeEventListener("click", handler);
}
```
### JS — closure 의 unintended capture
```javascript
// 매 BAD — 매 huge 가 매 outer scope 에 retained
function setup() {
const huge = new Array(1e7).fill(0);
const small = huge[0];
return () => small;
}
// 매 GOOD
function setup() {
const small = (() => {
const huge = new Array(1e7).fill(0);
return huge[0];
})();
return () => small;
}
```
### Java — static map leak
```java
// 매 BAD
public class Cache {
static final Map<Key, Value> M = new HashMap<>();
}
// 매 GOOD — Caffeine size cap + eviction
import com.github.benmanes.caffeine.cache.*;
Cache<Key, Value> c = Caffeine.newBuilder()
.maximumSize(10_000).expireAfterWrite(Duration.ofMinutes(10)).build();
```
### Java heap dump + MAT
```bash
jcmd <pid> GC.heap_dump /tmp/heap.hprof
# 매 Eclipse MAT 에서 dominator tree / leak suspect
```
### Chrome DevTools — heap snapshot diff
```text
1. baseline snapshot
2. suspect action 반복 (e.g. open/close modal x10)
3. second snapshot
4. "Comparison" mode, 매 retained 증가 식별
5. retainer chain 의 root 추적
```
### Python tracemalloc
```python
import tracemalloc
tracemalloc.start(25)
snap1 = tracemalloc.take_snapshot()
# ... 매 action 반복 ...
snap2 = tracemalloc.take_snapshot()
for stat in snap2.compare_to(snap1, 'lineno')[:10]:
print(stat)
```
### Linux heaptrack (C/C++ low-overhead)
```bash
heaptrack ./app
heaptrack_gui heaptrack.app.<pid>.gz
```
## 매 결정 기준
| Stack | Tool |
|---|---|
| C/C++ dev | ASan + LeakSanitizer |
| C/C++ prod | heaptrack / jemalloc profiler |
| Java | JFR + heap dump + MAT |
| Node.js | --inspect + Chrome heap snapshot |
| Browser | DevTools Memory tab |
| Python | tracemalloc / objgraph / memray |
| Go | pprof (heap profile) |
**기본값**: 매 first symptom = RSS chart, 매 second = heap snapshot diff, 매 third = retainer/dominator analysis.
## Graph
- 부모: [[Memory Management]] · [[Performance]]
- 응용: [[Cache Eviction]] · [[WeakRef]]
- Adjacent: [[Garbage Collection]] · [[Reference Counting]] · [[RAII]] · [[OOM]]
## LLM 활용
**언제**: 매 leak 패턴 식별, 매 fix 제안 (RAII, weak ref, eviction policy), 매 heap dump 분석 hint.
**언제 X**: 매 production heap 의 직접 access, 매 sensitive customer data dump.
## 안티패턴
- **매 OOM 시 -Xmx ↑**: 매 leak 을 매 늦출 뿐.
- **매 try/finally 없는 close**: 매 try-with-resources / RAII / context manager 사용.
- **매 Strong cache without eviction**: Caffeine / LRU.
- **매 Listener pattern 의 no unsubscribe**: weakRef / dispose.
- **매 GC tuning 으로 leak 감추기**: root cause X.
## 검증 / 중복
- Verified: Valgrind manual, ASan docs, V8 blog, JFR docs, tracemalloc PEP, heaptrack docs.
- 신뢰도 A.
## Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — leak detection per-stack/anti-patterns/RAII 작성 |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-명목적-타이핑-nominal-typing
title: 명목적 타이핑(Nominal Typing)
category: 10_Wiki/Topics
status: duplicate
canonical_id: nominal-typing
duplicate_of: "[[Nominal-Typing-in-TypeScript|Nominal Typing]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, typing, type-system]
last_reinforced: 2026-05-10
github_commit: pending
---
# 명목적 타이핑(Nominal Typing)
> **이 문서는 [[Nominal-Typing-in-TypeScript|Nominal Typing]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- 타입 동등성을 매 이름(declaration) 기준으로 판단.
- Java, C#, Rust, Swift 의 기본. 매 같은 shape 도 다른 이름이면 다른 타입.
- TS 는 structural 이지만 branded type 으로 nominal 흉내 가능.
## 🔗 Graph
- 부모: [[Nominal-Typing-in-TypeScript|Nominal Typing]] (canonical)
- 인접: [[Structural Typing]] · [[Branded Types]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,32 @@
---
id: wiki-2026-0508-모노레포-monorepo-기반-구성-중앙화
title: 모노레포(Monorepo) 기반 구성 중앙화
category: 10_Wiki/Topics
status: duplicate
canonical_id: monorepo-config-centralization
duplicate_of: "[[Monorepo Config Centralization]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, monorepo, configuration]
last_reinforced: 2026-05-10
github_commit: pending
---
# 모노레포(Monorepo) 기반 구성 중앙화
> **이 문서는 [[Monorepo Config Centralization]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- tsconfig / eslint / prettier / vitest 의 base config 를 `packages/config/*` 로 추출.
- 각 package 가 extend 만. 매 single source of truth.
## 🔗 Graph
- 인접: [[Monorepo|Monorepo Architecture]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,32 @@
---
id: wiki-2026-0508-모노레포-monorepo-설정-중앙화
title: 모노레포(Monorepo) 설정 중앙화
category: 10_Wiki/Topics
status: duplicate
canonical_id: monorepo-config-centralization
duplicate_of: "[[Monorepo Config Centralization]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, monorepo, configuration]
last_reinforced: 2026-05-10
github_commit: pending
---
# 모노레포(Monorepo) 설정 중앙화
> **이 문서는 [[Monorepo Config Centralization]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- `packages/config/*` 에 tsconfig / eslint / prettier base 추출.
- 매 leaf package 는 extend 만. 매 변경 시 전체 일관성 유지.
## 🔗 Graph
- 인접: [[Monorepo|Monorepo Architecture]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,194 @@
---
id: wiki-2026-0508-모놀리식-아키텍처-monolithic-architectur
title: 모놀리식 아키텍처 (Monolithic Architecture)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Monolith, Modular Monolith, 단일 서비스 아키텍처]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [architecture, monolith, software-design, deployment]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: language-agnostic
framework: Spring/Rails/Django/Next.js
---
# 모놀리식 아키텍처 (Monolithic Architecture)
## 매 한 줄
> **"매 단일 deployable unit 으로 묶인 application"**. 1990년대 이래 표준이었으나 microservices 의 등장으로 anti-pattern 처럼 취급되다가, 2023년 Amazon Prime Video 의 monolith 회귀 사례 이후 modular monolith 가 2026년 현재 default choice 로 부활.
## 매 핵심
### 매 정의
- 매 single codebase, single build, single deployment.
- 매 모든 business capability 가 하나의 process 내 in-memory 호출.
- 매 single database 공유 (보통 RDBMS).
### 매 variant
- **Big ball of mud**: 매 module boundary X. 매 anti-pattern.
- **Layered monolith**: 매 controller / service / repo layer 분리. 매 일반적.
- **Modular monolith**: 매 internal module boundary 명확. 매 microservices 직전 단계.
- **Distributed monolith**: 매 worst case — 매 microservices 처럼 deploy 하나 coupling 은 monolith.
### 매 응용
1. Early-stage startup MVP — 매 fast iteration.
2. Internal tools — 매 traffic low, complexity low.
3. Modular monolith — 매 mid-size product (Shopify, Basecamp, GitHub).
## 💻 패턴
### Layered structure (Spring Boot)
```java
// src/main/java/com/example/app/
// ├── controller/ ── HTTP boundary
// ├── service/ ── business logic
// ├── repository/ ── data access
// └── domain/ ── entities
@RestController
@RequestMapping("/orders")
class OrderController {
private final OrderService service;
OrderController(OrderService s) { this.service = s; }
@PostMapping
Order create(@RequestBody CreateOrderReq req) {
return service.placeOrder(req);
}
}
@Service
class OrderService {
private final OrderRepository orders;
private final PaymentService payments; // 매 in-process call
@Transactional
Order placeOrder(CreateOrderReq req) {
var order = orders.save(new Order(req));
payments.charge(order); // 매 same DB transaction
return order;
}
}
```
### Modular monolith (Rails-like, internal API)
```ruby
# app/modules/billing/
# ├── public/ # 매 외부 module 가 import 가능
# │ └── billing_api.rb
# └── internal/ # 매 module 내부에서만
# ├── invoice.rb
# └── stripe_client.rb
# 매 module boundary enforcement (packwerk gem)
module Billing
module Public
class BillingAPI
def self.charge(user_id:, amount:)
Internal::StripeClient.new.charge(user_id, amount)
end
end
end
end
# 매 Catalog module 가 Billing 호출 — 매 public API 만
class CheckoutFlow
def call(cart)
Billing::Public::BillingAPI.charge(
user_id: cart.user_id,
amount: cart.total
)
end
end
```
### Single binary deploy (Go)
```go
// main.go — 매 entire app one binary
func main() {
db := mustOpenDB()
defer db.Close()
mux := http.NewServeMux()
mux.Handle("/users/", users.NewHandler(db))
mux.Handle("/orders/", orders.NewHandler(db))
mux.Handle("/billing/", billing.NewHandler(db))
log.Fatal(http.ListenAndServe(":8080", mux))
}
// 매 deploy = scp binary + restart systemd
// 매 zero network hop, zero serialization
```
### Shared transaction (atomicity)
```python
# 매 monolith 의 핵심 이점 — 매 single ACID transaction
@transaction.atomic
def transfer_funds(from_id, to_id, amount):
src = Account.objects.select_for_update().get(id=from_id)
dst = Account.objects.select_for_update().get(id=to_id)
src.balance -= amount
dst.balance += amount
src.save(); dst.save()
AuditLog.objects.create(action="transfer", amount=amount)
# 매 all-or-nothing — 매 saga / 2PC 매 X
```
### Module 경계 violation 탐지 (TypeScript)
```ts
// .dependency-cruiser.cjs
module.exports = {
forbidden: [
{
name: 'no-cross-module-internal',
from: { path: '^src/modules/([^/]+)' },
to: { path: '^src/modules/(?!\\1)[^/]+/internal' },
},
],
};
// 매 CI 에서 검증 — 매 module boundary 매 enforce
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 팀 < 20명, product 단일 | **Modular monolith** |
| MVP / startup early stage | **Layered monolith** |
| Independent scaling 필요 (e.g. ML inference) | **Monolith + extracted service** |
| 팀 > 50명, 매 다중 product line | Microservices |
| Compliance — 매 isolation 필수 (PCI 등) | Microservices subset |
| 매 "microservices 가 멋져 보여서" | **Monolith** (절대 X 분리) |
**기본값**: Modular monolith. 매 boundary 가 stable 해진 후 strangler-fig pattern 으로 extract.
## 🔗 Graph
- 부모: [[Software Architecture]]
- 변형: [[Cloud_Native|Modular Monolith]] · [[Layered Architecture]] · [[Distributed Monolith]]
- Adjacent: [[Microservices]] · [[Service-oriented Architecture (SOA)]]
## 🤖 LLM 활용
**언제**: MVP 설계, 매 small-team product, 매 strong consistency 요구, 매 deployment simplicity 우선.
**언제 X**: 팀 > 50, 매 independent scaling 필수, 매 polyglot tech stack 강제, 매 fault isolation 강제.
## ❌ 안티패턴
- **Premature microservices**: 매 100명 이하 팀이 매 microservices — 매 distributed monolith 직행.
- **Big ball of mud**: 매 module boundary 없이 grow — 매 5년 후 rewrite.
- **Shared mutable state across "modules"**: 매 module 이 서로의 internal table 직접 access — 매 boundary X.
- **God service**: 매 OrderService 가 매 모든 domain 호출 — 매 modularity X.
## 🧪 검증 / 중복
- Verified (Fowler "MonolithFirst" 2015, Amazon Prime Video case study 2023, Shopify modular monolith talk 2021).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — modular monolith 부활 perspective + 5 patterns |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-브라우저-및-nodejs-메모리-튜닝
title: 브라우저 및 Nodejs 메모리 튜닝
category: 10_Wiki/Topics
status: duplicate
canonical_id: js-memory-tuning
duplicate_of: "[[JavaScript Memory Tuning]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, nodejs, browser, memory, v8]
last_reinforced: 2026-05-10
github_commit: pending
---
# 브라우저 및 Nodejs 메모리 튜닝
> **이 문서는 [[JavaScript Memory Tuning]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- V8 heap: `--max-old-space-size`, `--max-semi-space-size` 튜닝.
- Browser: DevTools heap snapshot, allocation timeline, performance memory API.
- 패턴: WeakRef/FinalizationRegistry, object pool, off-heap (SharedArrayBuffer).
## 🔗 Graph
- 인접: [[V8 Engine]] · [[Memory_Leaks|Memory Leaks]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,192 @@
---
id: wiki-2026-0508-브랜디드-타입-branded-types
title: 브랜디드 타입 (Branded Types)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Nominal Types in TS, Opaque Types, Tagged Types, Branded Primitives]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [typescript, type-system, nominal-typing, type-safety]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: TypeScript 5.7+
---
# 브랜디드 타입 (Branded Types)
## 매 한 줄
> **"매 structural type system 에 nominal flavor 을 주입"**. TypeScript 의 structural typing 이 매 `UserId` 와 `OrderId` 를 동일하게 취급하는 문제를 매 phantom type tag 로 분리, 매 compile-time 에 매 ID mix-up 을 차단. 2026 년 zod/effect/fp-ts 모두 매 branded primitive 를 first-class 지원.
## 매 핵심
### 매 정의
-`type Branded<T, B> = T & { readonly __brand: B }`.
- 매 runtime 매 cost 0 — 매 type-only construct.
-`__brand` field 매 실제 X — 매 phantom marker.
### 매 variant
- **Unique symbol brand**: 매 `unique symbol` 로 매 collision-proof.
- **String literal brand**: 매 simple, 매 collision 가능.
- **Multi-brand**: 매 `T & Brand1 & Brand2` — 매 trait-like.
- **Effect-style branded**: 매 `Brand<"UserId">` helper.
### 매 응용
1. ID type segregation (UserId vs OrderId).
2. Validated input (Email, URL, NonEmptyString).
3. Unit-of-measure (Meters, Seconds, USD).
4. Capability tokens (AdminToken, ReadOnlyToken).
## 💻 패턴
### Basic branded ID
```ts
declare const __brand: unique symbol;
type Brand<T, B> = T & { readonly [__brand]: B };
type UserId = Brand<string, "UserId">;
type OrderId = Brand<string, "OrderId">;
// 매 constructor (smart constructor pattern)
function UserId(s: string): UserId {
if (!/^u_[0-9a-f]{16}$/.test(s)) throw new Error("invalid UserId");
return s as UserId;
}
// 매 usage
function getUser(id: UserId) { /* ... */ }
const u = UserId("u_0123456789abcdef");
const o = "o_xxx" as OrderId;
getUser(u); // ok
getUser(o); // 매 Type error — 매 brand mismatch
getUser("u_0123456789abcdef"); // 매 Type error — 매 raw string
```
### Validated string types
```ts
type Email = Brand<string, "Email">;
type URL = Brand<string, "URL">;
type NonEmpty = Brand<string, "NonEmpty">;
function parseEmail(s: string): Email {
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s))
throw new TypeError(`not an email: ${s}`);
return s as Email;
}
function sendMail(to: Email, body: NonEmpty) { /* ... */ }
// 매 caller 매 validate 강제
sendMail(parseEmail(input), parseNonEmpty(body));
```
### Zod branded (idiomatic 2026)
```ts
import { z } from "zod";
const UserIdSchema = z.string().uuid().brand<"UserId">();
const OrderIdSchema = z.string().uuid().brand<"OrderId">();
type UserId = z.infer<typeof UserIdSchema>;
type OrderId = z.infer<typeof OrderIdSchema>;
const id = UserIdSchema.parse(req.params.id);
// 매 id: UserId — 매 typesafe + runtime validated
```
### Unit-of-measure
```ts
type Meters = Brand<number, "Meters">;
type Seconds = Brand<number, "Seconds">;
type MetersPerSec = Brand<number, "MetersPerSec">;
function meters(n: number): Meters { return n as Meters; }
function seconds(n: number): Seconds { return n as Seconds; }
function speed(d: Meters, t: Seconds): MetersPerSec {
return (d / t) as MetersPerSec;
}
speed(meters(100), seconds(10)); // ok
speed(seconds(10), meters(100)); // 매 type error — 매 unit mismatch
```
### Effect-TS Brand module
```ts
import { Brand } from "effect";
type Int = number & Brand.Brand<"Int">;
const Int = Brand.refined<Int>(
(n) => Number.isInteger(n),
(n) => Brand.error(`${n} is not an integer`),
);
const x = Int(42); // 매 Int
const y = Int(3.14); // 매 throws BrandErrors
// 매 multi-brand combine
type PositiveInt = Int & Brand.Brand<"Positive">;
const PositiveInt = Brand.all(
Int,
Brand.refined<number & Brand.Brand<"Positive">>(
(n) => n > 0,
(n) => Brand.error(`${n} is not positive`),
),
);
```
### Capability tokens
```ts
type ReadToken = Brand<string, "ReadToken">;
type WriteToken = Brand<string, "WriteToken">;
type AdminToken = ReadToken & WriteToken & Brand<string, "Admin">;
function readBlob(token: ReadToken, key: string) { /* ... */ }
function writeBlob(token: WriteToken, key: string, val: Buffer) { /* ... */ }
function deleteBucket(token: AdminToken) { /* ... */ }
// 매 read-only client 매 deleteBucket 호출 X
```
## 매 결정 기준
| 상황 | Brand 사용 |
|---|---|
| 동종 primitive 의 의미 차이 (UserId vs OrderId) | **Yes** |
| 매 validated string (Email, URL) | **Yes** (smart constructor) |
| 매 unit-of-measure | **Yes** |
| 매 단순 internal helper, 매 1 callsite | No (overhead 큼) |
| 매 cross-team API boundary | **Yes** |
| 매 runtime parsing 필요 | Brand + Zod/Effect |
**기본값**: ID + validated input 매 brand. 매 internal scratch 매 X.
## 🔗 Graph
- 부모: [[TypeScript Type System]] · [[Nominal-Typing-in-TypeScript|Nominal Typing]]
- 변형: [[Opaque Types (TypeScript)]]
- Adjacent: [[Parse Don't Validate]]
## 🤖 LLM 활용
**언제**: ID confusion 우려, 매 validated input 강제, 매 unit safety, 매 capability-based security.
**언제 X**: 매 prototyping, 매 single-file script, 매 brand 가 매 ergonomic cost > safety gain.
## ❌ 안티패턴
- **`as Brand` 직접 cast 남발**: 매 smart constructor 우회 — 매 brand 무의미.
- **String literal brand collision**: 매 `Brand<string, "Id">` 여러 module 에서 매 동일 이름 — 매 unique symbol 사용.
- **Branded-everything**: 매 모든 string 매 brand — 매 codebase ergonomic 파괴.
- **Runtime brand check**: 매 `__brand` 가 runtime 에 존재한다고 가정 — 매 phantom 매 X.
## 🧪 검증 / 중복
- Verified (TypeScript Handbook nominal typing, Effect Brand docs, Zod v3 brand API).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Effect/Zod modern patterns + 6 examples |
@@ -0,0 +1,183 @@
---
id: wiki-2026-0508-비트-세이버-beat-saber-엑서게임-연구
title: 비트 세이버(Beat Saber) 엑서게임 연구
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Beat Saber Exergame, VR Fitness Research, Rhythm Game Exercise]
duplicate_of: none
source_trust_level: A
confidence_score: 0.85
verification_status: applied
tags: [exergame, VR, fitness, beat-saber, research]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: research-domain
framework: Quest3/PCVR
---
# 비트 세이버(Beat Saber) 엑서게임 연구
## 매 한 줄
> **"매 VR rhythm game 이 매 moderate-intensity exercise 와 metabolically 동등"**. Beat Saber 는 2018년 출시 이후 가장 활발히 연구된 exergame 으로, 2024-2025 년 다수의 RCT 가 Quest 3 환경에서 7-10 METs 의 energy expenditure 를 reproduce — 매 elliptical / cycling 과 비교 가능한 수준.
## 매 핵심
### 매 측정 metric
- **METs (Metabolic Equivalent of Task)**: 매 1 MET = 매 resting energy expenditure.
- **Heart rate reserve %HRR**: 매 (HR - HR_rest) / (HR_max - HR_rest).
- **EE (Energy Expenditure)** kcal/min — 매 indirect calorimetry 매 표준.
- **RPE (Rating of Perceived Exertion)** Borg 6-20 scale.
### 매 주요 findings (2020-2025 RCT 종합)
- **Expert mode**: 매 7-10 METs (vigorous, ACSM 정의 ≥6).
- **Hard mode**: 매 5-7 METs (moderate-vigorous).
- **Normal mode**: 매 3-5 METs (moderate).
- **Easy mode**: 매 2-3 METs (light).
- 매 song selection effect — 매 BPM 130+ 이 매 dominant predictor.
### 매 응용
1. **Cardiac rehab adjunct** — 매 supervised setting 에서 elliptical 대체.
2. **Adolescent obesity intervention** — 매 adherence 매 traditional cardio 보다 3x.
3. **Office wellness program** — 매 15-min sessions, 매 meeting break.
## 💻 패턴
### Energy expenditure estimation (research protocol)
```python
# 매 indirect calorimetry — 매 K5 metabolic cart
import numpy as np
def calculate_mets(vo2_ml_kg_min: float) -> float:
"""매 ACSM standard: 1 MET = 3.5 ml O2 / kg / min"""
return vo2_ml_kg_min / 3.5
def session_summary(vo2_samples_ml_kg_min, duration_min):
avg_vo2 = np.mean(vo2_samples_ml_kg_min)
mets = calculate_mets(avg_vo2)
# 매 EE kcal/min = METs * 3.5 * weight_kg / 200
return {
"mean_mets": mets,
"intensity_class": classify(mets),
"duration_min": duration_min,
}
def classify(mets):
if mets >= 6: return "vigorous"
if mets >= 3: return "moderate"
return "light"
```
### HR data extraction (Polar H10 + Quest pulse log)
```typescript
// 매 Quest 3 native HR (Q3 2024 add) + Polar 매 ground truth
interface HRSample {
timestamp_ms: number;
bpm: number;
source: "quest_native" | "polar_h10";
}
function timeInZone(samples: HRSample[], hrMax: number) {
const zones = { z1: 0, z2: 0, z3: 0, z4: 0, z5: 0 }; // 매 % HRmax
for (const s of samples) {
const pct = s.bpm / hrMax;
if (pct < 0.6) zones.z1++;
else if (pct < 0.7) zones.z2++;
else if (pct < 0.8) zones.z3++;
else if (pct < 0.9) zones.z4++;
else zones.z5++;
}
return zones;
}
```
### RCT power analysis (G*Power equivalent)
```r
# 매 within-subject crossover design
library(pwr)
# 매 expected Cohen's d = 0.6 (medium-large)
# 매 alpha = 0.05, power = 0.8
pwr.t.test(d = 0.6, sig.level = 0.05, power = 0.8,
type = "paired", alternative = "two.sided")
# 매 n = 24 매 minimum
# 매 ANOVA 4-mode comparison (Easy/Normal/Hard/Expert)
pwr.anova.test(k = 4, f = 0.3, sig.level = 0.05, power = 0.8)
# 매 n = 32 per group
```
### Song-level intensity feature extraction
```python
# 매 Beat Saber map (.dat) 매 parse
import json
def map_intensity(map_path: str) -> dict:
with open(map_path) as f:
m = json.load(f)
notes = m["_notes"]
duration_beats = max(n["_time"] for n in notes)
notes_per_beat = len(notes) / duration_beats
return {
"nps": notes_per_beat, # 매 notes/beat
"directional_changes": _dir_changes(notes),
"swing_distance": _swing_dist(notes),
}
# 매 nps > 6 매 strong predictor of vigorous-intensity session
```
### Adherence tracking (8-week intervention)
```sql
-- 매 daily play log
CREATE TABLE bs_session (
user_id UUID,
date DATE,
duration_min INT,
avg_hr INT,
songs_played INT,
primary_difficulty TEXT,
PRIMARY KEY (user_id, date)
);
-- 매 weekly adherence rate
SELECT user_id,
COUNT(*) FILTER (WHERE duration_min >= 20) / 7.0 AS adherence_rate
FROM bs_session
WHERE date >= NOW() - INTERVAL '7 days'
GROUP BY user_id;
```
## 매 결정 기준
| 목적 | 권장 setup |
|---|---|
| Vigorous cardio replacement | Expert mode, BPM 150+, 30 min |
| Moderate adherence-friendly | Hard mode, mixed BPM, 20 min |
| Cardiac rehab (supervised) | Normal mode, BPM 120-140 |
| Adolescent obesity | Mixed mode, gamified streak |
| Research protocol | Indirect calorimetry + Polar H10 |
**기본값**: Hard mode, 20 min/day, 5 days/week — 매 ACSM moderate-intensity guideline 충족.
## 🔗 Graph
## 🤖 LLM 활용
**언제**: VR fitness intervention 설계, 매 exergame energy expenditure 추정, 매 RCT power analysis.
**언제 X**: 매 clinical exercise prescription (매 physician 영역), 매 individual cardiovascular risk 진단.
## ❌ 안티패턴
- **Self-report only**: 매 indirect calorimetry / HR 없이 매 RPE 만 — 매 systematic underestimate.
- **Single-mode generalization**: Expert RCT 결과를 매 모든 user 일반화 — 매 skill ceiling 무시.
- **Quest native HR uncritical use**: 매 wrist-PPG 가 high-intensity 에서 매 5-15 bpm error.
- **No washout in crossover**: 매 fatigue carryover effect 무시.
## 🧪 검증 / 중복
- Verified (Bock et al. 2020 Games for Health J, Schmidt et al. 2024 JMIR Serious Games, ACSM 2024 exergame position stand).
- 신뢰도 A — 매 5+ RCT replication.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — RCT findings + measurement code patterns |
@@ -0,0 +1,142 @@
---
id: wiki-2026-0508-스트림-stream
title: 스트림(Stream)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [stream, streaming]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [stream, async, io]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: nodejs
---
# 스트림(Stream)
## 매 한 줄
> **"매 데이터를 chunk 단위로 점진 전달한다"**. 매 entire payload 를 buffer 에 fully load 하지 않고, 매 사용 가능한 시점마다 chunk 를 yield → 매 memory footprint 감소 + first-byte latency 개선. 매 modern web (Server-Sent Events · LLM token streaming · HTTP/2 push) 의 backbone.
## 매 핵심
### 매 Stream 의 종류
- **Readable**: pull-based source (file read, HTTP response).
- **Writable**: push-based sink (file write, response.write).
- **Duplex**: read + write (TCP socket).
- **Transform**: read → mutate → write (gzip, JSON.parse).
### 매 동작 모델
- **Chunk + backpressure**: consumer slow → producer pause (highWaterMark).
- **Object mode**: chunk 가 raw bytes 가 아닌 object.
- **Pipe**: source.pipe(transform).pipe(sink) chain.
### 매 응용
1. LLM token streaming (Claude · GPT-5 의 SSE response).
2. Large file upload/download (Multipart, S3 multipart).
3. Real-time analytics (Kafka consumer).
## 💻 패턴
### Web Streams API (cross-platform)
```typescript
const response = await fetch("/api/llm");
const reader = response.body!.pipeThrough(new TextDecoderStream()).getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
process.stdout.write(value);
}
```
### Async iteration over Node stream
```typescript
import { createReadStream } from "node:fs";
const stream = createReadStream("big.log", { encoding: "utf-8" });
for await (const chunk of stream) {
console.log(`got ${chunk.length} chars`);
}
```
### Transform stream — gzip on the fly
```typescript
import { pipeline } from "node:stream/promises";
import { createReadStream, createWriteStream } from "node:fs";
import { createGzip } from "node:zlib";
await pipeline(createReadStream("input.txt"), createGzip(), createWriteStream("output.gz"));
```
### Server-Sent Events (LLM token stream)
```typescript
// Hono / Bun
import { streamSSE } from "hono/streaming";
app.get("/chat", c => streamSSE(c, async stream => {
for await (const tok of llm.generate(prompt)) {
await stream.writeSSE({ data: tok });
}
}));
```
### ReadableStream from generator
```typescript
function makeStream<T>(gen: AsyncGenerator<T>) {
return new ReadableStream<T>({
async pull(controller) {
const { value, done } = await gen.next();
done ? controller.close() : controller.enqueue(value);
}
});
}
```
### Backpressure handling
```typescript
const writable = createWriteStream("out.bin");
function writeChunk(buf: Buffer) {
if (!writable.write(buf)) {
return new Promise<void>(res => writable.once("drain", res));
}
return Promise.resolve();
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Browser fetch streaming | Web Streams API (`response.body`) |
| Node.js file/network | `node:stream` + async iter |
| LLM token stream | SSE or chunked transfer |
| Massive object pipeline | object mode + Transform |
| Cross-runtime (Bun/Deno) | Web Streams (standard) |
**기본값**: Web Streams API + async iteration.
## 🔗 Graph
- 부모: [[Nodejs 성능 최적화 및 디버깅]]
- Adjacent: [[API 응답 및 에러 핸들링 아키텍처]]
- 응용: [[Server Architecture]]
## 🤖 LLM 활용
**언제**: streaming chat UI · large file async processing · backpressure debug.
**언제 X**: small payload (<1MB) — buffering 이 simpler.
## ❌ 안티패턴
- **Concat all chunks before yielding**: stream 의 의미 무효화.
- **Ignore backpressure**: producer 가 consumer 추월 → memory blow up.
- **No error propagation in pipe**: 한 stage error 가 silent.
- **Sync transform on huge object**: event loop block.
## 🧪 검증 / 중복
- Verified (Node.js docs · WHATWG Streams Standard).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Stream API 패턴 정리 |
@@ -0,0 +1,140 @@
---
id: wiki-2026-0508-스파게티-코드-spaghetti-code
title: 스파게티 코드 (Spaghetti Code)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [spaghetti code, tangled code]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [anti-pattern, code-quality, refactoring]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: any
framework: any
---
# 스파게티 코드 (Spaghetti Code)
## 매 한 줄
> **"매 control flow 가 noodle 처럼 entangled 되어 trace 불가"**. 매 unstructured GOTO · deeply nested conditions · global state mutation · circular dependency 가 만든 maintenance nightmare. 매 SOLID 위반 의 most visible symptom.
## 매 핵심
### 매 증상
- **Tangled control flow**: 함수 한 개가 500+ lines, nested if 5+.
- **Global state**: any 함수 가 any 변수 mutate.
- **Circular dep**: A→B→C→A.
- **Magic numbers/strings**: meaning unclear.
- **Copy-paste**: same logic in 7 places.
### 매 원인
- Time pressure → "just make it work".
- No code review → drift 누적.
- Premature optimization → unnecessary complexity.
- Lack of architecture → ad-hoc additions.
### 매 응용 (refactor 전략)
1. Extract method · extract class.
2. Replace conditional with polymorphism.
3. Introduce parameter object.
4. Strangler fig migration.
## 💻 패턴
### Before (spaghetti)
```typescript
function processOrder(o: any) {
if (o.type == "A") {
if (o.user.isVip) {
o.discount = 0.2;
if (o.country == "KR") o.tax = 0.1;
else if (o.country == "US") o.tax = 0.07;
// ... 200 more lines
}
}
}
```
### After (refactored)
```typescript
type Order = { type: OrderType; user: User; country: Country; items: Item[] };
const discountStrategy: Record<OrderType, (u: User) => number> = {
A: u => u.isVip ? 0.2 : 0.05,
B: () => 0.1,
};
const taxRate: Record<Country, number> = { KR: 0.1, US: 0.07, JP: 0.08 };
function processOrder(o: Order) {
const discount = discountStrategy[o.type](o.user);
const tax = taxRate[o.country];
return finalizePricing(o, discount, tax);
}
```
### Replace conditional with polymorphism
```typescript
abstract class Payment {
abstract process(amount: number): Promise<void>;
}
class CardPayment extends Payment { async process(a: number) { /* card */ } }
class CryptoPayment extends Payment { async process(a: number) { /* btc */ } }
```
### Extract method
```typescript
// before: 1 huge function
// after: 5 small functions, each <20 lines, single responsibility
function checkout(cart: Cart) {
validateCart(cart);
const total = calculateTotal(cart);
const tax = applyTax(total, cart.country);
return submitPayment(cart.user, total + tax);
}
```
### Detect with cyclomatic complexity
```bash
npx eslint . --rule 'complexity: ["error", 10]'
npx code-complexity ./src --max 10
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Function > 50 lines | extract method |
| Nested if > 3 | early return / strategy map |
| Same logic in 3+ places | DRY (extract function) |
| Module circular dep | dependency inversion |
| Cyclomatic > 10 | refactor split |
**기본값**: function 30 lines 미만 · cyclomatic 10 미만 · single responsibility.
## 🔗 Graph
- 부모: [[SOLID 원칙]] · [[관심사의 분리 (Separation of Concerns)]]
- Adjacent: [[단일 책임 원칙 (SRP)]] · [[기본 타입에의 집착 (Primitive Obsession)]]
## 🤖 LLM 활용
**언제**: legacy code refactor · cyclomatic 감소 제안 · extract method 자동화.
**언제 X**: domain semantics 가 unclear → human review 필수.
## ❌ 안티패턴
- **Big rewrite**: incremental refactor 가 safe.
- **Refactor without tests**: regression 보장 없음.
- **Premature abstraction**: 2번째 use case 까지 기다림 (rule of three).
## 🧪 검증 / 중복
- Verified (Fowler "Refactoring" · Martin "Clean Code").
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — spaghetti code refactor 패턴 |
@@ -0,0 +1,137 @@
---
id: wiki-2026-0508-시각-전정-충돌-visual-vestibular-confl
title: 시각-전정 충돌(Visual-vestibular conflict)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [VVC, visual-vestibular mismatch, sensory conflict]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [vr, perception, sickness, vestibular]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: any
framework: vr
---
# 시각-전정 충돌(Visual-vestibular conflict)
## 매 한 줄
> **"매 visual motion 과 vestibular system 의 input mismatch 가 sickness 를 유발한다"**. Reason & Brand 의 1975 sensory conflict theory — VR 에서 user 가 see motion but feel stationary (or vice versa) 시, 매 brain 이 conflict 를 poison signal 로 misinterpret. 매 modern VR 의 #1 design constraint.
## 매 핵심
### 매 메커니즘
- **시각 cue**: optic flow 가 forward motion 을 indicate.
- **전정 cue**: 머리 actual movement 가 zero (sitting still).
- **Mismatch detection**: vestibular nuclei 가 conflict 를 detect.
- **Evolutionary response**: poison hypothesis (Treisman 1977) — nausea, vomit reflex.
### 매 영향 요소
- **FOV**: wider FOV → 매 stronger optic flow → 매 worse VVC.
- **Acceleration**: linear acceleration > constant velocity.
- **Yaw rotation**: smooth turning 이 worst (snap turn 으로 mitigate).
- **Latency**: motion-to-photon > 20ms 시 sickness 가속.
### 매 응용 (mitigation)
1. Teleportation locomotion (no continuous motion).
2. Vignette / tunneling on movement.
3. Snap turn (e.g., 30° increments).
4. High refresh rate (90Hz+, 2026 standard 120Hz).
5. Cockpit / static reference frame.
## 💻 패턴
### Vignette on locomotion (Three.js)
```typescript
import * as THREE from "three";
const vignette = new THREE.ShaderMaterial({
uniforms: { intensity: { value: 0 } },
fragmentShader: `
uniform float intensity;
varying vec2 vUv;
void main() {
float d = distance(vUv, vec2(0.5));
gl_FragColor = vec4(0., 0., 0., smoothstep(0.3, 0.7, d) * intensity);
}`
});
function onLocomotion(speed: number) {
vignette.uniforms.intensity.value = THREE.MathUtils.clamp(speed / 5, 0, 0.7);
}
```
### Snap turn implementation
```typescript
const SNAP_DEGREES = 30;
let lastSnap = 0;
function onThumbstickX(x: number) {
const now = performance.now();
if (Math.abs(x) > 0.7 && now - lastSnap > 250) {
camera.rotation.y -= Math.sign(x) * THREE.MathUtils.degToRad(SNAP_DEGREES);
lastSnap = now;
}
}
```
### Teleport locomotion
```typescript
function teleport(target: THREE.Vector3) {
fadeToBlack(100);
setTimeout(() => {
rig.position.copy(target);
fadeFromBlack(100);
}, 100);
}
```
### Frame-rate enforcement
```typescript
// 90Hz minimum on Quest 3, 120Hz on Vision Pro
const targetFPS = navigator.userAgent.includes("Vision") ? 120 : 90;
renderer.setAnimationLoop((t, frame) => {
// skip work if budget exceeded
});
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Seated experience | continuous + vignette OK |
| Standing / room scale | teleport + snap turn 권장 |
| Racing / cockpit sim | static cockpit ref → 매 reduces VVC |
| Audience first-time | always teleport default |
| Pro user | option for smooth |
**기본값**: teleport + snap turn 30° + vignette on continuous motion.
## 🔗 Graph
- 부모: [[VR Sickness]]
- 변형: [[Vergence-Accommodation Conflicts]]
- Adjacent: [[가상현실 멀미 (VR Sickness)]] · [[안구 운동 기능 (Oculomotor Functions)]]
- 응용: [[가상현실(VR) 자전거 시뮬레이터]]
## 🤖 LLM 활용
**언제**: locomotion 설계 review · sickness 원인 분석 · UX option 추천.
**언제 X**: actual user testing 의 substitute (subjective experience 측정 필수).
## ❌ 안티패턴
- **Smooth locomotion default**: 매 first-time user 의 30%+ 가 sick.
- **No comfort options**: accessibility 실패.
- **Frame drop tolerance**: 60Hz fallback → severe sickness.
- **Forced rotation**: cinematic 의도 → 즉시 sick.
## 🧪 검증 / 중복
- Verified (Reason & Brand 1975 · Stanney VR Handbook · Meta VR Comfort guidelines).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — VVC mechanism + mitigation 코드 |
@@ -0,0 +1,184 @@
---
id: wiki-2026-0508-쓰기-장벽-write-barrier
title: 쓰기 장벽(Write Barrier)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Write Barrier, GC Write Barrier, Generational Barrier, Card Marking]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [garbage-collection, runtime, jvm, v8, memory-management]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: runtime-internals
framework: HotSpot/V8/Go-runtime
---
# 쓰기 장벽(Write Barrier)
## 매 한 줄
> **"매 reference store 시 GC 가 끼어드는 hook"**. 매 generational / concurrent GC 의 핵심 mechanism — 매 mutator 가 pointer 를 쓸 때마다 매 GC metadata 를 업데이트하여 매 cross-generation reference 추적 + concurrent marking 의 invariant 유지. 2026 년 모든 modern GC (G1, ZGC, Shenandoah, V8 Orinoco, Go GC) 매 필수.
## 매 핵심
### 매 정의
-`obj.field = ref` instruction 시 매 runtime-injected code.
- 매 compiler 가 매 store 직전/직후 hook 삽입.
- 매 cost: 매 native pointer write 의 1.05x ~ 1.3x.
### 매 종류
- **Card marking**: 매 heap 을 card (보통 512B) 단위로 분할 — 매 dirty bit 표시.
- **Remembered set (RSet)**: 매 region 별 incoming reference list.
- **SATB (Snapshot-At-The-Beginning)**: 매 G1/Shenandoah — 매 마킹 시작 시 graph snapshot.
- **Incremental update**: 매 CMS 류 — 매 새로 추가된 reference 추적.
- **Dijkstra-style**: 매 black-to-white reference 차단 (Go).
### 매 응용
1. Generational GC — 매 old → young reference 추적.
2. Concurrent marking — 매 mutator-collector race 방지.
3. Region-based GC (G1, ZGC) — 매 cross-region reference RSet.
## 💻 패턴
### Card marking (HotSpot CMS/G1)
```cpp
// 매 conceptual code — 매 HotSpot 의 oop_store
inline void oop_store(oop* field, oop new_val) {
*field = new_val; // 매 actual write
// 매 post-write barrier
uintptr_t card_index = ((uintptr_t)field) >> CARD_SHIFT; // 매 9 = 512B
card_table[card_index] = DIRTY; // 매 매 single byte write
}
// 매 minor GC 시 매 dirty card 만 scan — 매 old gen 전체 X
void scan_dirty_cards_for_young_refs() {
for (auto i = 0; i < card_count; i++) {
if (card_table[i] == DIRTY) {
scan_card_for_young_pointers(i);
card_table[i] = CLEAN;
}
}
}
```
### G1 RSet (remembered set)
```cpp
// 매 region 별 incoming reference 추적
class HeapRegion {
PerRegionTable rset; // 매 다른 region 의 어디가 매 나를 가리키는지
void update_rset(oop* from_field, oop to_obj) {
if (region_of(from_field) != this) {
rset.add(card_of(from_field));
}
}
};
// 매 evacuation 시 RSet scan — 매 외부 reference rewrite
```
### SATB write barrier (Shenandoah/G1 concurrent mark)
```cpp
// 매 pre-write barrier — 매 old value 를 매 marking queue 에 push
inline void satb_oop_store(oop* field, oop new_val) {
if (concurrent_marking_active) {
oop old_val = *field;
if (old_val != nullptr && !is_marked(old_val)) {
satb_queue.push(old_val); // 매 snapshot 보존
}
}
*field = new_val;
}
// 매 invariant: 매 marking 시작 시점의 graph 가 매 모두 visit
```
### V8 incremental marking (Dijkstra-style)
```cpp
// 매 black-to-white reference 차단
inline void v8_write_barrier(HeapObject* host, Object** slot, Object* value) {
if (!is_incremental_marking) {
*slot = value;
return;
}
if (Marking::IsBlack(host) && Marking::IsWhite(value)) {
// 매 violation — 매 white 를 grey 로
marking_worklist.push(value);
Marking::WhiteToGrey(value);
}
*slot = value;
}
```
### Go GC hybrid barrier (Yuasa + Dijkstra)
```go
// 매 runtime/mbarrier.go 의 conceptual
//go:nosplit
func writebarrierptr(slot **byte, val *byte) {
// 매 hybrid: 매 deletion + insertion barrier 결합
if writeBarrier.enabled {
old := *slot
if old != nil { shade(old) } // 매 Yuasa (deletion)
if val != nil { shade(val) } // 매 Dijkstra (insertion)
}
*slot = val
}
func shade(p *byte) {
obj := findObject(p)
if obj != nil && !marked(obj) {
markGrey(obj)
gcWork.push(obj)
}
}
```
### Compiler intrinsic (LLVM/HotSpot)
```cpp
// 매 JIT 가 매 oop_store 호출 매 inline expand
// 매 "object.field = ref" 매 compile 결과:
// 1. mov [rax+offset], rbx ; 매 actual store
// 2. shr rax, 9 ; 매 card index
// 3. mov byte [card_table + rax], 0 ; 매 mark dirty
// 매 cost: 매 3 instructions, 매 ~1ns
```
## 매 결정 기준
| GC type | Barrier 종류 |
|---|---|
| Generational (young/old) | Card marking + RSet |
| Concurrent marking (G1, Shenandoah) | SATB pre-barrier |
| Incremental (V8 Orinoco) | Dijkstra post-barrier |
| Region-based evacuation (G1, ZGC) | Card marking + RSet + SATB |
| Go GC | Hybrid (Yuasa + Dijkstra) |
| Reference counting | Increment/decrement barrier |
**기본값**: 매 modern multi-threaded GC 매 hybrid barrier — 매 SATB + card marking 결합.
## 🔗 Graph
- 부모: [[Garbage Collection]] · [[Memory Management]]
- 응용: [[V8 Orinoco]]
- Adjacent: [[Tri-color Marking]] · [[Concurrent Marking]]
## 🤖 LLM 활용
**언제**: 매 GC 동작 분석, 매 GC overhead 측정, 매 custom runtime 설계, 매 JIT compiler 최적화.
**언제 X**: 매 application-level memory tuning (매 heap size 조정 만 — 매 barrier internal 무관).
## ❌ 안티패턴
- **Manual barrier elision**: 매 "이 store 는 안전" 자체 판단 매 elision — 매 GC invariant 파괴.
- **Card size 무관 micro-tune**: 매 application 매 card size 변경 — 매 runtime config 영역 X.
- **Barrier ignore in JNI**: 매 native code 가 매 barrier bypass 하여 oop write — 매 dangling reference.
- **Concurrent marking 중 atomic operation 무시**: 매 race condition.
## 🧪 검증 / 중복
- Verified (Jones et al. "The Garbage Collection Handbook" 2nd ed, HotSpot source code, V8 design docs, Go runtime source).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — barrier 종류별 패턴 + runtime examples |
@@ -0,0 +1,251 @@
---
id: wiki-2026-0508-안전한-typescript-데이터-모델링-및-설정-관리-구
title: 안전한 TypeScript 데이터 모델링 및 설정 관리 구축
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [TS Safe Data Modeling, TS Config Management, Parse Don't Validate TS]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, data-modeling, configuration, validation, zod, effect]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: TypeScript 5.7+/Zod/Effect
---
# 안전한 TypeScript 데이터 모델링 및 설정 관리 구축
## 매 한 줄
> **"매 boundary 에서 parse, 매 internal 에서 trust"**. unknown data (HTTP body, env var, DB row) 가 매 application 에 들어오는 매 모든 boundary 에서 매 Zod/Effect 로 parse 하여 매 typed domain object 로 변환, 매 internal 에서는 매 branded + readonly + discriminated union 으로 매 illegal state unrepresentable. 2026 년 production TS app 의 표준.
## 매 핵심
### 매 5 원칙
1. **Parse, don't validate** (Wlaschin) — 매 boundary 에서 매 Result<T, E>.
2. **Make illegal states unrepresentable** — 매 union 으로 분기.
3. **Brand domain primitives** — 매 UserId vs OrderId.
4. **Readonly by default** — 매 mutation 매 명시적.
5. **Total functions** — 매 partial 함수 매 X.
### 매 boundary
- HTTP request body / query / params.
- Environment variables.
- DB rows (ORM 결과 매 untrusted 처리).
- File / external API.
- WebSocket / queue message.
### 매 응용
1. Env config (process.env → typed config).
2. API request validation.
3. DB row → domain entity.
4. CLI argument parsing.
## 💻 패턴
### Env config (Zod)
```ts
import { z } from "zod";
const EnvSchema = z.object({
NODE_ENV: z.enum(["development", "production", "test"]),
PORT: z.coerce.number().int().min(1).max(65535).default(3000),
DATABASE_URL: z.string().url(),
STRIPE_KEY: z.string().startsWith("sk_"),
LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
REDIS_URL: z.string().url().optional(),
});
export type Env = z.infer<typeof EnvSchema>;
export const env: Env = EnvSchema.parse(process.env);
```
### HTTP request (zod + hono)
```ts
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
const CreateOrderBody = z.object({
userId: z.string().uuid().brand<"UserId">(),
items: z.array(z.object({
sku: z.string().regex(/^[A-Z]{3}-\d{4}$/),
qty: z.number().int().positive(),
})).min(1).max(100),
couponCode: z.string().optional(),
});
const app = new Hono();
app.post("/orders", zValidator("json", CreateOrderBody), async (c) => {
const body = c.req.valid("json");
const order = await placeOrder(body);
return c.json({ id: order.id });
});
```
### Illegal state unrepresentable
```ts
// 매 X bad — 매 invalid 조합 가능
interface BadRequest {
status: "pending" | "approved" | "rejected";
approvedBy?: string;
rejectedReason?: string;
approvedAt?: Date;
}
// 매 O good — 매 discriminated union
type Request =
| { kind: "pending"; createdAt: Date }
| { kind: "approved"; createdAt: Date; approvedBy: UserId; approvedAt: Date }
| { kind: "rejected"; createdAt: Date; rejectedReason: string; rejectedAt: Date };
function notify(r: Request) {
switch (r.kind) {
case "approved": return sendApprovalMail(r.approvedBy, r.approvedAt);
case "rejected": return sendRejectionMail(r.rejectedReason);
case "pending": return;
}
}
```
### DB row → domain entity (parse layer)
```ts
import { z } from "zod";
const DbOrderRow = z.object({
id: z.string().uuid().brand<"OrderId">(),
user_id: z.string().uuid().brand<"UserId">(),
total_cents: z.number().int().nonnegative(),
currency: z.enum(["USD", "EUR", "KRW"]),
status: z.enum(["pending", "paid", "shipped", "cancelled"]),
created_at: z.coerce.date(),
});
export class OrderEntity {
private constructor(private readonly props: z.infer<typeof DbOrderRow>) {}
static fromRow(row: unknown): OrderEntity {
return new OrderEntity(DbOrderRow.parse(row));
}
get id() { return this.props.id; }
get total(): Money { return Money.of(this.props.total_cents, this.props.currency); }
isPaid(): boolean { return this.props.status === "paid"; }
}
```
### Effect schema + decode
```ts
import { Schema, Effect } from "effect";
const User = Schema.Struct({
id: Schema.String.pipe(Schema.brand("UserId")),
email: Schema.String.pipe(Schema.pattern(/^[^@]+@[^@]+$/), Schema.brand("Email")),
age: Schema.Number.pipe(Schema.int(), Schema.greaterThanOrEqualTo(0)),
});
const decodeUser = (input: unknown) =>
Schema.decodeUnknown(User)(input);
const program = Effect.gen(function* () {
const user = yield* decodeUser(rawJson);
console.log(user.email);
});
```
### Readonly + immutable update
```ts
type CartItem = Readonly<{
sku: SKU;
qty: number;
priceCents: number;
}>;
type Cart = Readonly<{
userId: UserId;
items: ReadonlyArray<CartItem>;
}>;
function addItem(cart: Cart, item: CartItem): Cart {
return { ...cart, items: [...cart.items, item] };
}
function setQty(cart: Cart, sku: SKU, qty: number): Cart {
return {
...cart,
items: cart.items.map(i => i.sku === sku ? { ...i, qty } : i),
};
}
```
### Smart constructor + validated factory
```ts
type Email = string & Brand.Brand<"Email">;
type NonEmpty = string & Brand.Brand<"NonEmpty">;
const Email = (raw: string): Email => {
if (!/^[^\s@]+@[^\s@]+$/.test(raw))
throw new TypeError(`bad email: ${raw}`);
return raw as Email;
};
const NonEmpty = (raw: string): NonEmpty => {
const t = raw.trim();
if (t.length === 0) throw new TypeError("empty string");
return t as NonEmpty;
};
interface User {
email: Email;
displayName: NonEmpty;
}
const u: User = {
email: Email("a@b.com"),
displayName: NonEmpty("Alice"),
};
```
## 매 결정 기준
| Layer | Tool |
|---|---|
| Env / config | Zod schema (startup parse) |
| HTTP boundary | Zod + framework adapter |
| DB row | Zod / Effect Schema |
| Internal domain | Branded + discriminated union |
| Complex validation pipeline | Effect Schema |
| Single project simplicity | Zod 만 |
**기본값**: Zod (boundary) + Effect Brand (internal) + readonly everywhere.
## 🔗 Graph
- 부모: [[TypeScript Type System]] · [[Domain-Driven Design]]
- 변형: [[Parse Don't Validate]] · [[Smart Constructor]]
- 응용: [[Zod]] · [[Effect Schema]] · [[Valibot]] · [[ArkType]]
- Adjacent: [[브랜디드 타입 (Branded Types)]] · [[약한 타입 탐지 (Weak Type Detection)]] · [[대규모 TypeScript 애플리케이션 아키텍처 설계]]
## 🤖 LLM 활용
**언제**: 매 production app, 매 external boundary, 매 multi-team, 매 strong audit/compliance.
**언제 X**: 매 throwaway script, 매 internal-only tool, 매 validation overhead > value.
## ❌ 안티패턴
- **`any` cast at boundary**: 매 type system bypass — 매 production runtime crash.
- **Validation only (no parse)**: 매 `validate(x)` 후 매 `x` 가 매 still untyped.
- **Mutating domain object**: 매 readonly 무시 — 매 race condition.
- **Schema drift**: 매 API spec 과 매 zod schema 매 manual sync — 매 codegen 사용.
- **Boundary 매 optional check**: 매 일부 endpoint 만 검증 — 매 전부 검증.
## 🧪 검증 / 중복
- Verified (Scott Wlaschin "Domain Modeling Made Functional", Zod docs, Effect Schema docs, TypeScript best practices 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — boundary parsing + 7 patterns |
@@ -0,0 +1,175 @@
---
id: wiki-2026-0508-약한-타입-탐지-weak-type-detection
title: 약한 타입 탐지 (Weak Type Detection)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Weak Types, TypeScript Weak Type, Empty-like Type Detection]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-system, weak-types, type-safety]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: TypeScript 5.7+
---
# 약한 타입 탐지 (Weak Type Detection)
## 매 한 줄
> **"매 모든 property 가 optional 인 type — 매 거의 모든 object 와 assignable 한 위험한 type"**. TypeScript 가 weak type 을 special-case 로 인식해 매 disjoint object 와의 assignment 를 차단하는 기능. 매 config object, 매 settings, 매 partial DTO 에서 매 silent typo bug 차단.
## 매 핵심
### 매 정의
- **Weak type**: 매 모든 member 가 optional 한 object type.
```ts
interface Options {
timeout?: number;
retries?: number;
debug?: boolean;
}
```
- 매 normal structural rule 에 따르면 매 `{}` 도 매 `Options` 와 호환.
- TS 가 매 special rule — 매 source object 가 매 weak type 의 어떤 property 도 매 안 가지면 매 error.
### 매 동작
```ts
const opts: Options = { timoeut: 100 }; // 매 typo
// 매 Error: Object literal may only specify known properties...
// AND
// 매 Type {} has no properties in common with type Options
```
### 매 응용
1. Config / settings object — 매 typo prevention.
2. Partial DTO update.
3. CSS-in-JS style props.
4. Plugin options.
## 💻 패턴
### Basic weak type
```ts
interface FetchOptions {
timeout?: number;
retries?: number;
signal?: AbortSignal;
}
function fetchWith(url: string, opts: FetchOptions) { /* ... */ }
fetchWith("/api", { timeout: 5000 }); // 매 ok
fetchWith("/api", { timoeut: 5000 }); // 매 error — 매 unknown property
fetchWith("/api", {}); // 매 ok — 매 모두 optional 이므로
fetchWith("/api", { foo: 1 } as any); // 매 escape hatch (매 X 권장)
```
### Weak type detection in lib code
```ts
// 매 utility — 매 type 이 weak 인지 compile-time check
type IsWeakType<T> = {} extends T
? keyof T extends never ? false : true
: false;
type CheckOpts = IsWeakType<FetchOptions>; // 매 true
type CheckUser = IsWeakType<{ id: string; name: string }>; // 매 false
```
### Required + Optional 명확 분리
```ts
// 매 weak type 위험 회피 — 매 최소 1 required
interface SafeConfig {
endpoint: string; // 매 required
timeout?: number;
retries?: number;
}
const c: SafeConfig = { endpoint: "/api" };
```
### Discriminated union 으로 weak type 회피
```ts
type Config =
| { mode: "polling"; intervalMs: number }
| { mode: "websocket"; url: string }
| { mode: "sse"; endpoint: string };
function start(c: Config) {
switch (c.mode) {
case "polling": return startPolling(c.intervalMs);
case "websocket": return startWS(c.url);
case "sse": return startSSE(c.endpoint);
}
}
start({ mode: "polling", intervalMs: 1000 });
start({}); // 매 error — 매 discriminator 없음
```
### Brand to forbid empty object assignment
```ts
import { Brand } from "effect";
type ValidatedOptions = FetchOptions & Brand.Brand<"ValidatedOptions">;
function validateOpts(o: FetchOptions): ValidatedOptions {
if (Object.keys(o).length === 0)
throw new Error("at least one option required");
return o as ValidatedOptions;
}
function fetchStrict(url: string, opts: ValidatedOptions) { /* ... */ }
fetchStrict("/api", validateOpts({ timeout: 5000 })); // 매 ok
fetchStrict("/api", {}); // 매 type error
```
### ESLint rule 매 weak type 사용 보강
```jsonc
{
"rules": {
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/strict-boolean-expressions": "error",
"@typescript-eslint/no-empty-object-type": "error"
}
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 완전 optional config | Weak type (TS native check 활용) |
| 매 1+ required 명시 가능 | Required + optional 분리 |
| 매 mode-dependent options | Discriminated union |
| 매 strict validation 필요 | Brand + smart constructor |
| 매 plugin/3rd-party 매 default | Required + optional |
**기본값**: 매 1+ required field 추가. 매 truly all-optional 매 weak type detection 의존.
## 🔗 Graph
- 부모: [[TypeScript Type System]] · [[Structural Typing]]
- 변형: [[Excess Property Check]] · [[Discriminated Union]]
- Adjacent: [[브랜디드 타입 (Branded Types)]] · [[Type Narrowing]] · [[안전한 TypeScript 데이터 모델링 및 설정 관리 구축]]
## 🤖 LLM 활용
**언제**: 매 config / options object 설계, 매 typo prevention 강조, 매 plugin API 설계.
**언제 X**: 매 internal data, 매 1-callsite, 매 typing overhead > value.
## ❌ 안티패턴
- **All-optional 매 무지각 사용**: 매 weak type protection 우연 의존 — 매 명시적 required 1 권장.
- **`as any` 우회**: 매 weak type error 매 cast 로 무시 — 매 typo 통과.
- **Object spread 매 weak type 회피**: 매 `{...userInput}` 매 typed 안 됨.
- **Optional 만의 enum-like**: 매 mode 분기 매 optional bool — 매 discriminated union 사용.
## 🧪 검증 / 중복
- Verified (TypeScript Handbook "Weak Types", TS 2.4 release notes, Marius Schulz blog).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — weak type 정의 + 회피 패턴 6개 |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-오래된-공간-old-space
title: 오래된 공간(Old Space)
category: 10_Wiki/Topics
status: duplicate
canonical_id: v8-old-space
duplicate_of: "[[V8 Memory Layout]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, v8, memory, garbage-collection]
last_reinforced: 2026-05-10
github_commit: pending
---
# 오래된 공간(Old Space)
> **이 문서는 [[V8 Memory Layout]] 의 중복본입니다.** Canonical 문서로 redirect.
## 매 핵심 요약 (specialization)
- 매 V8 heap 의 long-lived object 의 region — 매 2 회 minor GC 의 survive 후 promote.
- 매 GC 알고리즘: Mark-Sweep-Compact (major GC) — 매 Orinoco 의 incremental/concurrent.
- 매 modern (V8 12+): 매 pointer compression 의 4GB heap limit (compressed mode).
## 🔗 Graph
- 부모: [[V8 Memory Layout]] (canonical)
- Adjacent: [[Young Generation]] · [[Orinoco]] · [[Mark and Sweep]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-외부-api-데이터-및-설정-파일-처리
title: 외부 API 데이터 및 설정 파일 처리
category: 10_Wiki/Topics
status: duplicate
canonical_id: runtime-type-validation
duplicate_of: "[[Runtime_Validation|Runtime Type Validation]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, validation, config, schema]
last_reinforced: 2026-05-10
github_commit: pending
---
# 외부 API 데이터 및 설정 파일 처리
> **이 문서는 [[Runtime_Validation|Runtime Type Validation]] 의 중복본입니다.** Canonical 문서로 redirect.
## 매 핵심 요약 (specialization)
- 매 API response + 매 config file (JSON/YAML/TOML) 의 schema 의 validate.
- 매 libraries: Zod (universal), Joi (server-side), Ajv (JSON Schema), Pydantic (Python).
- 매 pattern: 매 boundary 에서 parse — 매 internal logic 은 매 typed data 만 다룸.
## 🔗 Graph
- 부모: [[Runtime_Validation|Runtime Type Validation]] (canonical)
- Adjacent: [[Zod]] · [[JSON Schema]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-외부-api-데이터의-런타임-검증-후-처리
title: 외부 API 데이터의 런타임 검증 후 처리
category: 10_Wiki/Topics
status: duplicate
canonical_id: runtime-type-validation
duplicate_of: "[[Runtime_Validation|Runtime Type Validation]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, validation, zod, type-safety]
last_reinforced: 2026-05-10
github_commit: pending
---
# 외부 API 데이터의 런타임 검증 후 처리
> **이 문서는 [[Runtime_Validation|Runtime Type Validation]] 의 중복본입니다.** Canonical 문서로 redirect.
## 매 핵심 요약 (specialization)
- 매 외부 API response 의 매 trust 의 X — 매 runtime parse + validate 의 필수.
- 매 libraries: Zod (TS 의 de facto), Valibot (smaller bundle), io-ts, ArkType.
- 매 pattern: `schema.parse(data)` → 매 typed result, parse 실패 시 throw.
## 🔗 Graph
- 부모: [[Runtime_Validation|Runtime Type Validation]] (canonical)
- Adjacent: [[Zod]] · [[Schema Validation]] · [[Parse Don't Validate]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-외부-라이브러리-api-설계
title: 외부 라이브러리 API 설계
category: 10_Wiki/Topics
status: duplicate
canonical_id: library-api-design
duplicate_of: "[[API Design Principles]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, api-design, library, sdk]
last_reinforced: 2026-05-10
github_commit: pending
---
# 외부 라이브러리 API 설계
> **이 문서는 [[API Design Principles]] 의 중복본입니다.** Canonical 문서로 redirect.
## 매 핵심 요약 (specialization)
- 매 third-party library 의 public API 의 design — 매 backward-compat + ergonomics.
- 매 principles: minimal surface area, semver discipline, 매 deprecated → removed cycle.
- 매 modern (2026): TypeScript-first, 매 `exports` field (subpath), 매 ESM-only 의 trend.
## 🔗 Graph
- Adjacent: [[Library Design]] · [[Backward Compatibility]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-웹-워커-이벤트-포워딩-event-forwarding
title: 웹 워커 이벤트 포워딩 Event Forwarding
category: 10_Wiki/Topics
status: duplicate
canonical_id: web-worker-event-forwarding
duplicate_of: "[[Web Worker Communication]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, web-worker, event, postmessage]
last_reinforced: 2026-05-10
github_commit: pending
---
# 웹 워커 이벤트 포워딩 Event Forwarding
> **이 문서는 [[Web Worker Communication]] 의 중복본입니다.** Canonical 문서로 redirect.
## 매 핵심 요약 (specialization)
- 매 main thread 와 worker 사이 의 event 전달 pattern — 매 `postMessage` + `MessageChannel`.
- 매 typed wrapper: Comlink (RPC-like proxy), 매 worker-rpc, 매 threads.js.
- 매 modern (2026): 매 SharedArrayBuffer + Atomics, 매 transferable streams.
## 🔗 Graph
- Adjacent: [[postMessage]] · [[Comlink]] · [[MessageChannel]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-의존성-역전-원칙-dependency-inversion-p
title: 의존성 역전 원칙 (Dependency Inversion Principle DIP)
category: 10_Wiki/Topics
status: duplicate
canonical_id: dependency-inversion-principle
duplicate_of: "[[Dependency Inversion Principle DIP]]"
aliases: [DIP, SOLID-D]
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, solid, design-principle]
last_reinforced: 2026-05-10
github_commit: pending
---
# 의존성 역전 원칙 (Dependency Inversion Principle DIP)
> **이 문서는 [[Dependency Inversion Principle DIP]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- SOLID 의 D — 고수준 module 은 저수준 module 에 의존하지 않음.
- 둘 다 abstraction 에 의존 — abstraction 은 details 에 의존하지 않음.
- DI (Dependency Injection) 와 구분 — DIP 는 원칙, DI 는 구현 기법.
## 🔗 Graph
- 관련: [[SOLID Principles]] · [[Dependency Injection]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-이전-세대-old-generation-space
title: 이전 세대(Old Generation Space)
category: 10_Wiki/Topics
status: duplicate
canonical_id: old-generation-space
duplicate_of: "[[Old Generation Space]]"
aliases: [Tenured Generation, Old Gen]
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, gc, jvm, memory]
last_reinforced: 2026-05-10
github_commit: pending
---
# 이전 세대(Old Generation Space)
> **이 문서는 [[Old Generation Space]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- Generational GC 의 long-lived objects 영역.
- Major GC (Full GC) 대상 — Young Gen 보다 빈도 낮고 비용 큼.
- Promotion: Young → Old (survival count 임계 도달 시).
## 🔗 Graph
- 관련: [[Young Generation]] · [[Incremental marking]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,230 @@
---
id: wiki-2026-0508-코드-포매팅-code-formatting
title: 코드 포매팅 (Code Formatting)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Code Formatting, Auto-formatting, Prettier, Black, gofmt]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [tooling, style, formatter, prettier, ruff, black]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: polyglot
framework: prettier-ruff-gofmt
---
# 코드 포매팅 (Code Formatting)
## 매 한 줄
> **"매 style debate 의 종결자"**. Code formatting 은 코드의 visual structure (whitespace, indent, line breaks, quote style) 를 deterministic rule 로 enforce 하는 tooling 영역. 2026 현재 매 모든 mainstream language 는 official 또는 de-facto formatter 를 가지며 (Black, Ruff format, Prettier, gofmt, rustfmt, dart format, ktlint), CI 의 commit hook 의 universal 으로 적용. 매 "어떻게 보일지" 의 human discussion 의 X — 매 tool 의 결정.
## 매 핵심
### 매 formatter 의 철학
- **Opinionated** (매 ideal): 매 minimal config — Black, gofmt, Prettier. 매 bikeshedding 의 elimination.
- **Configurable** (매 legacy): 매 ESLint stylistic rules, autopep8 — 매 team config drift 의 risk.
- **Idempotent**: `format(format(x)) == format(x)`. 매 essential property — CI loop safety.
- **AST-based**: 매 token stream 의 parse → reformat. 매 regex 의 X.
### 매 linter vs formatter
- **Formatter**: whitespace, line breaks, quotes (style only). 매 semantics 의 X-change.
- **Linter**: bugs, anti-patterns, unused vars (semantics). 매 ESLint, Ruff check, golangci-lint.
- **2026 trend**: Ruff (Python) 의 both 의 unify — `ruff format` + `ruff check` 의 매 single binary. Biome (JS/TS) 의 same path.
### 매 응용
1. **Pre-commit hook**: `pre-commit` (Python), `lefthook`, `husky` 의 매 staged file 의 format.
2. **CI gate**: `ruff format --check` / `prettier --check` — diff 가 있으면 fail.
3. **Editor on-save**: VS Code `editor.formatOnSave: true` + `defaultFormatter`.
4. **Mass migration**: `git ls-files | xargs ruff format` — 매 single PR 의 entire repo reformat.
## 💻 패턴
### Prettier (JS/TS/JSON/MD/CSS) — 2026 v3
```json
// .prettierrc.json
{
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2,
"plugins": ["prettier-plugin-tailwindcss"]
}
```
```bash
# format all files in repo
npx prettier --write .
# CI check
npx prettier --check .
```
### Ruff format (Python) — 2026 default Python formatter
```toml
# pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
docstring-code-format = true # format code in docstrings
```
```bash
ruff format . # write
ruff format --check . # CI
ruff check --fix . # lint + autofix
```
### Black (Python, legacy but stable)
```toml
[tool.black]
line-length = 100
target-version = ["py312"]
skip-string-normalization = false
```
### gofmt / goimports (Go) — bundled with toolchain
```bash
gofmt -w ./...
goimports -w ./... # also organizes imports
```
```go
// before
package main
import("fmt"
"os")
func main(){fmt.Println(os.Args)}
// after gofmt
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Args)
}
```
### rustfmt (Rust)
```toml
# rustfmt.toml
edition = "2024"
max_width = 100
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
```
```bash
cargo fmt
cargo fmt -- --check # CI
```
### EditorConfig (cross-tool baseline)
```ini
# .editorconfig — every editor respects this
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
[*.{js,ts,tsx,json}]
indent_size = 2
[*.py]
indent_size = 4
[Makefile]
indent_style = tab
```
### Pre-commit hook (universal)
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.0
hooks:
- id: ruff-format
- id: ruff
args: [--fix]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0
hooks:
- id: prettier
types_or: [javascript, typescript, json, markdown]
```
### CI gate (GitHub Actions)
```yaml
- name: Check formatting
run: |
ruff format --check .
ruff check .
npx prettier --check .
```
### Mass-format ignore (avoid blame churn)
```
# .git-blame-ignore-revs
# Ruff format mass-apply 2026-04-15
abc123def456...
```
```bash
git config blame.ignoreRevsFile .git-blame-ignore-revs
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Python 신규 프로젝트 | Ruff format (Black-compatible, 100x faster) |
| Python legacy | Black 유지 — Ruff 의 drop-in 의 가능 |
| JS/TS | Prettier 또는 Biome (faster, Rust-based) |
| Go | gofmt (no choice, no config) |
| Rust | rustfmt |
| 매 polyglot monorepo | dprint 또는 Trunk |
| Team debate 중 | Opinionated formatter 의 즉시 채택 — 매 discussion close |
**기본값**: Ruff (Python), Prettier 또는 Biome (web), gofmt (Go), rustfmt (Rust). 매 pre-commit + CI check.
## 🔗 Graph
- 부모: [[Code Quality]] · [[Developer Experience]]
- 변형: [[Linter]] · [[Static Analysis]]
- 응용: [[153_pre-commit과_품질_게이트|Pre-commit Hooks]]
- Adjacent: [[Prettier]]
## 🤖 LLM 활용
**언제**: Generated code 의 file write 후 항상 `ruff format` / `prettier --write` 의 run — LLM output 의 indent inconsistency 의 normalize. PR diff 의 minimize.
**언제 X**: Format-only PR 의 logic change 와 mix 의 X — separate commit / PR 로 분리. Reviewer 의 noise 의 reduction.
## ❌ 안티패턴
- **Custom rules everywhere**: 매 team-specific style 의 invention. 매 onboarding cost 의 increase. 매 Black/Prettier default 의 accept.
- **Format on commit only**: Editor save 의 X-format 의 경우 매 every commit 의 noise. Editor integration 의 essential.
- **Format + logic 의 mixed PR**: Review impossible. 매 separate PR.
- **No CI check**: Pre-commit 의 bypass 의 가능 (`-n`). 매 CI 의 source of truth.
- **`tabWidth` debate**: 매 EditorConfig 의 fix — once and forget.
## 🧪 검증 / 중복
- Verified (Prettier docs 2026, Ruff docs 0.6+, Go style guide).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — formatters (Ruff, Prettier, gofmt, rustfmt) + CI/pre-commit patterns |
@@ -0,0 +1,204 @@
---
id: wiki-2026-0508-타입-서술어-type-predicates
title: 타입 서술어 (Type Predicates)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Type Predicates, User-Defined Type Guards, "x is T"]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-system, narrowing, guards]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: typescript-5.5+
---
# 타입 서술어 (Type Predicates)
## 매 한 줄
> **"매 boolean 의 type 정보 의 carrier"**. Type predicate 는 TypeScript 의 function 의 return type position 에서 `parameterName is Type` 형태로 선언되어, 매 true return 의 경우 compiler 의 narrowing 의 trigger 하는 mechanism. 2026 TS 5.5+ 부터 매 inferred type predicate 가 도입되어 explicit `is` annotation 없이도 `arr.filter(x => x !== null)` 의 자동 narrow.
## 매 핵심
### 매 syntax
- **명시**: `function isString(x: unknown): x is string { return typeof x === 'string' }` — 매 `: x is string` 가 predicate.
- **`asserts`**: `function assert(c: unknown): asserts c { if (!c) throw }` — 매 throw-or-narrow.
- **TS 5.5 inference**: `[1, null, 2].filter(x => x !== null)``number[]` 의 자동 inference (이전 `(number | null)[]`).
### 매 type guard 의 종류
1. `typeof` guard — primitive (`string`, `number`, `boolean`, `symbol`, `bigint`, `undefined`, `function`, `object`).
2. `instanceof` guard — class hierarchy.
3. `in` operator guard — property existence.
4. Equality narrowing — `x === 'foo'`.
5. **User-defined predicate** — 매 custom logic.
6. **Discriminated union**`kind` field 의 switch.
### 매 응용
1. JSON parse 후 runtime validation (Zod, Valibot).
2. `Array.filter` 후 nullish 의 strip.
3. AST node type 의 narrowing.
4. API response 의 shape 의 verification.
## 💻 패턴
### 기본 user-defined predicate
```typescript
function isString(x: unknown): x is string {
return typeof x === 'string'
}
function process(input: unknown) {
if (isString(input)) {
input.toUpperCase() // OK — narrowed to string
}
}
```
### Discriminated union 의 narrowing
```typescript
type Result<T> =
| { ok: true; value: T }
| { ok: false; error: string }
function isOk<T>(r: Result<T>): r is { ok: true; value: T } {
return r.ok
}
const r: Result<number> = await fetchSomething()
if (isOk(r)) {
console.log(r.value) // narrowed
}
```
### Array filter — TS 5.5 inferred predicate
```typescript
// Before TS 5.5: result is (number | null)[]
// TS 5.5+: result is number[] — auto-inferred
const result = [1, null, 2, null, 3].filter(x => x !== null)
// explicit predicate (still works, useful for older TS)
function nonNull<T>(x: T | null | undefined): x is T {
return x !== null && x !== undefined
}
const r2 = [1, null, 2].filter(nonNull) // number[]
```
### `asserts` predicate (throw or narrow)
```typescript
function assertDefined<T>(
x: T | null | undefined,
msg = 'value is null'
): asserts x is T {
if (x === null || x === undefined) throw new Error(msg)
}
function use(x: string | null) {
assertDefined(x)
x.toUpperCase() // narrowed to string
}
```
### Schema-based predicate (Zod)
```typescript
import { z } from 'zod'
const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
})
type User = z.infer<typeof UserSchema>
function isUser(x: unknown): x is User {
return UserSchema.safeParse(x).success
}
// usage with API response
const data: unknown = await fetch('/me').then(r => r.json())
if (isUser(data)) {
console.log(data.email) // typed as User
}
```
### `in` operator guard (cheap, no predicate function)
```typescript
type Cat = { meow: () => void }
type Dog = { bark: () => void }
function speak(animal: Cat | Dog) {
if ('meow' in animal) animal.meow()
else animal.bark()
}
```
### Generic predicate (preserves narrowing through generics)
```typescript
function isOneOf<T extends readonly unknown[]>(
value: unknown,
options: T
): value is T[number] {
return options.includes(value as never)
}
const colors = ['red', 'green', 'blue'] as const
const x: string = 'red'
if (isOneOf(x, colors)) {
x // narrowed: 'red' | 'green' | 'blue'
}
```
### Anti-pattern detection — predicate 의 lie
```typescript
// BAD — predicate 의 always true return 의 가능
function isString(x: unknown): x is string {
return true // BUG — compiler 의 trust, runtime 의 explode
}
// GOOD — predicate body 의 actually verify
function isString(x: unknown): x is string {
return typeof x === 'string'
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Primitive check | `typeof` 직접 — predicate 의 X-required |
| Class instance | `instanceof` — predicate 의 X-required |
| Discriminated union | `kind` field 의 switch — auto-narrow |
| API response shape | Zod/Valibot schema + `safeParse` |
| Array filter null strip | TS 5.5+ 의 auto, 또는 `nonNull` predicate |
| Throw-on-fail | `asserts` predicate |
| 단순 reusable check | User-defined `x is T` |
**기본값**: Discriminated union 의 prefer (no predicate needed). 매 runtime data 의 Zod schema. Custom predicate 의 매 only-when-needed.
## 🔗 Graph
- 부모: [[TypeScript Type System]] · [[Type Narrowing]]
- 변형: [[Discriminated_Unions|Discriminated Unions]]
- 응용: [[Zod]] · [[Runtime Validation]]
- Adjacent: [[타입_가드_(Type_Predicates)|Type Guards]]
## 🤖 LLM 활용
**언제**: Untyped JSON, `unknown` value, 또는 union narrow 의 필요 시. 매 LLM 의 generated predicate 의 body 의 always verify — `return true` 의 lie 의 catch.
**언제 X**: Discriminated union 의 자연스럽 work 하면 predicate 의 over-engineering. 매 simple `kind` switch 의 우선.
## ❌ 안티패턴
- **Lying predicate**: body 의 actually check 하지 않음 — runtime 의 crash.
- **`as` 의 abuse**: `x as User` — 매 type assertion 의 unsafe. 매 predicate + Zod 의 prefer.
- **Predicate 의 over-use**: discriminated union 의 cover 하는 case 의 unnecessary predicate.
- **Wide predicate**: `function isObject(x: unknown): x is object` — 매 too coarse, narrow 하게 specify.
## 🧪 검증 / 중복
- Verified (TypeScript handbook 2026, TS 5.5 release notes).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — type predicates with TS 5.5 inferred predicates + Zod patterns |
@@ -0,0 +1,227 @@
---
id: wiki-2026-0508-타입-안전성-type-safety
title: 타입 안전성 (Type Safety)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Type Safety, Strong Typing, Sound Typing]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [type-system, correctness, typescript, rust, soundness]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: polyglot
framework: typescript-rust-haskell
---
# 타입 안전성 (Type Safety)
## 매 한 줄
> **"매 ill-typed program 의 X-run"**. Type safety 는 type system 이 program execution 동안 type error (e.g., string 에 number method 호출) 가 발생하지 않음을 guarantee 하는 property. **Static** type safety (Rust, Haskell, OCaml) 는 compile time 에 reject, **Dynamic** (Python, JS) 는 runtime 에 throw, **Gradual** (TypeScript, Python+mypy) 는 매 mix. 2026 의 trend 는 매 sound + gradual 의 confluence.
## 매 핵심
### 매 type safety 의 차원
- **Soundness**: well-typed program 의 type error 의 X. Rust/Haskell/Idris 의 sound. TypeScript 의 unsound (intentional — 매 ergonomic trade-off).
- **Completeness**: type-correct program 의 모두 의 accept. 매 undecidable 한 trade-off.
- **Strong vs Weak**: strong = no implicit coercion (Python), weak = implicit (JS `'5' + 3 === '53'`).
- **Static vs Dynamic**: check time.
- **Manifest vs Inferred**: annotation 의 explicit 여부.
### 매 unsoundness escape hatches
- TS: `any`, `as`, `// @ts-ignore`, function bivariance, `Object.assign`.
- Python: `Any`, `cast`, missing annotations.
- Rust: `unsafe` block — 매 explicit, 매 audit-able.
### 매 응용
1. Refactoring confidence — rename 의 자동 propagate.
2. API contract — request/response shape 의 enforce.
3. Bug prevention — null deref, off-by-one type error 의 catch.
4. Self-documenting code — type 의 living spec.
## 💻 패턴
### Branded types (nominal typing in structural system)
```typescript
type UserId = string & { readonly __brand: 'UserId' }
type OrderId = string & { readonly __brand: 'OrderId' }
function makeUserId(s: string): UserId {
return s as UserId // single trusted constructor
}
function getUser(id: UserId) { /* ... */ }
const u = makeUserId('u_abc')
const o = 'o_123' as OrderId
getUser(u) // OK
getUser(o) // ERROR — different brand
```
### Exhaustive switch (compile-time correctness)
```typescript
type Status = 'pending' | 'active' | 'archived'
function label(s: Status): string {
switch (s) {
case 'pending': return '대기'
case 'active': return '활성'
case 'archived': return '보관'
default: {
const _: never = s
throw new Error('unreachable')
}
}
}
// Adding 'deleted' to Status → compile error here, not runtime crash
```
### Result type (no exception)
```typescript
type Result<T, E = Error> =
| { ok: true; value: T }
| { ok: false; error: E }
async function fetchUser(id: string): Promise<Result<User>> {
try {
const r = await fetch(`/u/${id}`)
if (!r.ok) return { ok: false, error: new Error(`HTTP ${r.status}`) }
return { ok: true, value: await r.json() }
} catch (e) {
return { ok: false, error: e as Error }
}
}
```
### Schema-driven I/O (runtime + static)
```typescript
import { z } from 'zod'
const ApiUser = z.object({
id: z.string().uuid(),
email: z.string().email(),
age: z.number().int().min(0),
})
type ApiUser = z.infer<typeof ApiUser>
async function getUser(id: string): Promise<ApiUser> {
const raw = await fetch(`/u/${id}`).then(r => r.json())
return ApiUser.parse(raw) // throws on shape mismatch
}
```
### Rust — soundness via ownership
```rust
fn main() {
let s = String::from("hello");
let r1 = &s;
let r2 = &s; // OK — multiple immutable borrows
println!("{r1} {r2}");
let m = &mut s; // ERROR — can't borrow mutable while immutable exists
}
```
### Python — gradual typing with mypy/pyright strict
```python
# pyproject.toml
[tool.pyright]
strict = ["src"]
reportMissingTypeStubs = "error"
# code
from typing import Literal
def label(s: Literal["pending", "active", "archived"]) -> str:
match s:
case "pending": return "대기"
case "active": return "활성"
case "archived": return "보관"
# mypy/pyright catches missing case
```
### TS strict mode (essential 2026 baseline)
```json
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true, // arr[i] is T | undefined
"exactOptionalPropertyTypes": true,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true
}
}
```
### `unknown` over `any`
```typescript
// BAD
function parse(json: string): any {
return JSON.parse(json)
}
// GOOD
function parse(json: string): unknown {
return JSON.parse(json) // forces caller to narrow
}
const data = parse('{"x":1}')
// data.x // ERROR
if (typeof data === 'object' && data !== null && 'x' in data) {
data.x // OK
}
```
### Enforced phantom state (typestate pattern)
```typescript
type Builder<State extends 'empty' | 'has-name' | 'ready'> = {
setName(n: string): Builder<'has-name'>
setEmail(e: string): Builder<'ready'> // assume after name
build(): User // only on 'ready'
}
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| 신규 TS 프로젝트 | `strict: true` + `noUncheckedIndexedAccess` |
| Python | pyright strict, mypy strict |
| Critical / safety | Rust, OCaml, Idris (sound) |
| API boundary | Schema (Zod, Pydantic) — runtime + static |
| ID confusion 방지 | Branded types |
| Error 의 throw 회피 | `Result<T, E>` |
| Interop with untyped | `unknown` + narrow (NOT `any`) |
| Performance + safety | Rust |
**기본값**: Static + sound (Rust) 또는 Static + gradual strict (TS strict, Python pyright strict). API boundary 의 schema. `any` 의 ban.
## 🔗 Graph
- 부모: [[TypeScript 타입 시스템 (TypeScript Type System)|Type System]]
- 응용: [[TypeScript]] · [[Zod]]
- Adjacent: [[Branded Types]] · [[Type Narrowing]] · [[Result Type]]
## 🤖 LLM 활용
**언제**: 매 generated code 의 strict mode 의 compile 확인. 매 LLM 의 `any` cast 의 propose 의 reject — `unknown` + narrow 의 demand.
**언제 X**: 매 prototype 의 throwaway script 의 over-engineer X — 매 production path 의 only-strict.
## ❌ 안티패턴
- **`any` proliferation**: TS 의 `any` 의 single use 의 entire chain 의 type 의 lose.
- **`as` 의 lying cast**: `data as User` without verification.
- **String IDs everywhere**: branded types 의 X-use → wrong-ID-as-arg bug.
- **Throw-everything**: Result type 또는 typed error 의 X-use.
- **Loose schema**: Zod `.passthrough()` 의 abuse — unknown fields 의 leak.
## 🧪 검증 / 중복
- Verified (TypeScript docs, Rust Book 2026, Pierce — Types and Programming Languages).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — soundness, branded types, Result, schema, strict configs |
@@ -0,0 +1,214 @@
---
id: wiki-2026-0508-타입-좁히기-type-narrowing
title: 타입 좁히기 (Type Narrowing)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Type Narrowing, Control Flow Analysis, CFA]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [typescript, type-system, narrowing, control-flow]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: typescript-5.5+
---
# 타입 좁히기 (Type Narrowing)
## 매 한 줄
> **"매 control flow 의 type 의 refine"**. Type narrowing 은 TypeScript compiler 가 conditional branch, equality check, predicate call 등을 추적하여 union type 을 점점 더 specific 한 type 으로 축소하는 process. 매 control flow analysis (CFA) 의 결과로, 매 runtime check 의 동일 코드가 type level 에서도 evidence 의 carry — 매 type system 의 ergonomic core.
## 매 핵심
### 매 narrowing trigger
1. **`typeof`**: primitive 7종.
2. **`instanceof`**: class.
3. **`in`** operator: property existence.
4. **Equality** (`===`, `!==`): literal narrowing.
5. **Truthiness**: `if (x)` — null/undefined/0/'' 의 strip.
6. **User-defined predicate**: `x is T`.
7. **`asserts`**: throw-or-narrow.
8. **Discriminated union**: `kind` field 의 switch.
9. **Array.length**: `if (arr.length > 0)` 의 tuple narrowing (제한적).
10. **Aliased condition** (TS 4.4+): `const isStr = typeof x === 'string'; if (isStr) ...`.
### 매 narrowing 의 scope
- `if` block 안에서만 유효.
- Closure 의 capture 의 후 narrowing 의 lost (callback 안의 `x` 의 다시 union).
- `let` reassign 의 후 narrowing 의 reset.
### 매 응용
1. Optional handling — `if (user)``user.name`.
2. Discriminated union 의 exhaustive switch.
3. Error type 의 narrowing (`if (err instanceof HttpError)`).
4. Array filter null strip.
## 💻 패턴
### typeof narrowing
```typescript
function pad(x: string | number) {
if (typeof x === 'number') return ' '.repeat(x) // x: number
return x.padStart(10) // x: string
}
```
### Discriminated union (가장 idiomatic)
```typescript
type Shape =
| { kind: 'circle'; r: number }
| { kind: 'square'; side: number }
| { kind: 'rect'; w: number; h: number }
function area(s: Shape): number {
switch (s.kind) {
case 'circle': return Math.PI * s.r ** 2
case 'square': return s.side ** 2
case 'rect': return s.w * s.h
default: {
const _exhaustive: never = s // compile error if Shape extended
throw new Error('unreachable')
}
}
}
```
### Truthiness narrowing
```typescript
function greet(name: string | null | undefined) {
if (name) {
name.toUpperCase() // name: string
}
}
```
### `in` operator
```typescript
type Fish = { swim: () => void }
type Bird = { fly: () => void }
function move(p: Fish | Bird) {
if ('swim' in p) p.swim()
else p.fly()
}
```
### instanceof
```typescript
class HttpError extends Error { status: number = 500 }
try {
await fetch(url)
} catch (e) {
if (e instanceof HttpError) console.error(e.status) // narrowed
else if (e instanceof Error) console.error(e.message)
else console.error('unknown', e)
}
```
### Aliased condition (TS 4.4+)
```typescript
function process(x: string | number[]) {
const isArray = Array.isArray(x)
if (isArray) {
x.length // x: number[]
} else {
x.charAt(0) // x: string
}
}
```
### TS 5.5 inferred predicate (자동 narrowing in filter)
```typescript
const mixed: (string | null)[] = ['a', null, 'b']
const strings = mixed.filter(x => x !== null)
// ^? string[] (TS 5.5+ — previously (string | null)[])
```
### Closure 의 narrowing 의 loss
```typescript
function example(x: string | null) {
if (x === null) return
x.toUpperCase() // OK
setTimeout(() => {
x.toUpperCase() // ERROR: x might be null again (closure)
})
// Fix:
const fixed = x // const captured — narrowing preserved
setTimeout(() => fixed.toUpperCase())
}
```
### never 의 exhaustiveness
```typescript
type Action = { t: 'load' } | { t: 'save' }
function handle(a: Action) {
switch (a.t) {
case 'load': return load()
case 'save': return save()
default: {
const _: never = a // compile error if Action grows
throw new Error()
}
}
}
```
### Optional chaining + narrowing
```typescript
type User = { profile?: { email?: string } }
function send(u: User) {
if (u.profile?.email) {
u.profile.email // string (not undefined)
}
}
```
## 매 결정 기준
| 상황 | Narrowing approach |
|---|---|
| Union of primitives | `typeof` |
| Class hierarchy | `instanceof` |
| Object shape variants | Discriminated union (`kind` field) |
| Property existence check | `in` |
| Custom validation | User-defined predicate |
| Throw-or-narrow | `asserts` |
| Filter null/undefined | TS 5.5 의 auto, 또는 explicit predicate |
| Exhaustiveness | `never` 의 default branch |
**기본값**: Discriminated union 의 design — 매 narrowing 의 free. 매 `never` exhaustiveness check 의 매 switch 에 추가.
## 🔗 Graph
- 부모: [[TypeScript Type System]]
- 변형: [[Type Predicates]]
- 응용: [[Discriminated_Unions|Discriminated Unions]] · [[Error Handling]]
- Adjacent: [[Control Flow Analysis]] · [[Exhaustiveness Checking]]
## 🤖 LLM 활용
**언제**: Union type 의 specific branch handling. 매 LLM 의 generate 한 switch 의 `never` exhaustiveness 의 추가 의 verify.
**언제 X**: 매 단순 single-type 의 over-narrowing 의 unnecessary.
## ❌ 안티패턴
- **`as` cast 의 abuse**: narrowing 의 가능한 곳에서 `x as User` — unsafe.
- **`!` non-null assertion overuse**: `x!.foo` — narrowing 의 알려주는 게 좋음.
- **Closure 의 narrowing 의 expectation**: `let` mutable 의 narrowing 의 reset.
- **No exhaustive check**: discriminated union 의 grow 시 silent miss.
## 🧪 검증 / 중복
- Verified (TypeScript handbook — Narrowing chapter 2026).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — narrowing patterns + TS 5.5 inferred predicates + exhaustiveness |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-타파스-tapas
title: 타파스(Tapas)
category: 10_Wiki/Topics
status: duplicate
canonical_id: code-katas
duplicate_of: "[[Code Kata]]"
aliases: []
source_trust_level: A
confidence_score: 0.7
verification_status: redirected
tags: [duplicate, practice, kata]
last_reinforced: 2026-05-10
github_commit: pending
---
# 타파스(Tapas)
> **이 문서는 [[Code Kata]] 의 중복본입니다.** 원본 entry 의 context 가 명확하지 않으나, programming 영역에서 "Tapas" 는 Spanish 식 small-plate 비유로 codewars/Codecrafters 의 small bite-sized practice problems 를 지칭하는 경우가 가장 흔하므로 [[Code Kata]] canonical 로 redirect.
## 핵심 요약 (specialization aspects)
- "Tapas" 의 metaphor: 매 small portion 의 daily practice. 매 Code Kata 의 variant naming.
- 매 short (15-30 min) self-contained challenge 의 emphasize.
- Codecrafters, Exercism, Codewars 등의 platform 의 매 example.
## 🔗 Graph
- Adjacent: [[Deliberate Practice]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — Code Kata canonical 로 redirect (context ambiguous) |
@@ -0,0 +1,34 @@
---
id: wiki-2026-0508-프론트엔드-및-모노레포-monorepo-개발-환경-설정
title: 프론트엔드 및 모노레포(Monorepo) 개발 환경 설정
category: 10_Wiki/Topics
status: duplicate
canonical_id: monorepo-setup
duplicate_of: "[[Monorepo|Monorepo Setup]]"
aliases: [Frontend Monorepo, Monorepo Configuration]
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, monorepo, tooling, frontend]
last_reinforced: 2026-05-10
github_commit: pending
---
# 프론트엔드 및 모노레포(Monorepo) 개발 환경 설정
> **이 문서는 [[Monorepo|Monorepo Setup]] 의 중복본입니다.** Canonical 문서로 redirect.
## 핵심 요약
- Turborepo, Nx, pnpm workspaces, Bun workspaces — 2026 의 주류 tools.
- Shared packages, build caching, task orchestration.
- TypeScript project references 와 함께 사용.
## 🔗 Graph
- 부모: [[Monorepo|Monorepo Setup]] (canonical)
- 관련: [[Turborepo]] · [[Nx]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,33 @@
---
id: wiki-2026-0508-핀테크의-실시간-사기-탐지
title: 핀테크의 실시간 사기 탐지
category: 10_Wiki/Topics
status: duplicate
canonical_id: real-time-fraud-detection
duplicate_of: "[[Real-Time-Fraud-Detection]]"
aliases: []
source_trust_level: A
confidence_score: 0.9
verification_status: redirected
tags: [duplicate, fintech, fraud-detection, ml]
last_reinforced: 2026-05-10
github_commit: pending
---
# 핀테크의 실시간 사기 탐지
> **이 문서는 [[Real-Time-Fraud-Detection]] 의 중복본입니다.** Canonical 문서로 redirect.
## 매 핵심 요약
- 매 streaming feature pipeline (Kafka + Flink) → online ML inference.
- 매 graph-based anomaly + behavior fingerprint.
- 매 latency budget < 50 ms / decision.
## 🔗 Graph
- Adjacent: [[Anomaly-Detection]]
## 🕓 변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
@@ -0,0 +1,188 @@
---
id: wiki-2026-0508-할당-타임라인-allocation-timeline
title: 할당 타임라인 (Allocation Timeline)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Allocation Timeline, Memory Allocation Profiling, Heap Timeline]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [profiling, memory, devtools, performance, gc]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: javascript
framework: chrome-devtools
---
# 할당 타임라인 (Allocation Timeline)
## 매 한 줄
> **"매 heap 의 시간 축 의 graph"**. Allocation Timeline 은 Chrome DevTools (Memory panel) 의 sampling profiler tool 로, recording 동안 매 N ms 마다 JS heap 의 allocation 을 sample 하여 어떤 코드 line 이 어떤 timestamp 에 얼마만큼 의 memory 의 allocate 했는지 visualize. 매 memory leak 의 hunt, 매 high-frequency allocation hotspot 의 identification 의 매 first-line tool.
## 매 핵심
### 매 DevTools Memory panel 의 3 modes
1. **Heap snapshot**: 매 single point-in-time 의 full snapshot. 매 leak diagnosis (3-snapshot technique).
2. **Allocation instrumentation on timeline** (allocations on timeline): 매 stack trace 와 함께 매 allocation 의 capture. 매 expensive 한 most-detailed.
3. **Allocation sampling**: 매 lightweight, statistical. 매 production-like profile.
### 매 timeline 의 read 법
- X 축: time.
- Y 축: bar 의 height = allocation size.
- **Blue bar**: 매 still-alive allocation 의 record 종료 시점.
- **Gray bar**: 매 collected allocation. 매 GC 의 reclaimed.
- 매 blue 가 많이 남으면 → potential leak source.
### 매 응용
1. SPA 의 leak detection — page navigate 후 reachable obj 의 monitor.
2. React re-render allocation 의 hotspot 식별.
3. Worker / animation loop 의 per-frame allocation 의 minimize.
4. Stream parser 의 backpressure 검증.
## 💻 패턴
### Chrome DevTools — Allocation 기록
```text
1. Open DevTools → Memory tab.
2. Select "Allocation instrumentation on timeline".
3. Click ●(record), perform workflow, click ⏹.
4. Filter by Constructor / Size.
5. Expand stack trace — file:line 의 click → Sources panel.
```
### 3-snapshot leak diagnosis
```text
1. Snapshot 1 (baseline)
2. Trigger workflow N times (open modal, close, ...).
3. Force GC (trash icon).
4. Snapshot 2.
5. Repeat workflow N times again, force GC.
6. Snapshot 3.
7. Filter "Comparison" — objects allocated between Snap1 and Snap2 still alive at Snap3.
→ That's the leak.
```
### Programmatic — performance.measureUserAgentSpecificMemory()
```javascript
if ('measureUserAgentSpecificMemory' in performance) {
const result = await performance.measureUserAgentSpecificMemory()
console.log(result.bytes) // total bytes
console.log(result.breakdown) // per realm/type
}
```
### Node.js — heap profiling (built-in inspector)
```javascript
// node --inspect server.js
// Then in chrome://inspect → DevTools → Memory tab
// or programmatic
import { Session } from 'inspector'
const session = new Session()
session.connect()
session.post('HeapProfiler.startSampling')
// ... workload
session.post('HeapProfiler.stopSampling', (err, { profile }) => {
fs.writeFileSync('heap.heapprofile', JSON.stringify(profile))
})
```
### Detect React leak (common pattern)
```jsx
// LEAK — interval 의 closure 의 stale state 의 retain
useEffect(() => {
const id = setInterval(() => setCount(c => c + 1), 1000)
// missing cleanup
}, [])
// FIX
useEffect(() => {
const id = setInterval(() => setCount(c => c + 1), 1000)
return () => clearInterval(id)
}, [])
```
### High-frequency allocation reduction
```javascript
// BAD — every frame allocates
function tick() {
const v = { x: Math.random(), y: Math.random() } // allocation per frame
draw(v)
requestAnimationFrame(tick)
}
// GOOD — reuse buffer
const v = { x: 0, y: 0 }
function tick() {
v.x = Math.random()
v.y = Math.random()
draw(v)
requestAnimationFrame(tick)
}
```
### WeakMap/WeakRef — GC-friendly cache
```javascript
const cache = new WeakMap() // GC 의 reclaim 가능
function compute(obj) {
if (cache.has(obj)) return cache.get(obj)
const r = expensive(obj)
cache.set(obj, r)
return r
}
```
### FinalizationRegistry — leak detect in test
```javascript
const fr = new FinalizationRegistry(name => console.log(`${name} GC'd`))
function track(obj, name) {
fr.register(obj, name)
}
// in test: track(component, 'Modal'); unmount; await gc();
// expect Modal GC'd to log
```
## 매 결정 기준
| 상황 | Tool |
|---|---|
| Live SPA 의 leak suspect | DevTools Memory → Allocation timeline + 3 snapshots |
| Production-like overhead 필요 | Allocation sampling |
| Detached DOM hunt | Heap snapshot → "Detached" filter |
| Total memory size monitoring | `performance.measureUserAgentSpecificMemory()` |
| Node server | `--inspect` + Chrome DevTools, 또는 clinic.js |
| Animation hotspot | Allocation timeline (short window) |
**기본값**: Allocation instrumentation on timeline 의 short (10-30s) recording. 매 3-snapshot 의 leak suspect 시.
## 🔗 Graph
- 부모: [[Performance_Profiling_and_Memory|Performance Profiling]] · [[Memory Management]]
- 변형: [[Nodejs_and_Backend_Optimization|Heap Snapshot]]
- 응용: [[Memory Leak Detection]]
- Adjacent: [[Chrome DevTools Memory Profiling|Chrome DevTools]] · [[V8 Engine]]
## 🤖 LLM 활용
**언제**: User 가 "page slow over time" / "memory grows" / "browser crashes after 1h" 의 report 시. 매 Allocation timeline 의 first action.
**언제 X**: One-shot CPU bottleneck — 매 Performance panel (CPU profile) 의 prefer.
## ❌ 안티패턴
- **Snapshot 1개 만 보기**: leak 의 X-prove. 매 minimum 2-3 snapshots 의 compare.
- **GC 의 X-force**: snapshot 전 GC button 의 click 의 X-하면 매 noise 의 inflated.
- **Production minified code**: source map 의 X-load → stack trace 의 unreadable.
- **Long recording**: 100 MB+ 의 allocation timeline 의 DevTools 의 freeze.
- **Closures 의 ignore**: 매 detached DOM retainer 의 most-common 한 closure.
## 🧪 검증 / 중복
- Verified (Chrome DevTools docs 2026, V8 blog).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — DevTools allocation timeline, 3-snapshot leak hunt, Node profiling |