docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
---
|
||||
id: wiki-2026-0508-acl-prevention
|
||||
title: ACL Prevention
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-HEALTH-001, ACL Injury Prevention]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, devops, health, biomechanics]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: pandas
|
||||
---
|
||||
|
||||
# ACL Prevention
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 ACL 부상 prevention 의 핵심 = neuromuscular training + landing mechanics + proprioception."**. ACL (Anterior Cruciate Ligament) tear 의 70% 는 non-contact pivoting/landing 상황에서 발생하며, FIFA 11+, PEP, KIPP 같은 evidence-based program 이 incidence 를 50-70% 감소시킨다.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Risk Factor
|
||||
- **Modifiable**: knee valgus on landing, weak hip abductors, quad-dominant deceleration, fatigue.
|
||||
- **Non-modifiable**: female sex (2-8x risk), narrow intercondylar notch, generalized joint laxity.
|
||||
- **Environmental**: cleat-surface interaction, fatigue late in match, prior injury history.
|
||||
|
||||
### 매 Prevention Pillar
|
||||
- **Neuromuscular training** — plyometric + balance + strength, 2-3x/week.
|
||||
- **Landing mechanics** — soft landing, knee over toe, hip-dominant.
|
||||
- **Core/hip strength** — gluteus medius, hip external rotators.
|
||||
- **Proprioception** — single-leg balance, perturbation training.
|
||||
|
||||
### 매 응용
|
||||
1. Youth soccer FIFA 11+ warmup (15 min pre-training).
|
||||
2. Female collegiate athletes PEP program.
|
||||
3. Post-ACLR return-to-sport batteries.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Risk Score Aggregator
|
||||
```python
|
||||
import pandas as pd
|
||||
|
||||
def acl_risk_score(athlete: dict) -> float:
|
||||
"""0-1 risk; >0.6 → enroll in prevention program."""
|
||||
score = 0.0
|
||||
if athlete["sex"] == "F": score += 0.25
|
||||
if athlete["prior_acl"]: score += 0.30
|
||||
if athlete["knee_valgus_deg"] > 8: score += 0.20
|
||||
if athlete["hop_lsi"] < 0.85: score += 0.15 # limb symmetry
|
||||
if athlete["age"] < 18: score += 0.10
|
||||
return min(score, 1.0)
|
||||
```
|
||||
|
||||
### Drop Vertical Jump (DVJ) Analyzer
|
||||
```python
|
||||
import numpy as np
|
||||
|
||||
def knee_abduction_moment(forces, lever_arms):
|
||||
"""Hewett 2005 — KAM > 25.3 Nm predicts ACL injury."""
|
||||
return np.dot(forces, lever_arms)
|
||||
|
||||
def classify_landing(kam_nm: float) -> str:
|
||||
if kam_nm > 25.3: return "high-risk"
|
||||
if kam_nm > 15.0: return "moderate"
|
||||
return "low-risk"
|
||||
```
|
||||
|
||||
### FIFA 11+ Session Builder
|
||||
```python
|
||||
FIFA_11_PLUS = {
|
||||
"part1_running": ["straight ahead", "hip out", "hip in", "circling partner"],
|
||||
"part2_strength": ["bench", "sideways bench", "hamstrings", "single-leg stance"],
|
||||
"part3_running": ["across pitch", "bounding", "plant-and-cut"],
|
||||
}
|
||||
|
||||
def build_session(level: int = 1) -> list[str]:
|
||||
drills = []
|
||||
for part, items in FIFA_11_PLUS.items():
|
||||
drills.extend(items if level >= 2 else items[:2])
|
||||
return drills
|
||||
```
|
||||
|
||||
### Hop Test Battery
|
||||
```python
|
||||
def hop_lsi(injured: float, uninjured: float) -> float:
|
||||
"""Limb Symmetry Index — RTS threshold ≥ 0.90."""
|
||||
return injured / uninjured
|
||||
|
||||
def cleared_for_rts(single_hop, triple_hop, crossover) -> bool:
|
||||
return all(lsi >= 0.90 for lsi in (single_hop, triple_hop, crossover))
|
||||
```
|
||||
|
||||
### Cohort Tracking with Pandas
|
||||
```python
|
||||
import pandas as pd
|
||||
|
||||
def season_incidence(df: pd.DataFrame) -> pd.Series:
|
||||
"""ACL injuries per 1000 athlete-exposures."""
|
||||
return df.groupby("team")["acl_injury"].sum() / df.groupby("team")["ae"].sum() * 1000
|
||||
```
|
||||
|
||||
### Fatigue Monitor
|
||||
```python
|
||||
def fatigue_flag(rpe: int, srpe_load: int, acwr: float) -> bool:
|
||||
"""Acute:chronic workload ratio > 1.5 → injury risk spike."""
|
||||
return rpe >= 8 or acwr > 1.5
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Youth team, no history | FIFA 11+ |
|
||||
| Female collegiate | PEP / KIPP |
|
||||
| Post-ACLR | Criterion-based RTS battery |
|
||||
| Pro athlete in-season | Modified neuromuscular maintenance |
|
||||
|
||||
**기본값**: FIFA 11+ 2-3x/week.
|
||||
|
||||
## 🔗 Graph
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: structured risk-stratification, program selection, periodization advice.
|
||||
**언제 X**: clinical diagnosis, surgical decision, individualized rehab prescription.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Static stretching only**: 매 효과 없음. Dynamic warmup 필요.
|
||||
- **Knee-only focus**: hip/core ignore 시 valgus 재발.
|
||||
- **Volume without quality**: poor landing form 의 reps 는 risk 증가.
|
||||
- **Generic program**: sex/age/sport-specific tailoring 없으면 effect size 감소.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Hewett 2005, Sadoghi 2012 meta-analysis, FIFA 11+ RCT).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — full content with risk scoring + FIFA 11+ patterns |
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
id: wiki-2026-0508-adversarial-code-stylometry
|
||||
title: Adversarial Code Stylometry
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-36585B, Code Authorship Obfuscation]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, ml, privacy, deanonymization]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: scikit-learn
|
||||
---
|
||||
|
||||
# Adversarial Code Stylometry
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 source code 의 author 를 statistical fingerprint 로 식별 — 그리고 attacker 는 이를 회피한다."**. Code stylometry 는 AST features + n-grams + lexical patterns 로 author 를 95% accuracy 로 deanonymize 가능; adversarial stylometry 는 transformation/obfuscation 으로 이를 무력화한다.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Feature Family
|
||||
- **Lexical**: identifier length, naming convention, comment density.
|
||||
- **Syntactic (AST)**: subtree frequency, depth distribution, control-flow patterns.
|
||||
- **Layout**: indentation, brace style, line length.
|
||||
- **Semantic**: API choice, idiom preference (list comp vs loop).
|
||||
|
||||
### 매 Attack Surface
|
||||
- **Open-source contributors** — GitHub commits 의 deanonymization.
|
||||
- **Malware authorship** — APT attribution.
|
||||
- **Plagiarism detection** — academic/hiring context.
|
||||
- **Bug bounty / leak** — anonymous reporter identification.
|
||||
|
||||
### 매 Defense
|
||||
1. Code transformation (Caliskan 2018 — paraphrase preserving semantics).
|
||||
2. LLM-mediated rewrite (rewrite via Claude/GPT to neutralize style).
|
||||
3. Style transfer to another author (mimicry).
|
||||
4. Mechanical normalization (autoformatter + identifier randomization).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### AST Feature Extractor
|
||||
```python
|
||||
import ast
|
||||
from collections import Counter
|
||||
|
||||
def ast_node_freq(source: str) -> Counter:
|
||||
tree = ast.parse(source)
|
||||
return Counter(type(n).__name__ for n in ast.walk(tree))
|
||||
```
|
||||
|
||||
### Author Classifier (sklearn)
|
||||
```python
|
||||
from sklearn.ensemble import RandomForestClassifier
|
||||
from sklearn.feature_extraction.text import TfidfVectorizer
|
||||
from sklearn.pipeline import Pipeline
|
||||
|
||||
pipe = Pipeline([
|
||||
("tfidf", TfidfVectorizer(analyzer="char_wb", ngram_range=(2, 5))),
|
||||
("rf", RandomForestClassifier(n_estimators=300, n_jobs=-1)),
|
||||
])
|
||||
pipe.fit(train_sources, train_authors)
|
||||
```
|
||||
|
||||
### Style Obfuscation via Rewrite
|
||||
```python
|
||||
import anthropic
|
||||
|
||||
client = anthropic.Anthropic()
|
||||
|
||||
def neutralize_style(code: str) -> str:
|
||||
msg = client.messages.create(
|
||||
model="claude-opus-4-7",
|
||||
max_tokens=4096,
|
||||
messages=[{"role": "user", "content": f"""Rewrite this code to neutralize authorial style.
|
||||
Preserve semantics exactly. Use generic identifiers, standard idioms, mechanical formatting.
|
||||
|
||||
```python
|
||||
{code}
|
||||
```"""}],
|
||||
)
|
||||
return msg.content[0].text
|
||||
```
|
||||
|
||||
### Mimicry Attack (target style)
|
||||
```python
|
||||
def mimic(code: str, target_samples: list[str]) -> str:
|
||||
"""Rewrite `code` to look like `target_samples` author."""
|
||||
target_blob = "\n---\n".join(target_samples[:3])
|
||||
prompt = f"Target author samples:\n{target_blob}\n\nRewrite preserving semantics:\n{code}"
|
||||
return llm_call(prompt)
|
||||
```
|
||||
|
||||
### Detection of Obfuscated Code
|
||||
```python
|
||||
def obfuscation_signal(code: str) -> float:
|
||||
"""High score → likely autoformatted/normalized."""
|
||||
feats = ast_node_freq(code)
|
||||
entropy = -sum((c/sum(feats.values())) * np.log2(c/sum(feats.values())) for c in feats.values())
|
||||
return 1.0 - entropy / np.log2(len(feats)) # uniform → 0, peaked → 1
|
||||
```
|
||||
|
||||
### Defensive Pre-commit Hook
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# .git/hooks/pre-commit
|
||||
ruff format --quiet .
|
||||
python -m style_neutralizer **/*.py
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Anonymous OSS contribution | LLM rewrite + autoformat |
|
||||
| Whistleblower | Full mimicry to public author |
|
||||
| Defensive (detection) | Char n-gram + AST RF |
|
||||
| Research baseline | Caliskan 2015 features |
|
||||
|
||||
**기본값**: autoformat + LLM neutralization for adversarial; char n-gram TF-IDF + RF for detection.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[Code Obfuscation]]
|
||||
- Adjacent: [[Differential Privacy]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: style neutralization, mimicry attack, defensive paraphrase.
|
||||
**언제 X**: ground-truth authorship verification 에 LLM judgment 단독 사용.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Autoformatter 만 의존**: AST/lexical features 는 그대로 leak.
|
||||
- **Identifier rename only**: control-flow signature 가 식별 가능.
|
||||
- **Single-pass LLM rewrite**: subtle idioms 잔존 — multi-pass 필요.
|
||||
- **Train/test 동일 repo**: leakage — author-disjoint split 필수.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Caliskan 2015 USENIX Sec, Abuhamad 2018 CCS).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — AST features, attack/defense patterns |
|
||||
@@ -0,0 +1,137 @@
|
||||
---
|
||||
id: wiki-2026-0508-alternative-realities
|
||||
title: Alternative Realities
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [XR, Mixed Reality, MR/AR/VR Spectrum]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [xr, vr, ar, mr, immersive]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: TypeScript
|
||||
framework: WebXR/Three.js/Unity
|
||||
---
|
||||
|
||||
# Alternative Realities
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 reality 는 spectrum 위 한 점이다."**. Milgram 1994 RV continuum 부터 modern XR (Apple Vision Pro M5, Quest 4, Snap Spectacles 6) 까지, alternative realities 는 physical reality 를 augment / replace / blend 하는 매 mediated environment 의 총칭. 2026 의 mainstream 은 passthrough MR + hand tracking + neural input.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Reality-Virtuality Continuum
|
||||
- **VR (Virtual Reality)**: 매 100% synthetic — Quest 4, Vision Pro fully-immersive mode.
|
||||
- **AR (Augmented Reality)**: 매 real + overlay — phone AR, Snap Spectacles, HoloLens.
|
||||
- **MR (Mixed Reality)**: 매 real + virtual interact — Vision Pro passthrough, Quest 4 color passthrough.
|
||||
- **XR (Extended Reality)**: 매 umbrella term — VR/AR/MR all-inclusive.
|
||||
|
||||
### 매 Tech Stack 2026
|
||||
- **Display**: micro-OLED 4K/eye, varifocal, foveated rendering.
|
||||
- **Tracking**: inside-out 6DoF, eye tracking, hand tracking 26-joint, body pose.
|
||||
- **Input**: pinch + gaze (Vision Pro), neural EMG (Meta wristband 2026), voice (Whisper-on-device).
|
||||
- **Compute**: Apple M5/Snapdragon XR3 — 매 on-device transformer inference.
|
||||
|
||||
### 매 응용
|
||||
1. **Productivity**: Vision Pro virtual displays, Immersed VR coding.
|
||||
2. **Training**: surgical sim, military, industrial maintenance.
|
||||
3. **Therapy**: VR exposure (PTSD, phobia), pain distraction.
|
||||
4. **Social**: Horizon Worlds, VRChat, Rec Room.
|
||||
5. **Industrial Twin**: AR overlay on factory equipment.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### WebXR session bootstrap
|
||||
```typescript
|
||||
// Modern WebXR (2026) — immersive-ar with hand tracking
|
||||
const xr = navigator.xr;
|
||||
if (await xr.isSessionSupported('immersive-ar')) {
|
||||
const session = await xr.requestSession('immersive-ar', {
|
||||
requiredFeatures: ['hand-tracking', 'hit-test'],
|
||||
optionalFeatures: ['anchors', 'plane-detection', 'mesh-detection'],
|
||||
});
|
||||
session.addEventListener('end', cleanup);
|
||||
await renderer.xr.setSession(session);
|
||||
}
|
||||
```
|
||||
|
||||
### Hand-tracking pinch gesture
|
||||
```typescript
|
||||
function onXRFrame(time: number, frame: XRFrame) {
|
||||
const refSpace = renderer.xr.getReferenceSpace();
|
||||
for (const inputSource of frame.session.inputSources) {
|
||||
if (!inputSource.hand) continue;
|
||||
const thumb = frame.getJointPose(inputSource.hand.get('thumb-tip'), refSpace);
|
||||
const index = frame.getJointPose(inputSource.hand.get('index-finger-tip'), refSpace);
|
||||
const dist = vec3.distance(thumb.transform.position, index.transform.position);
|
||||
if (dist < 0.02) emit('pinch', inputSource.handedness);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Passthrough + virtual content (Three.js)
|
||||
```typescript
|
||||
renderer.xr.enabled = true;
|
||||
renderer.setClearAlpha(0); // 매 transparent — passthrough shows through
|
||||
scene.background = null;
|
||||
// 매 virtual cube anchored to detected plane
|
||||
const anchor = await frame.createAnchor(planePose.transform, refSpace);
|
||||
scene.add(makeCubeAtAnchor(anchor));
|
||||
```
|
||||
|
||||
### Foveated rendering hint
|
||||
```typescript
|
||||
const layer = xr.glLayer;
|
||||
layer.fixedFoveation = 0.7; // 매 0=off, 1=max — 매 30% GPU savings
|
||||
```
|
||||
|
||||
### Eye-tracked gaze input
|
||||
```typescript
|
||||
session.requestReferenceSpace('viewer').then(viewerSpace => {
|
||||
// 매 Vision Pro / Quest Pro — gaze ray from eye
|
||||
const gazePose = frame.getPose(viewerSpace, refSpace);
|
||||
raycaster.set(gazePose.transform.position, gazeDirection);
|
||||
});
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Web 배포 | WebXR + Three.js |
|
||||
| Native iOS | RealityKit + ARKit |
|
||||
| Native Android | ARCore + Sceneform/Filament |
|
||||
| Cross-platform native | Unity XR / Unreal |
|
||||
| Enterprise 산업 | Vision Pro / HoloLens 2 |
|
||||
|
||||
**기본값**: 매 WebXR 시도 → 부족시 native.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[VR 엑서게임 (VR Exergaming)]] · [[HMD(Head-Mounted Display) 기반 엑서게임 환경]]
|
||||
- 변형: [[Digital Twins]] · [[Digital Twins|Digital-Twin-Technology]]
|
||||
- 응용: [[Beat Saber 엑서게임 연구(Beat Saber Exergaming Study)]] · [[Remote-Rehabilitation]]
|
||||
- Adjacent: [[Visual-Effects-VFX]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: XR scene authoring, gesture pattern matching, accessibility caption generation.
|
||||
**언제 X**: 매 real-time inner loop (latency budget 11ms) 에서 cloud LLM 호출.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **VR 멀미 무시**: 매 locomotion = teleport/snap-turn 권장. Smooth locomotion 은 매 opt-in.
|
||||
- **60fps 미만**: 매 90fps 미만 = motion sickness. 매 budget 11ms.
|
||||
- **Untracked controllers**: 매 always handle controller-lost 이벤트.
|
||||
- **Single-eye render**: 매 stereo render 필수 — single-eye 는 depth 깨짐.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: Milgram & Kishino 1994; W3C WebXR Device API 2024; Apple visionOS 3 docs.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — XR continuum + 2026 stack + WebXR patterns |
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
id: wiki-2026-0508-analyze-runtime-performance
|
||||
title: Analyze runtime performance
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Performance Analysis, Profiling, Runtime Profiling]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [profiling, performance, devtools]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: JavaScript/Python
|
||||
framework: Chrome DevTools/perf/py-spy
|
||||
---
|
||||
|
||||
# Analyze runtime performance
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 측정 없이 최적화 없다."**. Runtime performance 분석은 sampling profiler + tracing + flame graph + RAIL/Web Vitals metrics 의 stack 으로 매 hot path 와 long task 를 식별. 2026 stack: Chrome Performance panel (Insights AI), perf+FlameGraph, py-spy, eBPF/bpftrace, Datadog APM.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Profiler Type
|
||||
- **Sampling**: 매 N ms 마다 stack 캡처 — 매 low overhead, statistical (perf, py-spy, async-profiler).
|
||||
- **Instrumentation**: 매 fn enter/exit 기록 — 매 accurate, high overhead.
|
||||
- **Tracing**: 매 event timeline (Chrome trace, perfetto).
|
||||
- **Hardware counters**: PMU — IPC, cache miss, branch miss.
|
||||
|
||||
### 매 RAIL Model (web)
|
||||
- **Response**: < 100ms input → feedback.
|
||||
- **Animation**: < 16ms / frame (60fps).
|
||||
- **Idle**: 50ms work blocks max.
|
||||
- **Load**: < 5s on 4G.
|
||||
|
||||
### 매 Core Web Vitals 2026
|
||||
- **LCP** (Largest Contentful Paint) < 2.5s.
|
||||
- **INP** (Interaction to Next Paint) < 200ms — 매 FID 대체 (2024+).
|
||||
- **CLS** (Cumulative Layout Shift) < 0.1.
|
||||
|
||||
### 매 응용
|
||||
1. Web app TTI/INP 개선.
|
||||
2. Backend p99 latency 추적.
|
||||
3. Game/XR frame budget.
|
||||
4. ML inference latency.
|
||||
5. CI pipeline 시간 단축.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Chrome Performance panel + AI insights
|
||||
```javascript
|
||||
// 매 manual marker — show up in Performance timeline
|
||||
performance.mark('ai-search:start');
|
||||
const r = await search(q);
|
||||
performance.mark('ai-search:end');
|
||||
performance.measure('ai-search', 'ai-search:start', 'ai-search:end');
|
||||
// 매 record trace in DevTools → AI Insights highlights bottleneck (2025+)
|
||||
```
|
||||
|
||||
### User Timing API + reporter
|
||||
```javascript
|
||||
const obs = new PerformanceObserver(list => {
|
||||
list.getEntries().forEach(e => analytics('perf', { name: e.name, dur: e.duration }));
|
||||
});
|
||||
obs.observe({ entryTypes: ['measure', 'navigation', 'resource', 'longtask'] });
|
||||
```
|
||||
|
||||
### py-spy live flame graph
|
||||
```bash
|
||||
# 매 attach to running PID, no code change
|
||||
py-spy record -o flame.svg --pid 12345 --duration 30
|
||||
# 매 live top-like
|
||||
py-spy top --pid 12345
|
||||
```
|
||||
|
||||
### Linux perf flame graph
|
||||
```bash
|
||||
sudo perf record -F 99 -g -p $PID -- sleep 30
|
||||
sudo perf script | \
|
||||
./stackcollapse-perf.pl | ./flamegraph.pl > flame.svg
|
||||
```
|
||||
|
||||
### Web Vitals INP measurement
|
||||
```javascript
|
||||
import { onINP, onLCP, onCLS } from 'web-vitals';
|
||||
onINP(m => beacon('inp', m.value, m.id));
|
||||
onLCP(m => beacon('lcp', m.value, m.id));
|
||||
onCLS(m => beacon('cls', m.value, m.id));
|
||||
```
|
||||
|
||||
### Node --prof + --prof-process
|
||||
```bash
|
||||
node --prof server.js
|
||||
# 매 after run
|
||||
node --prof-process isolate-*.log > profile.txt
|
||||
```
|
||||
|
||||
### eBPF (bpftrace) syscall latency
|
||||
```bash
|
||||
sudo bpftrace -e '
|
||||
tracepoint:syscalls:sys_enter_read { @s[tid] = nsecs; }
|
||||
tracepoint:syscalls:sys_exit_read /@s[tid]/ {
|
||||
@us = hist((nsecs - @s[tid]) / 1000);
|
||||
delete(@s[tid]);
|
||||
}'
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| Web (Chromium) | DevTools Performance + Web Vitals |
|
||||
| Node.js | clinic.js / 0x / --prof |
|
||||
| Python | py-spy / scalene / cProfile |
|
||||
| JVM | async-profiler / JFR |
|
||||
| Go | pprof |
|
||||
| Linux native | perf + FlameGraph / eBPF |
|
||||
| Production APM | Datadog / NewRelic / OTel |
|
||||
|
||||
**기본값**: 매 sampling profiler 우선, instrumentation 은 spot-check.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Flame_Graphs]]
|
||||
- 변형: [[CPU Bottleneck]]
|
||||
- 응용: [[High Resolution Time]] · [[Memory Management]]
|
||||
- Adjacent: [[Page Experience Algorithm]] · [[Debugger_Techniques]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: flame graph 해석, perf insight 요약, regression hypothesis.
|
||||
**언제 X**: 매 nanosecond-level profiling — specialized tool 만이 정확.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Production 에 instrumenting profiler**: 매 overhead 폭발.
|
||||
- **Single-run 결론**: 매 statistical noise — multi-run 필요.
|
||||
- **Average only**: 매 p50 보다 p99 가 user 체감.
|
||||
- **Profile dev build**: 매 prod build 와 다름 — release/optimized 측정.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: web.dev Performance docs; Brendan Gregg "Systems Performance"; Chrome DevTools docs.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — RAIL/INP + multi-language profilers |
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
id: wiki-2026-0508-anomaly-detection
|
||||
title: Anomaly Detection
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Outlier Detection, Novelty Detection, 이상 탐지]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, ml, monitoring, observability]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: Python
|
||||
framework: scikit-learn/PyOD/Prometheus
|
||||
---
|
||||
|
||||
# Anomaly Detection
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 normal 의 boundary 를 학습하고 그 밖을 flag 한다."**. Anomaly detection 은 fraud, intrusion, equipment failure, log spike 등을 unsupervised 로 발견하는 매 core observability/security primitive. 2026 의 standard 는 Isolation Forest + LSTM-AE + transformer-based time-series (PatchTST, TimesNet).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Anomaly Type 3가지
|
||||
- **Point anomaly**: 매 single observation 이 outlier — credit card 단일 거래.
|
||||
- **Contextual anomaly**: 매 context 에서만 anomaly — 여름의 영하 온도.
|
||||
- **Collective anomaly**: 매 group 으로만 anomaly — DDoS 의 packet sequence.
|
||||
|
||||
### 매 Algorithm Family
|
||||
- **Statistical**: z-score, MAD, Grubbs, EWMA — 매 univariate baseline.
|
||||
- **Distance-based**: kNN, LOF — 매 density 차이로 detect.
|
||||
- **Tree-based**: Isolation Forest, Extended IF — 매 high-dim 잘 작동.
|
||||
- **Reconstruction**: Autoencoder, VAE — 매 reconstruction error = anomaly score.
|
||||
- **Time-series DL**: LSTM-AE, Transformer (PatchTST 2024, TimesNet) — 매 SOTA 2026.
|
||||
- **One-class**: One-Class SVM, Deep SVDD — 매 normal-only training.
|
||||
|
||||
### 매 응용
|
||||
1. **Fraud detection**: payment, account takeover.
|
||||
2. **Intrusion detection (IDS)**: network traffic anomaly.
|
||||
3. **Predictive maintenance**: vibration sensor, temp.
|
||||
4. **APM**: latency/error rate spike — Datadog Watchdog, New Relic.
|
||||
5. **Log anomaly**: unseen log template — DeepLog, LogBERT.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Isolation Forest baseline
|
||||
```python
|
||||
from sklearn.ensemble import IsolationForest
|
||||
import numpy as np
|
||||
|
||||
# 매 contamination = expected anomaly fraction
|
||||
clf = IsolationForest(contamination=0.01, n_estimators=200, random_state=42)
|
||||
clf.fit(X_train)
|
||||
scores = -clf.score_samples(X_test) # 매 high score = more anomalous
|
||||
preds = clf.predict(X_test) # -1=anomaly, 1=normal
|
||||
```
|
||||
|
||||
### LOF for density anomaly
|
||||
```python
|
||||
from sklearn.neighbors import LocalOutlierFactor
|
||||
lof = LocalOutlierFactor(n_neighbors=20, contamination=0.01, novelty=True)
|
||||
lof.fit(X_train)
|
||||
anomaly_score = -lof.score_samples(X_test)
|
||||
```
|
||||
|
||||
### Autoencoder reconstruction error (PyTorch)
|
||||
```python
|
||||
import torch.nn as nn
|
||||
class AE(nn.Module):
|
||||
def __init__(self, d=64):
|
||||
super().__init__()
|
||||
self.enc = nn.Sequential(nn.Linear(d,32), nn.ReLU(), nn.Linear(32,8))
|
||||
self.dec = nn.Sequential(nn.Linear(8,32), nn.ReLU(), nn.Linear(32,d))
|
||||
def forward(self, x): return self.dec(self.enc(x))
|
||||
|
||||
# 매 train on normal only — anomaly = high reconstruction error
|
||||
recon = model(x)
|
||||
score = ((x - recon) ** 2).mean(dim=1)
|
||||
```
|
||||
|
||||
### EWMA streaming detector
|
||||
```python
|
||||
class EWMA:
|
||||
def __init__(self, alpha=0.1, k=3.0):
|
||||
self.alpha, self.k = alpha, k
|
||||
self.mu = self.var = None
|
||||
def step(self, x):
|
||||
if self.mu is None: self.mu, self.var = x, 1.0; return False
|
||||
z = abs(x - self.mu) / (self.var ** 0.5 + 1e-9)
|
||||
self.mu = self.alpha * x + (1 - self.alpha) * self.mu
|
||||
self.var = self.alpha * (x - self.mu)**2 + (1 - self.alpha) * self.var
|
||||
return z > self.k
|
||||
```
|
||||
|
||||
### PyOD ensemble
|
||||
```python
|
||||
from pyod.models.iforest import IForest
|
||||
from pyod.models.lof import LOF
|
||||
from pyod.models.combination import average
|
||||
|
||||
scores = np.column_stack([
|
||||
IForest().fit(X).decision_function(X),
|
||||
LOF().fit(X).decision_function(X),
|
||||
])
|
||||
ensemble_score = average(scores)
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Algorithm |
|
||||
|---|---|
|
||||
| Tabular, low-dim | Isolation Forest |
|
||||
| Tabular, density 중요 | LOF |
|
||||
| Time-series univariate | EWMA / Prophet |
|
||||
| Time-series multivariate | LSTM-AE / PatchTST |
|
||||
| Image | PaDiM / PatchCore |
|
||||
| Log sequence | LogBERT / DeepLog |
|
||||
|
||||
**기본값**: 매 Isolation Forest baseline → 부족시 deep model.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Statistics & Data Analysis]]
|
||||
- 변형: [[Inferential-Statistics]]
|
||||
- 응용: [[Malware-Analysis]] · [[Deepfake-Detection]] · [[Logging_and_Error_Handling]]
|
||||
- Adjacent: [[경고 피로 (Alert Fatigue)]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: log template 추출, anomaly explanation generation, false-positive triage.
|
||||
**언제 X**: 매 high-frequency stream 의 inner-loop scoring (use specialized model).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Threshold hard-coding**: 매 environment drift 시 무용지물 — adaptive threshold 사용.
|
||||
- **Class imbalance 무시**: 매 anomaly 0.1% 일 때 accuracy 99.9% 무의미 — PR-AUC.
|
||||
- **Train on contaminated data**: 매 anomaly 가 train set 에 섞이면 mask 됨.
|
||||
- **Alert fatigue**: 매 raw score 그대로 alert 면 dev 가 무시.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: Liu et al. 2008 (Isolation Forest); PyOD docs; Nie et al. 2023 (PatchTST).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — algorithm taxonomy + PyOD/AE patterns |
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
id: wiki-2026-0508-automated-quality-review
|
||||
title: "Automated Quality & Review"
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Automated Code Review, AI Code Review, CR Automation]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [code-review, ci, devops, llm]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: TypeScript/Python
|
||||
framework: GitHub Actions/Claude Code/Copilot
|
||||
---
|
||||
|
||||
# Automated Quality & Review
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 PR 의 first reviewer 는 machine 이다."**. Automated Quality & Review 는 lint, type-check, test, SAST, AI review 를 PR pipeline 에 stack 하여 human reviewer 가 매 substance 만 보게 하는 매 modern engineering practice. 2026 의 stack: Biome + tsc + Vitest + Semgrep + Claude/Copilot review bot.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Quality Gate Layer
|
||||
1. **Format**: Biome / Prettier — 매 zero-arg.
|
||||
2. **Lint**: Biome / ESLint / Ruff — 매 style + likely-bug rules.
|
||||
3. **Type**: tsc / mypy / pyright — 매 static contract.
|
||||
4. **Test**: Vitest / Jest / pytest — 매 unit + integration.
|
||||
5. **Coverage**: c8 / coverage.py — 매 80%+ delta enforced.
|
||||
6. **SAST**: Semgrep / CodeQL — 매 security pattern.
|
||||
7. **AI review**: Claude Code, Copilot Workspace, Cursor — 매 semantic.
|
||||
8. **Mutation**: Stryker — 매 test quality 검증 (optional).
|
||||
|
||||
### 매 AI Review 2026 Capability
|
||||
- **Logic bug detection**: Claude Opus 4.7 finds nil-deref, race, off-by-one.
|
||||
- **Convention enforcement**: 매 codebase context 학습 후 style 위반 flag.
|
||||
- **Security**: SQLi, XSS, IDOR, deserialization 의 dataflow 추적.
|
||||
- **Performance**: N+1 query, O(n²) loop, unbounded recursion.
|
||||
- **Test gap**: 매 코드 변경 vs test coverage delta 분석.
|
||||
|
||||
### 매 응용
|
||||
1. PR comment bot — 매 inline suggestions.
|
||||
2. Pre-merge gate — 매 critical issue block.
|
||||
3. Refactor suggester — 매 nightly batch.
|
||||
4. Onboarding — 매 junior dev 의 mentor.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### GitHub Actions quality pipeline
|
||||
```yaml
|
||||
name: pr-quality
|
||||
on: pull_request
|
||||
jobs:
|
||||
quality:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
- run: bun install --frozen-lockfile
|
||||
- run: bun run biome check .
|
||||
- run: bun run tsc --noEmit
|
||||
- run: bun run vitest run --coverage
|
||||
- uses: returntocorp/semgrep-action@v1
|
||||
with: { config: 'p/owasp-top-ten' }
|
||||
- uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
mode: review
|
||||
model: claude-opus-4-7
|
||||
```
|
||||
|
||||
### Claude Code review prompt
|
||||
```markdown
|
||||
You are reviewing PR #{number}. Focus on:
|
||||
1. Logic bugs (off-by-one, null deref, race conditions)
|
||||
2. Security (OWASP Top 10)
|
||||
3. Performance (N+1, unbounded loops)
|
||||
4. Test coverage for changed lines
|
||||
|
||||
Output format: file:line — severity — description.
|
||||
Skip: style nits (handled by Biome).
|
||||
```
|
||||
|
||||
### Reviewdog inline comment
|
||||
```yaml
|
||||
- run: bun run biome check --reporter=github . | reviewdog -f=github-check -reporter=github-pr-review
|
||||
```
|
||||
|
||||
### Coverage delta gate
|
||||
```yaml
|
||||
- uses: ArtiomTr/jest-coverage-report-action@v2
|
||||
with:
|
||||
threshold: '{"lines":80,"branches":75}'
|
||||
annotations: failed-tests
|
||||
```
|
||||
|
||||
### Semgrep custom rule
|
||||
```yaml
|
||||
rules:
|
||||
- id: hardcoded-secret
|
||||
pattern-either:
|
||||
- pattern: const $K = "$VAL"
|
||||
metavariable-regex:
|
||||
$K: '(?i)(api[_-]?key|secret|token|password)'
|
||||
message: Hardcoded secret detected
|
||||
severity: ERROR
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| TS/JS format+lint | Biome (single tool) |
|
||||
| Python format+lint | Ruff |
|
||||
| Type check | tsc strict / pyright strict |
|
||||
| Security SAST | Semgrep + CodeQL |
|
||||
| AI review | Claude Code Action |
|
||||
| PR comment UX | reviewdog |
|
||||
|
||||
**기본값**: 매 Biome + tsc + Vitest + Semgrep + Claude review.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[CI_CD_Pipeline]]
|
||||
- 변형: [[수동 코드 리뷰]] · [[자동화된 코드 리뷰]]
|
||||
- 응용: [[SAST]] · [[Husky]] · [[lint-staged]]
|
||||
- Adjacent: [[Engineering Metrics (DORA)]] · [[Test_Automation]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: PR review, refactor suggestion, test gap detection, commit message generation.
|
||||
**언제 X**: 매 deterministic check (lint, type) — specialized tool 이 빠르고 정확.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **AI-only review**: 매 human approval 없이 merge 허용 — accountability 사라짐.
|
||||
- **Slow pipeline**: 매 30분 PR check 면 dev 가 우회. 5분 budget.
|
||||
- **Style nit storm**: 매 AI 가 nit 만 쏟으면 중요한 logic bug 가 묻힘.
|
||||
- **No fail-fast**: 매 lint fail 후에도 test 실행 — 매 sequential gate.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: GitHub Actions docs; Anthropic Claude Code docs; Semgrep playbook 2024.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — quality gate layers + Claude Code action |
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
id: wiki-2026-0508-bluf-bottom-line-up-front
|
||||
title: BLUF (Bottom Line Up Front)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [a1b2c3d4-e5f6-4901-2e3f-4a5b6c7d8e9f, Bottom Line Up Front]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 1.0
|
||||
verification_status: applied
|
||||
tags: [communication, writing, devops, incident-response]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: markdown
|
||||
framework: none
|
||||
---
|
||||
|
||||
# BLUF (Bottom Line Up Front)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 conclusion 을 첫 줄에 — recipient 가 더 못 읽어도 OK 하도록."**. US military origin 의 writing convention; 매 incident report, exec memo, PR description, on-call alert 의 표준 — 매 reader 의 cognitive load 를 minimize 하고 fastest decision-making 을 enable.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Structure
|
||||
- **Line 1**: the conclusion / decision needed / status verdict.
|
||||
- **Line 2-N**: supporting evidence in priority order.
|
||||
- **Tail**: details, appendices, traces.
|
||||
|
||||
### 매 vs Narrative
|
||||
- Narrative: "We started X, encountered Y, debugged Z, found root cause W, fixed it." — reader waits for punchline.
|
||||
- BLUF: "Outage resolved. Root cause: misconfigured DNS. Restored 14:23 UTC." — punchline first.
|
||||
|
||||
### 매 응용
|
||||
1. Incident postmortem TL;DR.
|
||||
2. PR description first sentence.
|
||||
3. Slack on-call escalation.
|
||||
4. Email subject + first line.
|
||||
5. Architecture decision record (ADR) summary.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Incident Slack Alert
|
||||
```markdown
|
||||
**[P1] Checkout API 5xx — DEGRADED**
|
||||
Impact: 12% of orders failing since 14:05 UTC.
|
||||
Action: rollback v2.4.1 in progress, ETA 5 min.
|
||||
Owner: @oncall-payments
|
||||
Thread: ↓
|
||||
```
|
||||
|
||||
### Postmortem Top
|
||||
```markdown
|
||||
# Postmortem: 2026-05-08 Checkout Outage
|
||||
|
||||
**TL;DR**: 47-min P1 outage due to DNS TTL misconfig in v2.4.1 deploy.
|
||||
- Customer impact: ~3,200 failed orders (~$84k revenue)
|
||||
- Resolution: rollback at 14:23 UTC
|
||||
- Action items: 4 (see §6)
|
||||
|
||||
## Timeline
|
||||
...
|
||||
```
|
||||
|
||||
### PR Description
|
||||
```markdown
|
||||
**Adds rate limiting to /api/checkout to prevent abuse.**
|
||||
|
||||
- New: `RateLimiter` middleware with Redis token bucket
|
||||
- Default: 60 req/min per IP, configurable via env
|
||||
- Tests: integration coverage for 429 path
|
||||
- Risk: low — feature-flagged behind `RATE_LIMIT_ENABLED`
|
||||
|
||||
## Why
|
||||
Spike on 05-06 saturated DB connections...
|
||||
```
|
||||
|
||||
### Email Template
|
||||
```markdown
|
||||
Subject: [DECISION NEEDED by Fri] Migrate auth to OIDC — recommend Keycloak
|
||||
|
||||
Recommendation: adopt Keycloak for SSO; deprecate legacy LDAP by Q3.
|
||||
Cost: $0 (OSS) + 2 SRE-weeks integration.
|
||||
Risk: medium (auth migration); mitigated by phased rollout.
|
||||
|
||||
Background: ...
|
||||
```
|
||||
|
||||
### ADR Header
|
||||
```markdown
|
||||
# ADR-0042: Use SQLite for local dev DB
|
||||
|
||||
**Decision**: SQLite for local; Postgres for staging/prod.
|
||||
**Status**: accepted (2026-05-10)
|
||||
**Context**: ... (3 paragraphs below)
|
||||
```
|
||||
|
||||
### On-Call Status Page
|
||||
```markdown
|
||||
🟢 **All systems operational** — last incident 9 days ago.
|
||||
Recent: deploys 4 (all green) · alerts 0 · SLO budget 99.4%
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | BLUF 적용 |
|
||||
|---|---|
|
||||
| Incident alert | YES — line 1 = severity + impact |
|
||||
| Postmortem | YES — TL;DR block before timeline |
|
||||
| Tutorial / explainer | NO — narrative 적합 |
|
||||
| Marketing copy | NO — hook 후 reveal |
|
||||
| ADR | YES — decision first |
|
||||
| Bug report | YES — observed vs expected first |
|
||||
|
||||
**기본값**: ops/exec communication 은 BLUF; pedagogical/narrative 은 example-first.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Technical Writing]]
|
||||
- 응용: [[Postmortem]] · [[ADR]]
|
||||
- Adjacent: [[Pyramid Principle]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: ask LLM to "rewrite as BLUF" — high-quality reflow.
|
||||
**언제 X**: storytelling / customer-facing narrative.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Buried lede**: conclusion 을 §3 에 묻기.
|
||||
- **Over-summarize**: line 1 이 vague ("there was an issue").
|
||||
- **No context for novices**: BLUF 는 expert reader 가정 — onboarding doc 에는 부적합.
|
||||
- **Decision-less BLUF**: "We did X" 보다 "Recommend Y" 가 actionable.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (US Army Field Manual, Google SRE Book postmortem chapter).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — full content with templates for incidents/PRs/ADRs |
|
||||
@@ -0,0 +1,164 @@
|
||||
---
|
||||
id: wiki-2026-0508-bvh
|
||||
title: BVH
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-D211FC, Bounding Volume Hierarchy]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [graphics, raytracing, datastructure, performance]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: rust
|
||||
framework: none
|
||||
---
|
||||
|
||||
# BVH
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 ray-object intersection 의 O(N) → O(log N) 변환의 표준 자료구조."**. Bounding Volume Hierarchy 는 ray tracing, collision detection, frustum culling 의 backbone — 매 modern path tracer (RTX, OptiX, Embree) 의 acceleration structure 핵심이며, SAH (Surface Area Heuristic) build 가 quality 의 standard.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Build Strategy
|
||||
- **Median split**: simple, fast build, mediocre traversal.
|
||||
- **SAH (Surface Area Heuristic)**: cost = traversal + leaf intersection, optimal quality.
|
||||
- **HLBVH / LBVH**: GPU-friendly Morton-code build.
|
||||
- **PLOC**: parallel locally-ordered clustering, modern GPU SOTA.
|
||||
|
||||
### 매 Traversal
|
||||
- Stack-based DFS (CPU).
|
||||
- Stackless / restart trail (GPU register-friendly).
|
||||
- Wide BVH (BVH4, BVH8) — SIMD-friendly child arrays.
|
||||
|
||||
### 매 응용
|
||||
1. Path tracing (Embree, OptiX, RTX hardware BVH).
|
||||
2. Physics broadphase (Bullet, PhysX).
|
||||
3. Three.js raycast acceleration (three-mesh-bvh).
|
||||
4. WebGPU ray queries.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### AABB Struct
|
||||
```rust
|
||||
#[derive(Copy, Clone)]
|
||||
struct Aabb { min: [f32; 3], max: [f32; 3] }
|
||||
|
||||
impl Aabb {
|
||||
fn surface_area(&self) -> f32 {
|
||||
let d = [self.max[0]-self.min[0], self.max[1]-self.min[1], self.max[2]-self.min[2]];
|
||||
2.0 * (d[0]*d[1] + d[1]*d[2] + d[2]*d[0])
|
||||
}
|
||||
fn union(a: Aabb, b: Aabb) -> Aabb {
|
||||
Aabb {
|
||||
min: [a.min[0].min(b.min[0]), a.min[1].min(b.min[1]), a.min[2].min(b.min[2])],
|
||||
max: [a.max[0].max(b.max[0]), a.max[1].max(b.max[1]), a.max[2].max(b.max[2])],
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Slab Ray-AABB Test
|
||||
```rust
|
||||
fn ray_aabb(o: [f32;3], inv_d: [f32;3], box_: &Aabb) -> Option<f32> {
|
||||
let mut tmin = 0.0_f32;
|
||||
let mut tmax = f32::INFINITY;
|
||||
for i in 0..3 {
|
||||
let t1 = (box_.min[i] - o[i]) * inv_d[i];
|
||||
let t2 = (box_.max[i] - o[i]) * inv_d[i];
|
||||
tmin = tmin.max(t1.min(t2));
|
||||
tmax = tmax.min(t1.max(t2));
|
||||
}
|
||||
if tmax >= tmin.max(0.0) { Some(tmin) } else { None }
|
||||
}
|
||||
```
|
||||
|
||||
### SAH Cost
|
||||
```rust
|
||||
fn sah_cost(left: &Aabb, n_left: usize, right: &Aabb, n_right: usize, parent: &Aabb) -> f32 {
|
||||
const C_TRAV: f32 = 1.0;
|
||||
const C_ISECT: f32 = 1.5;
|
||||
let inv_pa = 1.0 / parent.surface_area();
|
||||
C_TRAV + C_ISECT * (left.surface_area() * n_left as f32 + right.surface_area() * n_right as f32) * inv_pa
|
||||
}
|
||||
```
|
||||
|
||||
### Top-Down SAH Build (sketch)
|
||||
```rust
|
||||
fn build(prims: &mut [Prim]) -> Box<Node> {
|
||||
if prims.len() <= 4 { return Box::new(Node::Leaf(prims.to_vec())); }
|
||||
let (axis, split, _cost) = best_sah_split(prims);
|
||||
prims.select_nth_unstable_by(split, |a, b| a.centroid[axis].partial_cmp(&b.centroid[axis]).unwrap());
|
||||
let (l, r) = prims.split_at_mut(split);
|
||||
Box::new(Node::Internal(build(l), build(r)))
|
||||
}
|
||||
```
|
||||
|
||||
### Stack Traversal
|
||||
```rust
|
||||
fn traverse(root: &Node, ray: &Ray) -> Option<Hit> {
|
||||
let mut stack = vec![root];
|
||||
let mut closest: Option<Hit> = None;
|
||||
while let Some(n) = stack.pop() {
|
||||
match n {
|
||||
Node::Leaf(prims) => for p in prims { if let Some(h) = p.intersect(ray) { closest = Some(h.min_or(closest)); } },
|
||||
Node::Internal(l, r) => { stack.push(r); stack.push(l); }
|
||||
}
|
||||
}
|
||||
closest
|
||||
}
|
||||
```
|
||||
|
||||
### LBVH Morton Build
|
||||
```rust
|
||||
fn morton3d(x: u32, y: u32, z: u32) -> u32 {
|
||||
fn spread(mut v: u32) -> u32 {
|
||||
v = (v | v << 16) & 0x030000FF;
|
||||
v = (v | v << 8) & 0x0300F00F;
|
||||
v = (v | v << 4) & 0x030C30C3;
|
||||
v = (v | v << 2) & 0x09249249;
|
||||
v
|
||||
}
|
||||
spread(x) | (spread(y) << 1) | (spread(z) << 2)
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | BVH 변종 |
|
||||
|---|---|
|
||||
| Static scene, CPU PT | SAH BVH2 |
|
||||
| Dynamic scene | Refit + occasional rebuild |
|
||||
| GPU PT | Wide BVH (BVH4/8) + LBVH/PLOC |
|
||||
| Animated chars | Two-level BVH (TLAS+BLAS) |
|
||||
| Web (three.js) | three-mesh-bvh (SAH) |
|
||||
|
||||
**기본값**: SAH BVH2 for CPU; BVH8 + PLOC for GPU.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[KD-Tree]] · [[Octree]]
|
||||
- 응용: [[Collision Detection]] · [[Frustum Culling]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: explain SAH math, generate boilerplate AABB/traversal code.
|
||||
**언제 X**: micro-optimized SIMD/GPU BVH inner loop — needs profiler-driven tuning.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Median split for production PT**: 10-30% slower traversal vs SAH.
|
||||
- **Recursive traversal on GPU**: stack overflow in registers — use iterative.
|
||||
- **Refit-only forever**: quality degrades; periodic rebuild.
|
||||
- **Per-triangle leaf**: cache-unfriendly; pack 4-8 prims/leaf.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (PBRT 4th ed, Embree paper, Wald 2007 SAH).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — full content with SAH/LBVH patterns |
|
||||
@@ -0,0 +1,144 @@
|
||||
---
|
||||
id: wiki-2026-0508-backups
|
||||
title: Backups
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Backup Strategy, Disaster Recovery, 백업]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [backup, dr, ops, sre]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: Bash/Python
|
||||
framework: restic/borg/AWS Backup
|
||||
---
|
||||
|
||||
# Backups
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 backup 은 restore 가 검증된 backup 만이다."**. Backups 는 매 3-2-1 rule (3 copies, 2 media, 1 offsite) + RTO/RPO target + 정기 restore drill 의 trio. 2026 의 standard: incremental dedup (restic/borg) + immutable object lock (S3 Object Lock, Azure Immutable Blob) + ransomware-resistant air gap.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 3-2-1-1-0 Rule (modern)
|
||||
- **3** copies of data.
|
||||
- **2** different media types.
|
||||
- **1** offsite copy.
|
||||
- **1** immutable / air-gapped (anti-ransomware, 매 2020+ 추가).
|
||||
- **0** errors after restore verification.
|
||||
|
||||
### 매 RTO vs RPO
|
||||
- **RTO (Recovery Time Objective)**: 매 outage 후 service 복구까지 허용 시간.
|
||||
- **RPO (Recovery Point Objective)**: 매 허용 가능한 data loss window.
|
||||
- 매 RTO=1h / RPO=15min 이면 hot standby 필요.
|
||||
|
||||
### 매 Backup Type
|
||||
- **Full**: 매 전체 — slow, large, simple restore.
|
||||
- **Incremental**: 매 since last backup — fast, smaller, restore chain.
|
||||
- **Differential**: 매 since last full — middle ground.
|
||||
- **Snapshot (CoW)**: 매 ZFS/btrfs/LVM/EBS — instant, space-efficient.
|
||||
- **Continuous (CDC)**: 매 every transaction — Postgres WAL, MySQL binlog.
|
||||
|
||||
### 매 응용
|
||||
1. DB backup (pg_basebackup + WAL archive).
|
||||
2. File backup (restic, borg, Time Machine).
|
||||
3. VM/disk snapshot (EBS, GCP PD, ZFS).
|
||||
4. Object store replication (S3 CRR).
|
||||
5. App-level (export-import, logical dump).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### restic encrypted incremental backup
|
||||
```bash
|
||||
# 매 init repo (one-time)
|
||||
restic init --repo s3:s3.amazonaws.com/my-backup-bucket
|
||||
# 매 daily backup
|
||||
restic -r s3:s3.amazonaws.com/my-backup-bucket backup /var/data \
|
||||
--exclude '*.tmp' --tag daily --host $(hostname)
|
||||
# 매 retention: keep 7d, 4w, 12m
|
||||
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
|
||||
# 매 verify
|
||||
restic check --read-data-subset=10%
|
||||
```
|
||||
|
||||
### Postgres PITR setup
|
||||
```bash
|
||||
# postgresql.conf
|
||||
wal_level = replica
|
||||
archive_mode = on
|
||||
archive_command = 'aws s3 cp %p s3://pg-wal/%f'
|
||||
# 매 base backup
|
||||
pg_basebackup -D /backup/base -Ft -z -P -U replicator
|
||||
# 매 restore: recovery.conf or postgresql.auto.conf with restore_command + recovery_target_time
|
||||
```
|
||||
|
||||
### S3 Object Lock (immutable, ransomware-proof)
|
||||
```bash
|
||||
aws s3api put-object-lock-configuration \
|
||||
--bucket my-backup-bucket \
|
||||
--object-lock-configuration '{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":30}}}'
|
||||
```
|
||||
|
||||
### Restore drill automation
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# 매 nightly drill — restore latest to scratch, verify checksums
|
||||
set -euo pipefail
|
||||
SCRATCH=$(mktemp -d)
|
||||
restic -r s3:.../backup restore latest --target "$SCRATCH"
|
||||
sha256sum -c expected_checksums.sha256 --strict
|
||||
echo "drill ok: $(date -Iseconds)" | tee -a /var/log/restore-drill.log
|
||||
rm -rf "$SCRATCH"
|
||||
```
|
||||
|
||||
### ZFS snapshot + send
|
||||
```bash
|
||||
# 매 instant CoW snapshot
|
||||
zfs snapshot tank/data@$(date +%Y%m%d-%H%M)
|
||||
# 매 incremental send to remote
|
||||
zfs send -i tank/data@yesterday tank/data@today | ssh backup-host zfs recv tank/data
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Files, small-mid | restic / borg |
|
||||
| Postgres prod | pg_basebackup + WAL archive (PITR) |
|
||||
| MySQL prod | xtrabackup + binlog |
|
||||
| VM | snapshot + offsite replica |
|
||||
| Multi-cloud | S3-compatible + CRR |
|
||||
| Compliance (WORM) | S3 Object Lock COMPLIANCE mode |
|
||||
|
||||
**기본값**: 매 restic to S3 with Object Lock + nightly restore drill.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[SRE]]
|
||||
- 변형: [[CI_CD_Pipeline]]
|
||||
- 응용: [[카오스 몽키(Chaos Monkey)]]
|
||||
- Adjacent: [[Secret_Management]] · [[Logging_and_Error_Handling]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: backup script generation, restore runbook drafting, log anomaly summarization.
|
||||
**언제 X**: 매 actual restore execution — manual gate 필요.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **No restore test**: 매 가장 흔한 실패 — backup 은 되는데 restore 가 안 됨.
|
||||
- **Single copy**: 매 disk fail 한 방에 잃음.
|
||||
- **No encryption**: 매 backup 이 attack vector — at-rest encrypt 필수.
|
||||
- **No immutability**: 매 ransomware 가 backup 까지 암호화.
|
||||
- **Forever retention**: 매 비용 폭발 + GDPR 위반 가능.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: restic docs; AWS Backup whitepaper; Veeam 3-2-1-1-0 guide; PostgreSQL PITR docs.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — 3-2-1-1-0 + restic/PG PITR/S3 Object Lock |
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: wiki-2026-0508-batchedmesh-및-instancedmesh-성능-벤
|
||||
title: BatchedMesh 및 InstancedMesh 성능 벤치마크
|
||||
category: 10_Wiki/Topics
|
||||
status: duplicate
|
||||
canonical_id: batchedmesh-instancedmesh
|
||||
duplicate_of: "[[BatchedMesh and InstancedMesh Performance]]"
|
||||
aliases: []
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: redirected
|
||||
tags: [duplicate, threejs, webgl, performance]
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
---
|
||||
|
||||
# BatchedMesh 및 InstancedMesh 성능 벤치마크
|
||||
|
||||
> **이 문서는 [[BatchedMesh and InstancedMesh Performance]] 의 중복본입니다.** Canonical 문서로 redirect.
|
||||
|
||||
## 핵심 요약 (specialization aspects, optional)
|
||||
- Three.js r158+ 의 BatchedMesh — 매 multi-draw indirect 활용.
|
||||
- InstancedMesh — 동일 geometry 의 GPU instancing.
|
||||
- Draw call 절감 = 매 frame budget 의 핵심.
|
||||
|
||||
## 🔗 Graph
|
||||
|
||||
## 🕓 변경 이력
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: wiki-2026-0508-beat-saber-엑서게임-연구-beat-saber-ex
|
||||
title: Beat Saber 엑서게임 연구(Beat Saber Exergaming Study)
|
||||
category: 10_Wiki/Topics
|
||||
status: duplicate
|
||||
canonical_id: beat-saber-exergaming
|
||||
duplicate_of: "[[Beat Saber Exergaming]]"
|
||||
aliases: []
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: redirected
|
||||
tags: [duplicate, vr, exergaming, health]
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
---
|
||||
|
||||
# Beat Saber 엑서게임 연구(Beat Saber Exergaming Study)
|
||||
|
||||
> **이 문서는 [[Beat Saber Exergaming]] 의 중복본입니다.** Canonical 문서로 redirect.
|
||||
|
||||
## 핵심 요약 (specialization aspects, optional)
|
||||
- VR rhythm game 의 cardiovascular load — moderate-to-vigorous intensity.
|
||||
- Adherence 가 traditional exercise 보다 높음 (gamification effect).
|
||||
- Energy expenditure 5-8 METs (Expert+ 난이도).
|
||||
|
||||
## 🔗 Graph
|
||||
|
||||
## 🕓 변경 이력
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: wiki-2026-0508-beat-saber를-활용한-vr-엑서게임-후유증-연구-v
|
||||
title: Beat Saber를 활용한 VR 엑서게임 후유증 연구(VR Exergaming Aftereffects)
|
||||
category: 10_Wiki/Topics
|
||||
status: duplicate
|
||||
canonical_id: vr-exergaming-aftereffects
|
||||
duplicate_of: "[[VR Exergaming Aftereffects]]"
|
||||
aliases: []
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: redirected
|
||||
tags: [duplicate, vr, exergaming, cybersickness]
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
---
|
||||
|
||||
# Beat Saber를 활용한 VR 엑서게임 후유증 연구(VR Exergaming Aftereffects)
|
||||
|
||||
> **이 문서는 [[VR Exergaming Aftereffects]] 의 중복본입니다.** Canonical 문서로 redirect.
|
||||
|
||||
## 핵심 요약 (specialization aspects, optional)
|
||||
- Post-VR aftereffects: balance disruption, eye strain, cognitive fatigue.
|
||||
- Cybersickness scores (SSQ) post-session.
|
||||
- Recovery timeline — typically 10-30 min for mild cases.
|
||||
|
||||
## 🔗 Graph
|
||||
|
||||
## 🕓 변경 이력
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
|
||||
@@ -0,0 +1,140 @@
|
||||
---
|
||||
id: wiki-2026-0508-bioinformatics-structure-predict
|
||||
title: Bioinformatics Structure Prediction
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Protein Structure Prediction, AlphaFold, ESM]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [bioinformatics, ml, protein, structure]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: Python
|
||||
framework: AlphaFold3/ESM3/ColabFold
|
||||
---
|
||||
|
||||
# Bioinformatics Structure Prediction
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 sequence 에서 3D 구조까지 — 50년 grand challenge 가 2021 년 풀렸다."**. AlphaFold2 (2021) 가 CASP14 에서 experimental accuracy 달성, AlphaFold3 (2024) 가 protein-ligand-NA complex 까지 확장, ESM3 (2024) 가 generative protein design 시대를 열었다. 2026 의 표준: AF3 + ESMFold + RoseTTAFold All-Atom + ColabFold pipeline.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Method Lineage
|
||||
- **Homology modeling** (1990s): MODELLER — known template 의존.
|
||||
- **Threading / fold recognition** (2000s).
|
||||
- **Ab initio physics** (Rosetta).
|
||||
- **Coevolution + DL** (2018+): trRosetta, AlphaFold1.
|
||||
- **Attention-based** (2021+): AlphaFold2 — Evoformer + Structure module.
|
||||
- **All-atom diffusion** (2024+): AlphaFold3 — protein/DNA/RNA/ligand 통합.
|
||||
- **Single-sequence (LLM)**: ESMFold, ESM3 — 매 MSA 없이 fast.
|
||||
|
||||
### 매 AlphaFold3 Capability (2024)
|
||||
- 매 protein-protein, protein-NA, protein-ligand complex.
|
||||
- 매 covalent modifications, ions.
|
||||
- 매 diffusion-based all-atom output.
|
||||
- 매 license: research-only via AF Server.
|
||||
|
||||
### 매 응용
|
||||
1. **Drug discovery**: target-ligand docking, hit triage.
|
||||
2. **Protein engineering**: enzyme design, antibody.
|
||||
3. **Disease mechanism**: variant effect (missense3D, AlphaMissense).
|
||||
4. **Structural biology**: cryo-EM model building.
|
||||
5. **De novo design**: RFdiffusion + ProteinMPNN.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### ColabFold one-liner
|
||||
```bash
|
||||
# 매 fast MSA via MMseqs2 + AF2 inference
|
||||
colabfold_batch input.fasta out_dir/ \
|
||||
--num-recycle 3 --model-type alphafold2_multimer_v3
|
||||
```
|
||||
|
||||
### ESMFold (single-sequence, no MSA)
|
||||
```python
|
||||
import torch
|
||||
from transformers import EsmForProteinFolding
|
||||
model = EsmForProteinFolding.from_pretrained("facebook/esmfold_v1").cuda().eval()
|
||||
seq = "MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQAPILSRVGDGTQDNLSGAEKAVQVK"
|
||||
with torch.no_grad():
|
||||
out = model.infer_pdb(seq)
|
||||
open("pred.pdb","w").write(out)
|
||||
```
|
||||
|
||||
### AlphaFold3 via API
|
||||
```python
|
||||
# 매 AF3 server (research) — JSON job spec
|
||||
import requests
|
||||
job = {
|
||||
"name": "complex_001",
|
||||
"modelSeeds": [42],
|
||||
"sequences": [
|
||||
{"protein": {"id":"A","sequence":"MKTA..."}},
|
||||
{"ligand": {"id":"L","ccdCodes":["ATP"]}}
|
||||
]
|
||||
}
|
||||
r = requests.post("https://alphafoldserver.com/api/job", json=job, headers=auth)
|
||||
```
|
||||
|
||||
### RFdiffusion de novo binder design
|
||||
```bash
|
||||
# 매 design 80aa binder against target hotspot
|
||||
python run_inference.py \
|
||||
inference.output_prefix=binders/run \
|
||||
contigmap.contigs="['A1-150,0 80-80']" \
|
||||
ppi.hotspot_res="['A30','A33','A56']" \
|
||||
inference.num_designs=100
|
||||
```
|
||||
|
||||
### Confidence (pLDDT) filtering
|
||||
```python
|
||||
import numpy as np
|
||||
# 매 pLDDT > 90 = very high; 70-90 = confident; 50-70 = low; <50 = disordered
|
||||
plddt = np.array([atom.bfactor for atom in structure.get_atoms() if atom.name == "CA"])
|
||||
mean_conf = plddt.mean()
|
||||
disordered_frac = (plddt < 50).mean()
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| Single protein, fast | ESMFold |
|
||||
| Single protein, accurate | AlphaFold2 (ColabFold) |
|
||||
| Multimer / complex | AlphaFold3 / AF-Multimer |
|
||||
| Protein + ligand | AlphaFold3 / Boltz-1 |
|
||||
| De novo design | RFdiffusion + ProteinMPNN |
|
||||
| Variant effect | AlphaMissense |
|
||||
|
||||
**기본값**: 매 ColabFold AF2-multimer → AF3 for ligand/NA.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Statistics & Data Analysis]]
|
||||
- 변형: [[Anomaly-Detection]]
|
||||
- 응용: [[Practical-Cryptography]]
|
||||
- Adjacent: [[Inferential-Statistics]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: protein language model embedding, binder search, paper summary, mutation scan ranking.
|
||||
**언제 X**: 매 final pose prediction — physics/structure model 이 specialized.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **pLDDT 무시**: 매 low-confidence region 을 그대로 사용 — 매 disordered 일 수 있음.
|
||||
- **Single seed**: 매 AF3 multi-seed sampling 권장 — diversity.
|
||||
- **MSA 없이 large complex**: 매 ESMFold 는 single-chain 강점, multimer 약함.
|
||||
- **License 위반**: 매 AF3 weights non-commercial — server API 만 허용.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: Jumper et al. 2021 Nature (AF2); Abramson et al. 2024 Nature (AF3); Lin et al. 2023 Science (ESM2).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — AF3/ESM3/RFdiffusion 2026 stack |
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
id: wiki-2026-0508-blink
|
||||
title: Blink
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-7F733B, Chromium Blink, Blink Renderer]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [browser, web, rendering, chromium]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: cpp
|
||||
framework: chromium
|
||||
---
|
||||
|
||||
# Blink
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 Chromium 의 rendering engine — 매 Web 의 de facto standard."**. Blink 는 Google 이 2013 년 WebKit 에서 fork 한 layout/rendering engine 으로, Chrome/Edge/Brave/Opera 등 Chromium-based browser 의 90%+ market share 를 통해 매 modern web platform (CSS Grid, Houdini, View Transitions) 을 정의한다.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Pipeline
|
||||
1. **Parse** — HTML/CSS → DOM/CSSOM.
|
||||
2. **Style** — selector matching, computed style.
|
||||
3. **Layout (LayoutNG)** — box tree, fragment tree.
|
||||
4. **Paint** — display item list.
|
||||
5. **Composite (CC)** — layer tree → GPU draw quads.
|
||||
6. **Raster + Display** — Skia/SkiaGanesh → Viz → Display compositor.
|
||||
|
||||
### 매 vs WebKit / Gecko
|
||||
- **Blink (Chromium)**: V8, Skia, multi-process.
|
||||
- **WebKit (Safari)**: JavaScriptCore, CoreGraphics/Metal.
|
||||
- **Gecko (Firefox)**: SpiderMonkey, WebRender (Rust).
|
||||
|
||||
### 매 응용
|
||||
1. Chrome/Edge browsers.
|
||||
2. Electron/Tauri (Tauri uses platform webview).
|
||||
3. CEF (Chromium Embedded Framework).
|
||||
4. Headless Chrome / Puppeteer / Playwright.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Custom Element via Web Components
|
||||
```javascript
|
||||
class MyButton extends HTMLElement {
|
||||
connectedCallback() {
|
||||
this.attachShadow({ mode: "open" }).innerHTML = `
|
||||
<button><slot></slot></button>
|
||||
<style>button { padding: 8px 16px; }</style>`;
|
||||
}
|
||||
}
|
||||
customElements.define("my-button", MyButton);
|
||||
```
|
||||
|
||||
### CSS Houdini Paint Worklet
|
||||
```javascript
|
||||
// checkerboard.js
|
||||
class Checkerboard {
|
||||
paint(ctx, geom, props) {
|
||||
const size = props.get("--check-size").value;
|
||||
for (let y = 0; y < geom.height; y += size)
|
||||
for (let x = 0; x < geom.width; x += size)
|
||||
if (((x/size) + (y/size)) % 2) ctx.fillRect(x, y, size, size);
|
||||
}
|
||||
}
|
||||
registerPaint("checkerboard", Checkerboard);
|
||||
```
|
||||
```css
|
||||
div { background: paint(checkerboard); --check-size: 20; }
|
||||
```
|
||||
|
||||
### View Transitions (Blink 111+)
|
||||
```javascript
|
||||
async function navigate(url) {
|
||||
if (!document.startViewTransition) return location.assign(url);
|
||||
const t = document.startViewTransition(() => loadInto(url));
|
||||
await t.finished;
|
||||
}
|
||||
```
|
||||
|
||||
### Performance: Containment
|
||||
```css
|
||||
.card {
|
||||
contain: layout paint style; /* isolate subtree work */
|
||||
content-visibility: auto; /* skip offscreen rendering */
|
||||
}
|
||||
```
|
||||
|
||||
### DevTools Trace (Programmatic)
|
||||
```javascript
|
||||
// puppeteer
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
await page.tracing.start({ path: "trace.json", categories: ["devtools.timeline"] });
|
||||
await page.goto("https://example.com");
|
||||
await page.tracing.stop();
|
||||
```
|
||||
|
||||
### CDP (Chrome DevTools Protocol)
|
||||
```javascript
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send("Performance.enable");
|
||||
const { metrics } = await client.send("Performance.getMetrics");
|
||||
console.log(metrics.find(m => m.name === "LayoutCount"));
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | 권장 |
|
||||
|---|---|
|
||||
| Cross-browser web app | Standards-only, test 3 engines |
|
||||
| Desktop app (full Chromium) | Electron/CEF |
|
||||
| Lightweight desktop | Tauri (system webview) |
|
||||
| Automation/scrape | Playwright (multi-engine) |
|
||||
| Mobile WebView | System WebView (avoid bundling) |
|
||||
|
||||
**기본값**: standards + feature detection; Blink-specific API only with fallbacks.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Chromium]]
|
||||
- 변형: [[WebKit]]
|
||||
- 응용: [[Electron]] · [[Playwright]]
|
||||
- Adjacent: [[V8]] · [[Skia]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: explain pipeline stage, generate web platform boilerplate.
|
||||
**언제 X**: Blink internals C++ patches — need source + CL review.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Vendor-prefixed only**: `-webkit-` without standard fallback.
|
||||
- **Layout thrashing**: read-write-read forced sync layouts.
|
||||
- **Heavy main thread**: blocks composite — use Workers + OffscreenCanvas.
|
||||
- **Assuming Chromium-only**: breaks Safari/Firefox parity.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (chromium.org docs, web.dev, Blink design docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — pipeline, Houdini, View Transitions |
|
||||
@@ -0,0 +1,165 @@
|
||||
---
|
||||
id: wiki-2026-0508-blog-post
|
||||
title: Blog Post
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Engineering Blog, Tech Writing]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [writing, content, devrel]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: Markdown/MDX
|
||||
framework: Astro/Next.js/Hugo
|
||||
---
|
||||
|
||||
# Blog Post
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 잘 쓴 한 글이 1000번의 회의를 대체한다."**. Engineering blog post 는 매 internal knowledge 를 외부 (recruiting, brand, community) 와 미래 자신 에게 publish 하는 매 leveraged artifact. 2026 의 stack: Astro/Next.js + MDX + algolia search + RSS + open-graph + Schema.org + AI-generated TL;DR.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Strong Post 의 Anatomy
|
||||
- **Hook**: 매 첫 두 문장 — problem + stake.
|
||||
- **TL;DR / BLUF**: 매 결론 먼저.
|
||||
- **Concrete numbers**: 매 "20% faster" not "much faster".
|
||||
- **Code that runs**: 매 copy-pasteable, working snippet.
|
||||
- **Diagrams**: 매 system 그림이 단어 100개를 대체.
|
||||
- **Honest tradeoffs**: 매 안 좋은 점도 적기.
|
||||
- **Sources**: 매 reference link.
|
||||
|
||||
### 매 Format Type
|
||||
- **Tutorial**: 매 step-by-step, runnable.
|
||||
- **Reference**: 매 spec-like.
|
||||
- **Explainer / mental-model**: 매 "왜".
|
||||
- **Postmortem**: 매 incident retrospective.
|
||||
- **Decision record (ADR)**: 매 trade-off 기록.
|
||||
- **Benchmark**: 매 measure + reproduce.
|
||||
|
||||
### 매 Stack 2026
|
||||
- **Authoring**: MDX, code blocks with shiki/Prism, KaTeX math.
|
||||
- **SSG**: Astro, Next.js, Hugo, Eleventy.
|
||||
- **Hosting**: Vercel, Cloudflare Pages, Netlify, GitHub Pages.
|
||||
- **Analytics**: Plausible, Fathom (privacy-friendly).
|
||||
- **Feedback**: Giscus (GitHub Discussions).
|
||||
|
||||
### 매 응용
|
||||
1. Engineering blog (Stripe, Cloudflare, Vercel style).
|
||||
2. Personal site (Notion-style or Astro).
|
||||
3. Internal wiki post.
|
||||
4. Conference talk companion.
|
||||
5. Open-source project announcement.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Astro + MDX setup
|
||||
```bash
|
||||
bun create astro@latest my-blog -- --template blog --typescript strict
|
||||
cd my-blog && bunx astro add mdx sitemap
|
||||
```
|
||||
|
||||
### Frontmatter schema (zod-validated)
|
||||
```typescript
|
||||
// src/content/config.ts
|
||||
import { defineCollection, z } from 'astro:content';
|
||||
export const collections = {
|
||||
blog: defineCollection({
|
||||
type: 'content',
|
||||
schema: z.object({
|
||||
title: z.string().max(70),
|
||||
pubDate: z.coerce.date(),
|
||||
tags: z.array(z.string()),
|
||||
heroImage: z.string().optional(),
|
||||
tldr: z.string().min(40).max(280),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
```
|
||||
|
||||
### Code block with shiki + line highlight
|
||||
````mdx
|
||||
```ts {3-5}
|
||||
function fib(n: number): number {
|
||||
if (n < 2) return n;
|
||||
// 매 highlighted recursion
|
||||
return fib(n-1) + fib(n-2);
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
### Open Graph + JSON-LD
|
||||
```html
|
||||
<meta property="og:title" content={post.title}>
|
||||
<meta property="og:description" content={post.tldr}>
|
||||
<meta property="og:image" content={`https://blog.example.com/og/${post.slug}.png`}>
|
||||
<script type="application/ld+json">{JSON.stringify({
|
||||
"@context":"https://schema.org",
|
||||
"@type":"BlogPosting",
|
||||
"headline": post.title,
|
||||
"datePublished": post.pubDate.toISOString(),
|
||||
})}</script>
|
||||
```
|
||||
|
||||
### Auto-generated OG image (Vercel OG)
|
||||
```typescript
|
||||
// pages/og/[slug].tsx
|
||||
import { ImageResponse } from '@vercel/og';
|
||||
export default function og(req) {
|
||||
const title = new URL(req.url).searchParams.get('title');
|
||||
return new ImageResponse(<div style={{fontSize:64,padding:80}}>{title}</div>, { width:1200, height:630 });
|
||||
}
|
||||
```
|
||||
|
||||
### TL;DR via LLM (build-time)
|
||||
```typescript
|
||||
// 매 build hook — generate 280-char summary
|
||||
const tldr = await anthropic.messages.create({
|
||||
model: 'claude-haiku-4',
|
||||
max_tokens: 200,
|
||||
messages: [{ role:'user', content:`Summarize in 2 sentences:\n\n${markdown}` }],
|
||||
});
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | SSG |
|
||||
|---|---|
|
||||
| Content-heavy, fast | Astro |
|
||||
| React stack, ISR | Next.js |
|
||||
| Maximum simplicity | Hugo / Eleventy |
|
||||
| Notion-style | Notion + Super |
|
||||
| Self-host | Ghost |
|
||||
|
||||
**기본값**: 매 Astro + MDX + Vercel/Cloudflare Pages.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Continuous-Discovery]]
|
||||
- 변형: [[BLUF (Bottom Line Up Front)]]
|
||||
- 응용: [[MECE Principle]]
|
||||
- Adjacent: [[Edtech-Industry-Trends]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: TL;DR 생성, alt-text, SEO meta description, draft outline.
|
||||
**언제 X**: 매 fact claim — 매 verify 안 한 LLM output 은 hallucination 위험.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Wall of text**: 매 heading + list 없이는 skim 불가.
|
||||
- **Pseudocode only**: 매 reader 가 실행 못 함.
|
||||
- **No metrics**: 매 "faster, better" 만 — concrete 숫자 필요.
|
||||
- **Stale code**: 매 deprecated API 사용.
|
||||
- **No date**: 매 reader 가 freshness 판단 불가.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: web.dev SEO docs; Schema.org BlogPosting; Astro docs.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — anatomy + Astro/MDX/OG patterns |
|
||||
@@ -0,0 +1,145 @@
|
||||
---
|
||||
id: wiki-2026-0508-branch-prediction
|
||||
title: Branch Prediction
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-4D7707, CPU Branch Predictor]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [cpu, performance, security, microarchitecture]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: cpp
|
||||
framework: none
|
||||
---
|
||||
|
||||
# Branch Prediction
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 modern CPU 의 IPC 핵심 mechanism — 그리고 Spectre 의 attack surface."**. Branch predictor 는 conditional/indirect branch 의 결과를 speculatively execute 함으로써 deep pipeline 의 stall 을 회피; 매 misprediction penalty 는 15-20+ cycles, 매 mispredicted speculative window 가 Spectre v1/v2 의 leak vector.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Predictor 종류
|
||||
- **Static**: forward-not-taken, backward-taken (hint).
|
||||
- **Bimodal (2-bit)**: per-PC saturating counter.
|
||||
- **Local history**: per-branch shift register.
|
||||
- **Global history (gshare/GAg)**: shared GHR XOR PC.
|
||||
- **Tournament**: meta-predictor selects local vs global.
|
||||
- **TAGE / ITTAGE**: tagged geometric history (modern SOTA).
|
||||
- **Perceptron**: AMD Zen — neural-style predictor.
|
||||
|
||||
### 매 Indirect Branches
|
||||
- BTB (Branch Target Buffer) — caches target.
|
||||
- ITTAGE for indirect.
|
||||
- Critical for vtables, function pointers, switch.
|
||||
|
||||
### 매 응용
|
||||
1. Hot loops — predictable branches → near-zero penalty.
|
||||
2. Sorted-data effect (the famous SO question).
|
||||
3. Spectre/BranchScope side-channel attacks.
|
||||
4. JIT branch ordering decisions (V8, Hotspot).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Likely / Unlikely Hints (C++20)
|
||||
```cpp
|
||||
if (x > 0) [[likely]] {
|
||||
fast_path();
|
||||
} else [[unlikely]] {
|
||||
slow_path();
|
||||
}
|
||||
```
|
||||
|
||||
### Branchless via Mask
|
||||
```cpp
|
||||
// branchful
|
||||
int abs_v(int x) { return x < 0 ? -x : x; }
|
||||
|
||||
// branchless
|
||||
int abs_v_nb(int x) {
|
||||
int mask = x >> 31; // 0 or -1
|
||||
return (x ^ mask) - mask;
|
||||
}
|
||||
```
|
||||
|
||||
### Branchless Min via cmov
|
||||
```cpp
|
||||
int min_v(int a, int b) {
|
||||
return a < b ? a : b; // compilers emit cmov on x86
|
||||
}
|
||||
```
|
||||
|
||||
### Sort Before Loop (classic)
|
||||
```cpp
|
||||
std::sort(data.begin(), data.end()); // 정렬 → branch predictable
|
||||
long sum = 0;
|
||||
for (int v : data) if (v >= 128) sum += v;
|
||||
```
|
||||
|
||||
### LLVM `__builtin_expect`
|
||||
```cpp
|
||||
if (__builtin_expect(error_flag, 0)) {
|
||||
handle_error();
|
||||
}
|
||||
```
|
||||
|
||||
### Spectre v1 Mitigation (lfence)
|
||||
```cpp
|
||||
// vulnerable
|
||||
if (idx < arr_size) {
|
||||
secret = arr[idx]; // mispredict → leaks
|
||||
}
|
||||
// hardened
|
||||
if (idx < arr_size) {
|
||||
asm volatile("lfence" ::: "memory");
|
||||
secret = arr[idx];
|
||||
}
|
||||
```
|
||||
|
||||
### perf Branch Stats
|
||||
```bash
|
||||
perf stat -e branches,branch-misses ./bench
|
||||
# branch-miss rate > 5% → suspect; > 10% → critical
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | 전략 |
|
||||
|---|---|
|
||||
| Hot loop, predictable | Trust predictor — natural code |
|
||||
| Hot loop, unpredictable | Branchless / mask / cmov |
|
||||
| Cold path | Doesn't matter — clarity > tricks |
|
||||
| Indirect-heavy (vtable) | Devirtualize, monomorphize |
|
||||
| Security-sensitive | lfence / speculative load hardening |
|
||||
|
||||
**기본값**: write clear branchful code; branchless only when profiler shows misprediction hotspot.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Pipeline]]
|
||||
- 응용: [[JIT Compilation]]
|
||||
- Adjacent: [[Spectre]] · [[Speculative Execution]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: explain mispredict cost, generate branchless equivalents, suggest hints.
|
||||
**언제 X**: micro-arch tuning without perf data — speculation hurts.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Random unpredictable branch in hot loop**: 20-30% slowdown.
|
||||
- **Premature branchless conversion**: hurts cold/clarity paths.
|
||||
- **Trusting `[[likely]]` blindly**: PGO data > human guess.
|
||||
- **Ignoring Spectre in untrusted-input parsers**: real CVE risk.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Hennessy & Patterson 6th, Agner Fog optimization manuals, Intel SDM).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — predictor types, branchless patterns, Spectre |
|
||||
@@ -0,0 +1,160 @@
|
||||
---
|
||||
id: wiki-2026-0508-buffergeometry
|
||||
title: BufferGeometry
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-2887C6, Three.js BufferGeometry]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [graphics, threejs, webgl, performance]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: javascript
|
||||
framework: three.js
|
||||
---
|
||||
|
||||
# BufferGeometry
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 Three.js 의 GPU-resident geometry container — 매 modern Three 의 only geometry class."**. BufferGeometry 는 typed-array 기반 attribute (position, normal, uv, index) 의 GPU upload 를 직접 관리하며, 매 Geometry class deprecation (r125) 이후 표준 — instancing/batching/morph 의 backbone.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Attribute
|
||||
- **Position** (Float32Array, itemSize=3): vertex coords.
|
||||
- **Normal** (Float32Array, itemSize=3).
|
||||
- **UV** (Float32Array, itemSize=2).
|
||||
- **Index** (Uint16/Uint32Array): triangle list.
|
||||
- **Custom**: any vertex attribute (color, tangent, instance data).
|
||||
|
||||
### 매 Update Strategy
|
||||
- **Static**: upload once, never modify (default).
|
||||
- **Dynamic** (`setUsage(DynamicDrawUsage)`): frequent CPU update.
|
||||
- **Stream**: per-frame update (rare).
|
||||
|
||||
### 매 응용
|
||||
1. Custom shaders with custom attributes.
|
||||
2. GPU instancing (InstancedBufferAttribute).
|
||||
3. Procedural geometry generation.
|
||||
4. Mesh deformation / morphing.
|
||||
5. GPGPU particle systems.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Manual Triangle
|
||||
```javascript
|
||||
import * as THREE from "three";
|
||||
|
||||
const geo = new THREE.BufferGeometry();
|
||||
const positions = new Float32Array([
|
||||
0, 1, 0,
|
||||
-1, -1, 0,
|
||||
1, -1, 0,
|
||||
]);
|
||||
geo.setAttribute("position", new THREE.BufferAttribute(positions, 3));
|
||||
geo.computeVertexNormals();
|
||||
```
|
||||
|
||||
### Indexed Quad
|
||||
```javascript
|
||||
const positions = new Float32Array([-1,-1,0, 1,-1,0, 1,1,0, -1,1,0]);
|
||||
const indices = new Uint16Array([0, 1, 2, 0, 2, 3]);
|
||||
const geo = new THREE.BufferGeometry();
|
||||
geo.setAttribute("position", new THREE.BufferAttribute(positions, 3));
|
||||
geo.setIndex(new THREE.BufferAttribute(indices, 1));
|
||||
```
|
||||
|
||||
### Dynamic Vertex Update
|
||||
```javascript
|
||||
const attr = geo.attributes.position;
|
||||
attr.setUsage(THREE.DynamicDrawUsage);
|
||||
|
||||
function tick(t) {
|
||||
for (let i = 0; i < attr.count; i++) {
|
||||
attr.setY(i, Math.sin(t + i * 0.1));
|
||||
}
|
||||
attr.needsUpdate = true;
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Shader Attribute
|
||||
```javascript
|
||||
const aRandom = new Float32Array(geo.attributes.position.count);
|
||||
for (let i = 0; i < aRandom.length; i++) aRandom[i] = Math.random();
|
||||
geo.setAttribute("aRandom", new THREE.BufferAttribute(aRandom, 1));
|
||||
|
||||
const mat = new THREE.ShaderMaterial({
|
||||
vertexShader: `attribute float aRandom; varying float vR;
|
||||
void main(){ vR=aRandom; gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.); }`,
|
||||
fragmentShader: `varying float vR; void main(){ gl_FragColor=vec4(vR,vR,vR,1.); }`,
|
||||
});
|
||||
```
|
||||
|
||||
### Instanced Attribute
|
||||
```javascript
|
||||
const N = 10000;
|
||||
const offsets = new Float32Array(N * 3);
|
||||
for (let i = 0; i < N; i++) {
|
||||
offsets[i*3] = (Math.random()-0.5)*100;
|
||||
offsets[i*3+1] = (Math.random()-0.5)*100;
|
||||
offsets[i*3+2] = (Math.random()-0.5)*100;
|
||||
}
|
||||
const igeo = new THREE.InstancedBufferGeometry().copy(geo);
|
||||
igeo.instanceCount = N;
|
||||
igeo.setAttribute("aOffset", new THREE.InstancedBufferAttribute(offsets, 3));
|
||||
```
|
||||
|
||||
### Merge Geometries
|
||||
```javascript
|
||||
import { mergeGeometries } from "three/addons/utils/BufferGeometryUtils.js";
|
||||
|
||||
const merged = mergeGeometries([geoA, geoB, geoC], false);
|
||||
// single draw call instead of three
|
||||
```
|
||||
|
||||
### Bounding Volume Recompute
|
||||
```javascript
|
||||
geo.computeBoundingBox();
|
||||
geo.computeBoundingSphere(); // required for frustum culling after vertex moves
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Static mesh | StaticDrawUsage (default) |
|
||||
| Per-frame deform | DynamicDrawUsage + needsUpdate |
|
||||
| Many copies | InstancedBufferGeometry |
|
||||
| Many distinct meshes | mergeGeometries or BatchedMesh |
|
||||
| Massive points | BufferGeometry + Points + custom shader |
|
||||
|
||||
**기본값**: static indexed BufferGeometry; switch to instanced/merged for >100 copies.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Three.js]]
|
||||
- 변형: [[BatchedMesh]]
|
||||
- Adjacent: [[BufferAttribute]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: generate procedural geometry boilerplate, debug attribute layout.
|
||||
**언제 X**: micro-optimization of custom shaders without profiling.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Forgetting `needsUpdate = true`**: GPU never re-uploads.
|
||||
- **Recreating BufferGeometry per frame**: GC pressure — mutate in place.
|
||||
- **Float32 indices**: not supported — use Uint16/Uint32.
|
||||
- **No bounding sphere recompute**: frustum-culled erroneously after deform.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (three.js r170 docs, threejs-journey).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — attributes, dynamic update, instancing patterns |
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: wiki-2026-0508-cantab-5-선택-반응-시간-과제-cantab-5-ch
|
||||
title: CANTAB 5-선택 반응 시간 과제(CANTAB 5-choice RTI)
|
||||
category: 10_Wiki/Topics
|
||||
status: duplicate
|
||||
canonical_id: cantab-5-choice-rti
|
||||
duplicate_of: "[[CANTAB 5-Choice RTI]]"
|
||||
aliases: []
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: redirected
|
||||
tags: [duplicate, neuropsychology, cognition, assessment]
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
---
|
||||
|
||||
# CANTAB 5-선택 반응 시간 과제(CANTAB 5-choice RTI)
|
||||
|
||||
> **이 문서는 [[CANTAB 5-Choice RTI]] 의 중복본입니다.** Canonical 문서로 redirect.
|
||||
|
||||
## 핵심 요약 (specialization aspects, optional)
|
||||
- Cambridge Neuropsychological Test Automated Battery (CANTAB) 의 5-choice reaction time task.
|
||||
- Movement time + reaction time 의 분리 측정.
|
||||
- 임상: ADHD, dementia, TBI 의 attention/processing speed assessment.
|
||||
|
||||
## 🔗 Graph
|
||||
|
||||
## 🕓 변경 이력
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
|
||||
@@ -0,0 +1,163 @@
|
||||
---
|
||||
id: wiki-2026-0508-ci-cd-pipeline
|
||||
title: CI CD Pipeline
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Continuous Integration / Delivery Pipeline, Build Pipeline]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [ci, cd, devops, pipeline]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: YAML
|
||||
framework: GitHub Actions/GitLab CI/Buildkite
|
||||
---
|
||||
|
||||
# CI CD Pipeline
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 commit 이 production 까지 도달하는 자동 경로가 CI/CD pipeline."**. Pipeline 은 build → test → security → package → deploy → verify 의 매 ordered DAG. 2026 의 표준: GitHub Actions reusable workflow + OIDC 기반 cloud auth + supply-chain attestation (SLSA L3) + progressive delivery (Argo Rollouts/Flagger).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Pipeline Stage
|
||||
1. **Source**: trigger on PR / push / tag.
|
||||
2. **Build**: deterministic, hermetic — Bazel/Nx cache.
|
||||
3. **Test**: unit / integration / e2e — parallel shards.
|
||||
4. **Security**: SAST (Semgrep), SCA (Trivy), secret scan.
|
||||
5. **Package**: container, helm chart, npm — sign (cosign).
|
||||
6. **Attest**: SBOM (Syft) + SLSA provenance.
|
||||
7. **Deploy**: env-progressive (dev → staging → prod).
|
||||
8. **Verify**: smoke, canary metrics, auto-rollback.
|
||||
|
||||
### 매 Modern Best Practices 2026
|
||||
- **OIDC over long-lived secrets** (GitHub OIDC → AWS/GCP).
|
||||
- **Reusable workflows** — DRY across repos.
|
||||
- **Matrix sharding** — test parallelism.
|
||||
- **Cache layers** — Turborepo, Nx, Bazel remote cache.
|
||||
- **Progressive delivery** — canary, blue/green, feature flags.
|
||||
- **GitOps** — Argo CD / Flux — git as source of truth.
|
||||
- **Supply chain** — Sigstore cosign, SLSA L3 attestation.
|
||||
|
||||
### 매 응용
|
||||
1. SaaS web app deploy.
|
||||
2. Library publish (npm, PyPI, Maven).
|
||||
3. Container image release.
|
||||
4. Mobile (Fastlane).
|
||||
5. ML model deploy (MLOps).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### GitHub Actions reusable workflow
|
||||
```yaml
|
||||
# .github/workflows/ci.yml
|
||||
on: [pull_request, push]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # 매 OIDC
|
||||
jobs:
|
||||
test:
|
||||
uses: org/.github/.github/workflows/ts-ci.yml@v1
|
||||
with:
|
||||
node-version: '22'
|
||||
deploy:
|
||||
needs: test
|
||||
if: github.ref == 'refs/heads/main'
|
||||
uses: org/.github/.github/workflows/deploy.yml@v1
|
||||
with:
|
||||
env: prod
|
||||
```
|
||||
|
||||
### OIDC to AWS (no long-lived keys)
|
||||
```yaml
|
||||
- uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::123:role/gha-deployer
|
||||
aws-region: us-east-1
|
||||
- run: aws s3 sync ./dist s3://my-bucket
|
||||
```
|
||||
|
||||
### Matrix test sharding
|
||||
```yaml
|
||||
strategy:
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4]
|
||||
steps:
|
||||
- run: bun run vitest run --shard=${{ matrix.shard }}/4
|
||||
```
|
||||
|
||||
### Container build + sign + SBOM
|
||||
```yaml
|
||||
- uses: docker/build-push-action@v6
|
||||
id: build
|
||||
with: { tags: ghcr.io/org/app:${{ github.sha }}, push: true }
|
||||
- uses: anchore/sbom-action@v0
|
||||
with: { image: ghcr.io/org/app:${{ github.sha }}, format: spdx-json }
|
||||
- uses: sigstore/cosign-installer@v3
|
||||
- run: cosign sign --yes ghcr.io/org/app@${{ steps.build.outputs.digest }}
|
||||
```
|
||||
|
||||
### Argo Rollouts canary
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Rollout
|
||||
spec:
|
||||
strategy:
|
||||
canary:
|
||||
steps:
|
||||
- setWeight: 10
|
||||
- pause: { duration: 5m }
|
||||
- analysis: { templates: [{ templateName: error-rate }] }
|
||||
- setWeight: 50
|
||||
- pause: { duration: 10m }
|
||||
- setWeight: 100
|
||||
```
|
||||
|
||||
### Turborepo remote cache
|
||||
```bash
|
||||
# 매 first build seeds cache; later runs hit
|
||||
TURBO_TOKEN=$REMOTE_TOKEN TURBO_TEAM=acme bunx turbo run build --remote-cache-timeout=60
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| OSS / GitHub repo | GitHub Actions |
|
||||
| GitLab native | GitLab CI |
|
||||
| Monorepo many pipelines | Buildkite / Dagger |
|
||||
| K8s GitOps | Argo CD + Argo Rollouts |
|
||||
| Multi-cloud workflow | Dagger / Earthly |
|
||||
|
||||
**기본값**: 매 GitHub Actions + OIDC + reusable workflow + Argo Rollouts.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Continuous Integration (지속적 통합, CI)]] · [[Continuous Delivery (지속적 제공, CD)]]
|
||||
- 변형: [[지속적 통합 (CI) 및 지속적 배포 (CD)]]
|
||||
- 응용: [[Engineering Metrics (DORA)]] · [[Feature-Flags]]
|
||||
- Adjacent: [[Husky]] · [[Test_Automation]] · [[Secret_Management]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: workflow YAML drafting, failed-build log triage, retry-storm root-cause.
|
||||
**언제 X**: 매 deterministic step (lint/test) — pipeline 자체가 검증.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Long-lived AWS keys in secret**: 매 OIDC 사용.
|
||||
- **`if: always()` 남용**: 매 fail 무시 — 신뢰 무너짐.
|
||||
- **No cache**: 매 매 build 30분.
|
||||
- **Single-stage everything**: 매 fail-fast 설계 안 됨.
|
||||
- **No staging**: 매 직접 prod — rollback 어려움.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: GitHub Actions docs; SLSA spec v1.0; Argo Rollouts docs; DORA report 2024.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — pipeline stages + OIDC/SLSA/canary |
|
||||
@@ -0,0 +1,158 @@
|
||||
---
|
||||
id: wiki-2026-0508-cpu-bottleneck
|
||||
title: CPU Bottleneck
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [CPU-Bound, Compute Bottleneck]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [performance, profiling, cpu]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: C++/Rust/JS
|
||||
framework: perf/Instruments/Chrome DevTools
|
||||
---
|
||||
|
||||
# CPU Bottleneck
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 GPU 가 놀고 main thread 가 100% 면 CPU bottleneck."**. CPU bottleneck 은 frame budget 16.7ms (60fps) 또는 11ms (90fps XR) 안에 main thread 작업이 안 끝나는 상태. 2026 진단: Chrome Performance panel + perf + Instruments → fix: WebWorker / WASM SIMD / off-main-thread / batching.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 진단 신호
|
||||
- GPU utilization < 70% but FPS drop.
|
||||
- Long Task > 50ms in Performance panel.
|
||||
- `perf top` 의 single function 이 hot.
|
||||
- Profile 의 self-time 이 한 함수에 집중.
|
||||
|
||||
### 매 Bottleneck Source
|
||||
- **Main-thread JS**: parse, layout, large loop.
|
||||
- **Layout thrash**: read-write-read DOM.
|
||||
- **GC pause**: allocation pressure.
|
||||
- **Synchronous IO**: blocking syscall.
|
||||
- **Unoptimized algorithm**: O(n²) on hot path.
|
||||
- **Single-core saturation**: no parallelism.
|
||||
|
||||
### 매 Fix Strategy
|
||||
1. **Profile first** — 매 measure, not guess.
|
||||
2. **Off-main-thread**: WebWorker, OffscreenCanvas.
|
||||
3. **Batch**: requestAnimationFrame, microtask.
|
||||
4. **SIMD/WASM**: 매 hot inner loop.
|
||||
5. **Algorithmic**: O(n²) → O(n log n).
|
||||
6. **Cache**: memoize, weak-ref.
|
||||
7. **Lazy**: defer, code-split.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Detect long task
|
||||
```javascript
|
||||
const obs = new PerformanceObserver(list => {
|
||||
for (const e of list.getEntries()) {
|
||||
if (e.duration > 50) console.warn('long task', e.duration, e.name);
|
||||
}
|
||||
});
|
||||
obs.observe({ entryTypes: ['longtask'] });
|
||||
```
|
||||
|
||||
### Move work to Worker
|
||||
```javascript
|
||||
// main.js
|
||||
const w = new Worker('worker.js', { type: 'module' });
|
||||
w.postMessage({ data: bigArray }, [bigArray.buffer]); // 매 transfer, zero-copy
|
||||
w.onmessage = e => render(e.data);
|
||||
|
||||
// worker.js
|
||||
self.onmessage = e => {
|
||||
const result = heavyCompute(e.data.data);
|
||||
self.postMessage(result, [result.buffer]);
|
||||
};
|
||||
```
|
||||
|
||||
### WASM SIMD hot loop (Rust)
|
||||
```rust
|
||||
#[target_feature(enable = "simd128")]
|
||||
unsafe fn dot_product(a: &[f32], b: &[f32]) -> f32 {
|
||||
use std::arch::wasm32::*;
|
||||
let mut sum = f32x4_splat(0.0);
|
||||
for i in (0..a.len()).step_by(4) {
|
||||
let va = v128_load(a.as_ptr().add(i) as *const v128);
|
||||
let vb = v128_load(b.as_ptr().add(i) as *const v128);
|
||||
sum = f32x4_add(sum, f32x4_mul(va, vb));
|
||||
}
|
||||
f32x4_extract_lane::<0>(sum) + f32x4_extract_lane::<1>(sum)
|
||||
+ f32x4_extract_lane::<2>(sum) + f32x4_extract_lane::<3>(sum)
|
||||
}
|
||||
```
|
||||
|
||||
### Time-sliced loop (yield to event loop)
|
||||
```javascript
|
||||
async function processChunked(items) {
|
||||
const CHUNK = 200;
|
||||
for (let i = 0; i < items.length; i += CHUNK) {
|
||||
items.slice(i, i + CHUNK).forEach(processOne);
|
||||
await new Promise(r => setTimeout(r, 0)); // 매 yield
|
||||
}
|
||||
}
|
||||
// 또는 scheduler.yield() (2025+)
|
||||
if ('scheduler' in window && 'yield' in scheduler) await scheduler.yield();
|
||||
```
|
||||
|
||||
### Batch DOM read/write
|
||||
```javascript
|
||||
// 매 안티 — layout thrash
|
||||
items.forEach(el => { const w = el.offsetWidth; el.style.width = (w*2)+'px'; });
|
||||
// 매 fix — read first, then write
|
||||
const widths = items.map(el => el.offsetWidth);
|
||||
items.forEach((el, i) => { el.style.width = (widths[i]*2)+'px'; });
|
||||
```
|
||||
|
||||
### Linux perf hot function
|
||||
```bash
|
||||
sudo perf record -F 99 -g -p $(pidof myapp) -- sleep 10
|
||||
sudo perf report --stdio | head -40
|
||||
sudo perf script | stackcollapse-perf.pl | flamegraph.pl > flame.svg
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Long JS function | WebWorker / time-slice |
|
||||
| Image/video pipeline | OffscreenCanvas |
|
||||
| Number crunching | WASM SIMD / GPU compute |
|
||||
| Layout thrash | read-then-write batch |
|
||||
| GC pressure | object pool |
|
||||
| Multi-core unused | Worker pool / parallel |
|
||||
|
||||
**기본값**: 매 measure → identify hot fn → off-main-thread or algorithmic fix.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Analyze runtime performance]] · [[Flame_Graphs]]
|
||||
- 변형: [[Draw Call]]
|
||||
- 응용: [[Tree Shaking (번들 크기 최적화)]] · [[Frustum Culling]]
|
||||
- Adjacent: [[Memory Management]] · [[Branch Prediction]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: profile flamegraph 해석, hot-function refactor 제안, perf annotation.
|
||||
**언제 X**: 매 actual perf measurement — deterministic 도구가 정확.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Premature optimization**: 매 profile 없이 추측 — 잘못된 부분 fix.
|
||||
- **Worker overuse**: 매 small task 의 postMessage 오버헤드 > 이득.
|
||||
- **`while(true)` busy-wait**: 매 throttle / requestIdleCallback 사용.
|
||||
- **Synchronous XHR**: 매 deprecated, main-thread block.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: Chrome Performance docs; web.dev Long Tasks; Linux perf-tools (Brendan Gregg).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — diagnosis + Worker/SIMD/yield patterns |
|
||||
@@ -0,0 +1,151 @@
|
||||
---
|
||||
id: wiki-2026-0508-cheneys-algorithm
|
||||
title: Cheney's Algorithm
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Cheney GC, Semi-space Collector, Copying GC]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [gc, memory, algorithm, runtime]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: C/Rust
|
||||
framework: runtime/GC
|
||||
---
|
||||
|
||||
# Cheney's Algorithm
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 stop-and-copy GC 의 BFS-style two-finger traversal"**. 1970년 C.J. Cheney 가 제시한 copying garbage collector 의 표준 algorithm — recursion 없이 queue-style 로 live object 를 from-space 에서 to-space 로 evacuate. 매 modern V8/SpiderMonkey young generation, OCaml minor heap, MLton 의 baseline.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 semi-space 구조
|
||||
- Heap 을 두 개의 equal-sized region 으로 split: from-space, to-space.
|
||||
- Allocation 은 from-space 의 bump pointer 만 증가.
|
||||
- GC 시 live object 를 to-space 로 copy 후 role swap.
|
||||
|
||||
### 매 two pointers
|
||||
- `scan`: to-space 에서 아직 children 추적 안 한 boundary.
|
||||
- `free`: to-space 의 next allocation slot.
|
||||
- `scan == free` 이면 traversal 종료.
|
||||
|
||||
### 매 응용
|
||||
1. V8 young-gen scavenger (Node.js, Chrome).
|
||||
2. OCaml minor heap collection.
|
||||
3. SBCL, MLton 의 default GC.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Core Cheney loop (C)
|
||||
```c
|
||||
void* to_space; size_t scan, free_;
|
||||
|
||||
void* copy(void* obj) {
|
||||
if (is_forwarded(obj)) return forward_addr(obj);
|
||||
size_t sz = size_of(obj);
|
||||
void* dst = (char*)to_space + free_;
|
||||
memcpy(dst, obj, sz);
|
||||
set_forward(obj, dst);
|
||||
free_ += sz;
|
||||
return dst;
|
||||
}
|
||||
|
||||
void cheney_gc(void** roots, size_t n) {
|
||||
free_ = scan = 0;
|
||||
for (size_t i = 0; i < n; i++) roots[i] = copy(roots[i]);
|
||||
while (scan < free_) {
|
||||
void* obj = (char*)to_space + scan;
|
||||
for_each_pointer_field(obj, p) { *p = copy(*p); }
|
||||
scan += size_of(obj);
|
||||
}
|
||||
swap(from_space, to_space);
|
||||
}
|
||||
```
|
||||
|
||||
### Forwarding pointer trick
|
||||
```c
|
||||
// Object header overlap: live header OR forwarding pointer.
|
||||
struct header { uintptr_t tag_or_fwd; };
|
||||
#define IS_FWD(h) ((h)->tag_or_fwd & 1)
|
||||
#define FWD_PTR(h) ((void*)((h)->tag_or_fwd & ~1))
|
||||
#define SET_FWD(h, dst) ((h)->tag_or_fwd = (uintptr_t)(dst) | 1)
|
||||
```
|
||||
|
||||
### Allocation (post-GC)
|
||||
```c
|
||||
void* alloc(size_t sz) {
|
||||
if (free_ + sz > SEMI_SIZE) cheney_gc(roots, n_roots);
|
||||
if (free_ + sz > SEMI_SIZE) abort(); // OOM
|
||||
void* p = (char*)to_space + free_;
|
||||
free_ += sz;
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
### V8-style scavenger (simplified)
|
||||
```cpp
|
||||
void Scavenger::Process() {
|
||||
while (!worklist_.empty()) {
|
||||
HeapObject obj = worklist_.Pop();
|
||||
obj->IterateBody(this); // visits each pointer field
|
||||
}
|
||||
}
|
||||
void Scavenger::VisitPointer(Object** slot) {
|
||||
HeapObject obj = HeapObject::cast(*slot);
|
||||
if (Heap::InFromSpace(obj)) {
|
||||
HeapObject target = EvacuateObject(obj);
|
||||
*slot = target;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Generational tweak
|
||||
```c
|
||||
// Young gen uses Cheney; old gen uses mark-sweep.
|
||||
// Promotion: if object survives N scavenges, copy to old-gen instead of to-space.
|
||||
if (age(obj) >= PROMOTION_THRESHOLD) dst = old_gen_alloc(sz);
|
||||
else dst = (char*)to_space + free_;
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Short-lived allocation 多 | Cheney (semi-space) — fast bump alloc |
|
||||
| Large heap, low live ratio | Cheney 우수 (cost ∝ live, not heap) |
|
||||
| Mostly-live mature data | Mark-sweep / mark-compact |
|
||||
| Real-time constraints | Incremental / concurrent GC (Shenandoah, ZGC) |
|
||||
| Memory tight (mobile) | Mark-sweep (no 2× overhead) |
|
||||
|
||||
**기본값**: Young generation 에 Cheney, old generation 에 mark-compact (generational hypothesis).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Garbage Collection]] · [[Memory Management]]
|
||||
- 변형: [[Mark-Sweep]]
|
||||
- 응용: [[V8 Engine]] · [[Nodejs]]
|
||||
- Adjacent: [[Write Barrier]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: GC 설명, runtime internals 분석, language implementation 설계 시.
|
||||
**언제 X**: Application-level memory tuning (use language-specific profiler 대신).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Naive recursive copy**: stack overflow 가능 — Cheney 의 queue 방식 사용.
|
||||
- **Forgetting forward check**: 동일 object 두 번 copy → 데이터 corrupt.
|
||||
- **Pointer 누락**: stack/register/global root scan 빠짐 → dangling pointer.
|
||||
- **Pinning ignored**: native pointer 가 from-space object 가리키는 동안 GC → crash.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Cheney 1970 CACM paper, V8/SpiderMonkey source).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Cheney GC algorithm 의 BFS copy + V8 scavenger 패턴 |
|
||||
@@ -0,0 +1,164 @@
|
||||
---
|
||||
id: wiki-2026-0508-chrome-v8-heap-analysis
|
||||
title: Chrome V8 Heap Analysis
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [V8 Heap Snapshot, Chrome DevTools Memory, Heap Profiler]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [v8, chrome, heap, debugging, performance]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: javascript
|
||||
framework: chrome-devtools
|
||||
---
|
||||
|
||||
# Chrome V8 Heap Analysis
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 heap snapshot 의 retain path"**. 매 V8 의 mark-sweep + generational GC 의 internal state 의 DevTools Memory tab 을 통한 introspection 의 production 의 leak 의 root cause 의 identification 의 enable. 매 2026 년 의 Chrome 132+ 의 trace-based + sampling allocator 의 < 5% overhead 의 production profiling 의 standard.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Snapshot 종류
|
||||
- **Heap snapshot**: 매 모든 reachable object 의 graph 의 capture. 매 retainers 의 trace.
|
||||
- **Allocation timeline**: 매 시간 에 따라 allocate 된 object 의 추적. 매 churn 의 detection.
|
||||
- **Allocation sampling**: 매 lightweight (5% 이하 overhead). 매 production 의 OK.
|
||||
|
||||
### 매 V8 GC structure
|
||||
- **Young generation (Scavenger)**: 매 fast minor GC. 매 semi-space copying.
|
||||
- **Old generation (Mark-Sweep-Compact)**: 매 incremental mark + concurrent sweep.
|
||||
- **Code space, Map space, Large object space**: 매 separate region.
|
||||
|
||||
### 매 응용
|
||||
1. Memory leak hunt — DOM detached node 의 detection.
|
||||
2. Bundle size 의 runtime impact analysis.
|
||||
3. Closure-induced retention 의 audit.
|
||||
4. Listener leak 의 trace.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Programmatic snapshot (Node.js / Electron)
|
||||
```javascript
|
||||
const v8 = require('v8');
|
||||
const fs = require('fs');
|
||||
|
||||
function takeHeapSnapshot(label) {
|
||||
const path = `./heap-${label}-${Date.now()}.heapsnapshot`;
|
||||
const stream = v8.getHeapSnapshot();
|
||||
stream.pipe(fs.createWriteStream(path));
|
||||
return path;
|
||||
}
|
||||
|
||||
// Usage: take 3 snapshots, compare in DevTools
|
||||
takeHeapSnapshot('baseline');
|
||||
runWorkload();
|
||||
global.gc?.();
|
||||
takeHeapSnapshot('after-gc');
|
||||
```
|
||||
|
||||
### Detached DOM detection
|
||||
```javascript
|
||||
// In Console / Snapshot Comparison view
|
||||
// Filter by "Detached HTMLDivElement"
|
||||
// → retainer chain shows the closure / array holding it
|
||||
|
||||
class LeakyComponent {
|
||||
constructor() {
|
||||
this.handlers = [];
|
||||
document.addEventListener('scroll', this.onScroll); // leak: never removed
|
||||
}
|
||||
onScroll = () => { /* ... */ }
|
||||
}
|
||||
// Fix: store bound ref, removeEventListener in destroy()
|
||||
```
|
||||
|
||||
### CDP (Chrome DevTools Protocol) automation
|
||||
```javascript
|
||||
const CDP = require('chrome-remote-interface');
|
||||
|
||||
async function profileHeap() {
|
||||
const client = await CDP();
|
||||
const { HeapProfiler } = client;
|
||||
await HeapProfiler.enable();
|
||||
await HeapProfiler.collectGarbage();
|
||||
const chunks = [];
|
||||
HeapProfiler.on('addHeapSnapshotChunk', ({ chunk }) => chunks.push(chunk));
|
||||
await HeapProfiler.takeHeapSnapshot({ reportProgress: false });
|
||||
return chunks.join('');
|
||||
}
|
||||
```
|
||||
|
||||
### Sampling allocation profiler
|
||||
```javascript
|
||||
// V8 11+, ~512KB sample interval
|
||||
const profiler = require('v8-profiler-next');
|
||||
profiler.startSamplingHeapProfiler(512 * 1024, 64);
|
||||
// ... workload ...
|
||||
const profile = profiler.stopSamplingHeapProfiler();
|
||||
fs.writeFileSync('alloc.heapprofile', JSON.stringify(profile));
|
||||
```
|
||||
|
||||
### --inspect + automated diff
|
||||
```bash
|
||||
node --inspect=0.0.0.0:9229 server.js
|
||||
# Connect Chrome DevTools → Memory → take snapshot
|
||||
# Run load test → take 2nd snapshot
|
||||
# Comparison view → filter "Delta > 0" + sort by Retained Size
|
||||
```
|
||||
|
||||
### Constructor filter (find specific class instances)
|
||||
```javascript
|
||||
// In DevTools heap viewer
|
||||
// class: SomeBigBuffer → see all live instances + retainers
|
||||
// Common pattern: a Map / Set holding stale references
|
||||
```
|
||||
|
||||
### --max-old-space-size tuning
|
||||
```bash
|
||||
node --max-old-space-size=4096 --expose-gc app.js
|
||||
# or for Chrome:
|
||||
chrome --js-flags="--max-old-space-size=8192"
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Production leak (live) | Sampling allocation profiler (low overhead) |
|
||||
| Dev / staging deep dive | Full heap snapshot diff (3-snapshot technique) |
|
||||
| Allocation hotspot | Allocation timeline |
|
||||
| Specific class instances | Constructor filter |
|
||||
| CI regression check | Programmatic `v8.getHeapSnapshot()` + threshold |
|
||||
|
||||
**기본값**: 매 3-snapshot technique (baseline → workload → after-gc → diff).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[V8 Engine]] · [[Chrome DevTools Memory Profiling|Chrome DevTools]]
|
||||
- 변형: [[Electron V8 Memory Cage]]
|
||||
- 응용: [[Memory Leak Detection]] · [[Performance Optimization]]
|
||||
- Adjacent: [[Garbage Collection]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 leak 의 reproducibility 의 OK 의 case. 매 retainer chain 의 interpretation 의 LLM 의 강점.
|
||||
**언제 X**: 매 production 의 large heap (> 4GB) 의 snapshot 의 capture 의 비용 (multi-second pause).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Snapshot before GC X**: 매 항상 `--expose-gc` + `global.gc()` 후 snapshot. 매 noise 의 reduction.
|
||||
- **Single snapshot 의존**: 매 항상 diff. 매 absolute size 의 less informative.
|
||||
- **Closures의 underestimate**: 매 arrow function 의 lexical scope 의 모든 outer var 의 retain.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (V8 docs, Chrome DevTools docs, Node.js v8 module).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — V8 heap snapshot / leak hunting workflow |
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
id: wiki-2026-0508-code-obfuscation
|
||||
title: Code Obfuscation
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Obfuscation, Anti-Reverse Engineering]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, reverse-engineering, drm, javascript]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: JavaScript/C++
|
||||
framework: obfuscator.io/LLVM-Obfuscator
|
||||
---
|
||||
|
||||
# Code Obfuscation
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 reverse-engineering cost 의 raise — semantic 보존하면서 readability 파괴"**. Crypto 처럼 secrecy 가 아닌 cost-shifting — determined attacker 는 매 결국 풀 수 있음. 매 modern usage: anti-piracy, anti-cheating, license validation, 매 LLM-based deobfuscation 의 등장으로 의미 retreat.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 layer
|
||||
- **Lexical**: rename identifier (`x_a1b2c3`).
|
||||
- **Control flow**: opaque predicate, control-flow flattening.
|
||||
- **Data**: string encryption, constant unfolding.
|
||||
- **Anti-analysis**: anti-debug, VM detection, integrity check.
|
||||
- **Virtualization**: custom VM bytecode (VMProtect, Themida).
|
||||
|
||||
### 매 trade-off
|
||||
- Performance: 2-10× slowdown (virtualization 시).
|
||||
- Size: 2-5× binary bloat.
|
||||
- Stability: false positive 가능 (anti-debug).
|
||||
- Security: 매 cost-raise 만 — break 시간을 hours → weeks 로.
|
||||
|
||||
### 매 응용
|
||||
1. JavaScript bundle (anti-scraping).
|
||||
2. Mobile app DRM, license check.
|
||||
3. Game anti-cheat (e.g., VAC, EAC).
|
||||
4. Malware (defensive obfuscation).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### String encryption
|
||||
```javascript
|
||||
// Before
|
||||
const KEY = "secret-api-key";
|
||||
|
||||
// After
|
||||
const _0xa1b2 = ['c2VjcmV0', 'LWFwaQ==', 'LWtleQ=='];
|
||||
const _0xc3d4 = (i) => atob(_0xa1b2[i]);
|
||||
const KEY = _0xc3d4(0) + _0xc3d4(1) + _0xc3d4(2);
|
||||
```
|
||||
|
||||
### Control-flow flattening
|
||||
```c
|
||||
// Before: linear flow
|
||||
void f() { a(); b(); c(); }
|
||||
|
||||
// After: dispatcher loop
|
||||
void f_obf() {
|
||||
int state = 0;
|
||||
while (state != -1) {
|
||||
switch (state) {
|
||||
case 0: a(); state = 7; break;
|
||||
case 7: b(); state = 3; break;
|
||||
case 3: c(); state = -1; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Opaque predicate
|
||||
```cpp
|
||||
// Always true at runtime, hard to determine statically
|
||||
auto opaque = [](int x) { return (x*x*x - x) % 3 == 0; }; // always true for any int
|
||||
if (opaque(rand())) real_logic();
|
||||
else fake_branch(); // dead but appears live to disassembler
|
||||
```
|
||||
|
||||
### Identifier mangling (terser)
|
||||
```javascript
|
||||
// terser config
|
||||
{
|
||||
mangle: {
|
||||
toplevel: true,
|
||||
properties: { regex: /^_/ }
|
||||
},
|
||||
compress: { passes: 3, dead_code: true }
|
||||
}
|
||||
```
|
||||
|
||||
### Anti-debug (browser)
|
||||
```javascript
|
||||
setInterval(() => {
|
||||
const t = performance.now();
|
||||
debugger; // pauses if devtools open
|
||||
if (performance.now() - t > 100) {
|
||||
// devtools detected
|
||||
location.href = 'about:blank';
|
||||
}
|
||||
}, 1000);
|
||||
```
|
||||
|
||||
### LLVM IR pass (obfuscator-llvm style)
|
||||
```cpp
|
||||
struct StringObfPass : PassInfoMixin<StringObfPass> {
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager&) {
|
||||
for (auto &GV : M.globals()) {
|
||||
if (auto *CDA = dyn_cast<ConstantDataArray>(GV.getInitializer())) {
|
||||
if (CDA->isString()) xor_encrypt(GV);
|
||||
}
|
||||
}
|
||||
return PreservedAnalyses::none();
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Web bundle anti-scraping | terser + javascript-obfuscator |
|
||||
| Native binary (commercial) | VMProtect / Themida |
|
||||
| Open-source w/ embedded secret | DON'T — use server-side proxy |
|
||||
| Game anti-cheat | Kernel driver + virtualization |
|
||||
| Mobile DRM | Hardware-backed (TEE, SEP) — obfuscation 보조 |
|
||||
|
||||
**기본값**: Don't obfuscate — secrets belong server-side. Necessary 시 매 layered defense.
|
||||
|
||||
## 🔗 Graph
|
||||
- 응용: [[Malware Analysis]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Defense-in-depth context, malware analysis 학습, anti-tamper design.
|
||||
**언제 X**: Hiding actual secrets — broken by definition. 매 server-side 가 답.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Security through obscurity (alone)**: 매 always falls.
|
||||
- **Embedding API key in client**: obfuscation 으로도 매 보호 불가.
|
||||
- **Custom crypto**: roll-your-own → obfuscation 보다 매 weaker.
|
||||
- **Performance ignored**: 10× slowdown 으로 UX 망침.
|
||||
- **No update path**: 매 break 되면 매 fresh release 필요 — automation 필수.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Collberg taxonomy, obfuscator-llvm, javascript-obfuscator).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — obfuscation taxonomy + JS/LLVM patterns |
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
id: wiki-2026-0508-code-stylometry-코드-문체론
|
||||
title: Code Stylometry (코드 문체론)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Authorship Attribution, Code Fingerprinting, Programmer Identification]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, ml, forensics, privacy]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Python
|
||||
framework: scikit-learn/transformers
|
||||
---
|
||||
|
||||
# Code Stylometry (코드 문체론)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 코드 작성자를 매 stylistic feature 로 식별하는 ML 기법"**. Caliskan et al. 2015 (USENIX) 가 random forest 로 250 명 중 94% 식별. 매 modern era — CodeBERT/StarCoder embedding 기반 분류기로 매 더 강력해짐. Privacy 위협 (anonymous contributor de-anon) ↔ defensive utility (malware attribution, plagiarism detection) 의 양날.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 feature class
|
||||
- **Lexical**: identifier naming (camelCase vs snake_case), keyword frequency.
|
||||
- **Layout**: indentation, brace style, line length.
|
||||
- **Syntactic**: AST node distribution, depth, n-gram of node types.
|
||||
- **Idiomatic**: preferred construct (`for` vs `map`, ternary vs if).
|
||||
- **Embedding-based**: CodeBERT/StarCoder hidden states (2024+).
|
||||
|
||||
### 매 attack scenario
|
||||
- De-anonymizing GitHub anonymous account.
|
||||
- Linking malware author across samples.
|
||||
- Plagiarism detection in coursework.
|
||||
- Insider threat attribution.
|
||||
|
||||
### 매 응용
|
||||
1. Forensic attribution (FBI/Interpol cases).
|
||||
2. Academic integrity (MOSS, JPlag).
|
||||
3. Bug-injection-source detection (xz-style supply chain).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Layout features
|
||||
```python
|
||||
import re
|
||||
def layout_features(src: str) -> dict:
|
||||
lines = src.split('\n')
|
||||
return {
|
||||
'avg_line_len': sum(len(l) for l in lines) / max(len(lines), 1),
|
||||
'tab_ratio': sum(l.startswith('\t') for l in lines) / max(len(lines), 1),
|
||||
'blank_ratio': sum(not l.strip() for l in lines) / max(len(lines), 1),
|
||||
'snake_ratio': len(re.findall(r'\b[a-z]+_[a-z]+\b', src)),
|
||||
'camel_ratio': len(re.findall(r'\b[a-z]+[A-Z][a-z]+\b', src)),
|
||||
}
|
||||
```
|
||||
|
||||
### AST n-gram (Python)
|
||||
```python
|
||||
import ast
|
||||
from collections import Counter
|
||||
|
||||
def ast_ngrams(src: str, n=3):
|
||||
tree = ast.parse(src)
|
||||
seq = [type(node).__name__ for node in ast.walk(tree)]
|
||||
return Counter(tuple(seq[i:i+n]) for i in range(len(seq)-n+1))
|
||||
```
|
||||
|
||||
### Random forest classifier (Caliskan-style)
|
||||
```python
|
||||
from sklearn.ensemble import RandomForestClassifier
|
||||
from sklearn.feature_extraction import DictVectorizer
|
||||
|
||||
vec = DictVectorizer(sparse=False)
|
||||
X = vec.fit_transform([extract_all_features(s) for s in samples])
|
||||
clf = RandomForestClassifier(n_estimators=300, max_depth=20)
|
||||
clf.fit(X, authors)
|
||||
print(clf.score(X_test, y_test)) # ~90%+ on 100-author corpus
|
||||
```
|
||||
|
||||
### CodeBERT embedding classifier (2024+)
|
||||
```python
|
||||
from transformers import AutoTokenizer, AutoModel
|
||||
import torch
|
||||
|
||||
tok = AutoTokenizer.from_pretrained('microsoft/codebert-base')
|
||||
model = AutoModel.from_pretrained('microsoft/codebert-base').eval()
|
||||
|
||||
def embed(src: str) -> torch.Tensor:
|
||||
inp = tok(src, truncation=True, max_length=512, return_tensors='pt')
|
||||
with torch.no_grad():
|
||||
out = model(**inp).last_hidden_state[:, 0] # CLS
|
||||
return out.squeeze()
|
||||
|
||||
# Then train linear classifier on embeddings
|
||||
```
|
||||
|
||||
### Defensive: code anonymizer
|
||||
```python
|
||||
# Normalize to defeat stylometry
|
||||
import black, autopep8
|
||||
def anonymize(src: str) -> str:
|
||||
src = black.format_str(src, mode=black.Mode()) # uniform layout
|
||||
# rename identifiers via AST transform
|
||||
# replace idiosyncratic constructs with canonical form
|
||||
return src
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Small corpus (<50 authors) | RF on hand-crafted features |
|
||||
| Large corpus, deep features | CodeBERT/StarCoder embedding + classifier |
|
||||
| Defending privacy | Black/Prettier + identifier normalization |
|
||||
| Adversarial robust attack | Limited — formatting tools 매 defeat 대부분 |
|
||||
| Cross-language | Embedding-based 만 가능 |
|
||||
|
||||
**기본값**: 매 RF + AST n-gram 으로 baseline. Embedding 으로 boost.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Authorship Attribution]]
|
||||
- 응용: [[Supply Chain Security]]
|
||||
- Adjacent: [[Code Obfuscation]] · [[AST]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Forensic context, plagiarism check, OSS contributor analysis.
|
||||
**언제 X**: Identifying anonymous whistleblower — ethical 매 거부.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Single-feature reliance**: layout 만 → autoformatter 로 매 trivial defeat.
|
||||
- **Ignoring base rate**: low base rate = high false positive rate (Bonferroni).
|
||||
- **Author-set assumption**: open-world (unknown author) ≠ closed-world.
|
||||
- **Privacy ignored**: deploying on anonymous code 매 ethical review 없이.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Caliskan USENIX 2015, Abuhamad 2018, CodeBERT papers).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — stylometry features + RF/CodeBERT pipelines |
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
id: wiki-2026-0508-code-property-graph
|
||||
title: Code Property Graph
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [CPG, Code Property Graphs, Joern CPG]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, sast, cpg, static-analysis]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: scala
|
||||
framework: joern
|
||||
---
|
||||
|
||||
# Code Property Graph
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 CPG 의 의미: 매 AST + CFG + PDG 의 매 single graph representation"**. 매 Yamaguchi et al. (2014) 가 매 IEEE S&P 의 매 propose, 매 Joern 의 매 implement. 매 2026 modern SAST (Joern, Qwiet AI/ShiftLeft, CodeQL의 dataflow) 의 매 backbone.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 3 layer
|
||||
- **AST** (Abstract Syntax Tree): 매 syntactic structure
|
||||
- **CFG** (Control Flow Graph): 매 execution order, branches
|
||||
- **PDG** (Program Dependency Graph): 매 data + control dependencies
|
||||
|
||||
### 매 single graph
|
||||
- 매 node = AST node
|
||||
- 매 edge = AST parent / CFG next / PDG dataflow / call edge
|
||||
- 매 query 의 graph traversal 로 매 vulnerability pattern 감지
|
||||
|
||||
### 매 query language
|
||||
- **Joern**: Scala-based DSL (Gremlin-like)
|
||||
- **CodeQL**: declarative QL language (similar concept)
|
||||
- **Semgrep**: 매 simpler (AST-only), 매 not full CPG
|
||||
|
||||
### 매 응용
|
||||
1. 매 SAST: 매 SQLi/XSS/RCE pattern 의 매 detection.
|
||||
2. 매 audit: 매 sensitive sink (exec, eval) 의 매 tainted source 까지 trace.
|
||||
3. 매 academic research: 매 vulnerability mining (CVE 의 retroactive find).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Joern 의 매 install + import
|
||||
```bash
|
||||
# 2026 Joern v4
|
||||
curl -L https://github.com/joernio/joern/releases/latest/download/joern-install.sh | sh
|
||||
joern --import src/
|
||||
|
||||
joern> importCode("path/to/project")
|
||||
joern> cpg.method.l
|
||||
```
|
||||
|
||||
### 매 SQLi pattern detection
|
||||
```scala
|
||||
// Joern Scala query: 매 user input 의 SQL 실행 까지 도달
|
||||
cpg.method.name("query|execute")
|
||||
.parameter
|
||||
.reachableBy(cpg.method.name("getParameter|req\\.body").ast)
|
||||
.l
|
||||
```
|
||||
|
||||
### 매 hardcoded secret detection
|
||||
```scala
|
||||
cpg.literal
|
||||
.code("\"[A-Za-z0-9+/]{32,}\"")
|
||||
.filter(_.method.name != "test")
|
||||
.l
|
||||
```
|
||||
|
||||
### CodeQL 의 매 taint tracking (similar)
|
||||
```ql
|
||||
import javascript
|
||||
|
||||
class Configuration extends TaintTracking::Configuration {
|
||||
Configuration() { this = "UserInputToEval" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source instanceof RemoteFlowSource
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(CallExpr c | c.getCalleeName() = "eval" |
|
||||
sink.asExpr() = c.getArgument(0))
|
||||
}
|
||||
}
|
||||
|
||||
from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where cfg.hasFlowPath(source, sink)
|
||||
select sink, source, sink, "Tainted eval"
|
||||
```
|
||||
|
||||
### 매 custom 매 sink 정의
|
||||
```scala
|
||||
val customSinks = cpg.call.name("dangerouslySetInnerHTML|innerHTML")
|
||||
val customSources = cpg.call.name("fetch|axios.get").argument(1)
|
||||
|
||||
customSinks.reachableBy(customSources).l
|
||||
```
|
||||
|
||||
### 매 CPG 의 매 export (for visualization)
|
||||
```scala
|
||||
joern> cpg.runScript("export-cpg.sc")
|
||||
// 매 GraphML / DOT / Neo4j 로 export
|
||||
```
|
||||
|
||||
### 매 CI integration (Joern Scan)
|
||||
```yaml
|
||||
# .github/workflows/joern.yml
|
||||
- name: Joern Scan
|
||||
run: |
|
||||
joern-scan --src ./src --output joern-report.json
|
||||
jq '.findings[] | select(.severity=="HIGH")' joern-report.json
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Quick rule-based scan | 매 Semgrep (syntactic, fast) |
|
||||
| Deep dataflow analysis | 매 Joern / CodeQL (CPG-based) |
|
||||
| GitHub-native | 매 CodeQL (Advanced Security) |
|
||||
| Multi-language audit | 매 Joern (C/C++/Java/Python/JS/PHP) |
|
||||
| Custom vuln mining | 매 Joern Scala script |
|
||||
|
||||
**기본값**: 매 Semgrep (매 quick CI gate) + 매 CodeQL (매 deep weekly audit).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[SAST]] · [[Static Analysis]]
|
||||
- 변형: [[AST]]
|
||||
- 응용: [[Joern]] · [[CodeQL]]
|
||||
- Adjacent: [[보안 및 시스템 신뢰성 표준|DAST]] · [[SCA_Fundamentals|SCA]] · [[DevSecOps Framework]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 Joern Scala query 의 draft, 매 CPG result 의 false positive triage, 매 custom sink/source 의 suggestion.
|
||||
**언제 X**: 매 LLM 의 self 의 vulnerability detection — 매 hallucination risk. 매 CPG-based 결과 가 매 ground truth.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **CPG 의 build 만 하고 의 query 의 X**: 매 graph 의 사용 안함.
|
||||
- **매 source / sink 의 매 default 만**: 매 framework-specific (Express, Spring) 의 매 manual 정의 필요.
|
||||
- **매 Joern 의 huge codebase 의 timeout**: 매 incremental import / 매 module 별 split.
|
||||
- **매 alert fatigue**: 매 severity tuning 없이 매 모든 finding raise.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Yamaguchi et al. 2014 IEEE S&P; Joern docs; CodeQL docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — CPG full content |
|
||||
@@ -0,0 +1,146 @@
|
||||
---
|
||||
id: wiki-2026-0508-cognitive-load
|
||||
title: Cognitive Load
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Mental Load, Working Memory Pressure, Code Complexity Tax]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [engineering, design, code-quality, devex]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: any
|
||||
framework: software-engineering
|
||||
---
|
||||
|
||||
# Cognitive Load
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 working memory 에 동시에 매 잡고 있어야 하는 정보의 양"**. Sweller 의 cognitive load theory (1988) 에 기반 — intrinsic, extraneous, germane 의 3-tier. 매 modern software design 의 first-principle metric — 작은 cognitive load 가 매 maintainable code 를 결정.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 3 종류
|
||||
- **Intrinsic**: 문제 자체의 본질적 복잡도 (e.g., distributed consensus).
|
||||
- **Extraneous**: 표현/도구 가 만드는 인위적 복잡도 (bad naming, deep nesting).
|
||||
- **Germane**: schema 형성 과정 (learning) — useful load.
|
||||
|
||||
### 매 7±2 rule
|
||||
- Working memory 는 약 4-7 chunk 만 동시 처리 (Miller 1956, refined Cowan 2001).
|
||||
- Code 가 이 한계 넘으면 → bug, slow review, onboarding 지연.
|
||||
|
||||
### 매 응용
|
||||
1. Function 의 line / parameter 제한 (small functions).
|
||||
2. Module boundary 설계 — high cohesion, low coupling.
|
||||
3. PR size 제한 (200-400 line max).
|
||||
4. Naming convention — domain language 사용.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Guard clause 로 nesting 줄임
|
||||
```python
|
||||
# BAD: deep nesting (high extraneous load)
|
||||
def process(user):
|
||||
if user is not None:
|
||||
if user.is_active:
|
||||
if user.has_permission('write'):
|
||||
return do_work(user)
|
||||
return None
|
||||
|
||||
# GOOD: early return
|
||||
def process(user):
|
||||
if user is None: return None
|
||||
if not user.is_active: return None
|
||||
if not user.has_permission('write'): return None
|
||||
return do_work(user)
|
||||
```
|
||||
|
||||
### Extract domain primitive
|
||||
```typescript
|
||||
// BAD: primitive obsession — caller must remember semantics
|
||||
function transfer(from: string, to: string, amount: number, currency: string) {}
|
||||
|
||||
// GOOD: types carry semantics
|
||||
type AccountId = string & { __brand: 'AccountId' };
|
||||
type Money = { amount: bigint; currency: Currency };
|
||||
function transfer(from: AccountId, to: AccountId, money: Money) {}
|
||||
```
|
||||
|
||||
### 매 colocation
|
||||
```tsx
|
||||
// BAD: scattered — must context-switch
|
||||
// styles.css, validation.ts, component.tsx, types.ts
|
||||
|
||||
// GOOD: single-file feature unit (Astro/Svelte/RSC era)
|
||||
export function Form() {
|
||||
const validate = (v: string) => v.length > 0;
|
||||
return <input onBlur={e => validate(e.target.value)} />;
|
||||
}
|
||||
```
|
||||
|
||||
### Boundary objects
|
||||
```python
|
||||
# Each layer translates — caller doesn't need to know inner schema
|
||||
class UserDTO: # external API shape
|
||||
...
|
||||
class User: # domain entity
|
||||
...
|
||||
class UserRow: # DB schema
|
||||
...
|
||||
def to_domain(dto: UserDTO) -> User: ...
|
||||
def to_row(user: User) -> UserRow: ...
|
||||
```
|
||||
|
||||
### Team Topologies pattern
|
||||
```yaml
|
||||
# Stream-aligned team owns a single bounded context
|
||||
# Platform team provides self-service infra
|
||||
# Goal: each team's cognitive load fits one team's working memory
|
||||
team: payments
|
||||
owns: [PaymentService, RefundService, payment-db]
|
||||
depends_on:
|
||||
platform: [k8s-cluster, observability]
|
||||
enabling: []
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Function > 50 lines | Extract sub-functions or strategy |
|
||||
| Class > 7 public methods | Split by responsibility |
|
||||
| Team owns > 1 product area | Reorg per Team Topologies |
|
||||
| Domain logic mixed w/ infra | Hexagonal / Clean Architecture |
|
||||
| Onboarding > 2 weeks | Reduce coupling, write decision records |
|
||||
|
||||
**기본값**: Optimize for reader, not writer — 매 reduce extraneous, accept intrinsic.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Cognitive Psychology]]
|
||||
- 응용: [[Team Topologies]] · [[Hexagonal Architecture]] · [[Clean Code]]
|
||||
- Adjacent: [[Working Memory]] · [[Code Smell]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Code review, refactoring decision, team structure 설계, PR size 판단.
|
||||
**언제 X**: Pure performance optimization (different metric).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Cleverness 자랑**: dense one-liner, clever bitwise — high extraneous.
|
||||
- **God object**: 30+ method class — exceeds chunking capacity.
|
||||
- **Magic constants**: `if x > 86400` 대신 `SECONDS_PER_DAY`.
|
||||
- **Implicit context**: global mutable state — reader 가 매 trace 해야 함.
|
||||
- **Premature abstraction**: framework-itis — abstraction 이 intrinsic 아닌데 추가됨.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Sweller 1988, Skelton & Pais 2019 Team Topologies).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — cognitive load theory + practical refactoring patterns |
|
||||
@@ -0,0 +1,143 @@
|
||||
---
|
||||
id: wiki-2026-0508-commit-history
|
||||
title: Commit History
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Git Log, Commit Log, Git History]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [git, vcs, history]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: Bash
|
||||
framework: Git
|
||||
---
|
||||
|
||||
# Commit History
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 commit 은 미래의 자기 자신을 위한 편지다."**. Commit history 는 매 codebase 의 시간축 — bisect, blame, revert, audit 의 매 기반. 2026 의 표준은 Conventional Commits + signed commits (Sigstore gitsign / SSH key) + linear history (rebase or squash-merge).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 좋은 history 의 특징
|
||||
- **Atomic**: 매 한 commit = 한 logical change.
|
||||
- **Descriptive subject**: 50자, imperative — "Fix login race".
|
||||
- **Body explains why**: 매 what 은 diff 가 보여줌 — why 가 commit 의 가치.
|
||||
- **Linkable**: issue/PR ref.
|
||||
- **Signed**: GPG / SSH / gitsign — supply-chain integrity.
|
||||
- **Linear or trunked**: bisect 친화적.
|
||||
|
||||
### 매 Conventional Commits
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
<body>
|
||||
|
||||
<footer>
|
||||
```
|
||||
- type: feat, fix, refactor, perf, test, docs, chore, build, ci.
|
||||
- 매 BREAKING CHANGE: footer.
|
||||
|
||||
### 매 응용
|
||||
1. Bisect — 매 regression commit 이분 탐색.
|
||||
2. Blame — 매 line author/intent 추적.
|
||||
3. Cherry-pick — hotfix backport.
|
||||
4. Revert — production rollback.
|
||||
5. Changelog — automated (release-please, semantic-release).
|
||||
6. Audit — compliance, post-mortem.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### git bisect 자동화
|
||||
```bash
|
||||
git bisect start
|
||||
git bisect bad HEAD
|
||||
git bisect good v1.2.0
|
||||
git bisect run npm test # 매 each step automated
|
||||
git bisect reset
|
||||
```
|
||||
|
||||
### Signed commit (gitsign / Sigstore)
|
||||
```bash
|
||||
# 매 keyless OIDC sign
|
||||
git config --global gpg.x509.program gitsign
|
||||
git config --global gpg.format x509
|
||||
git config --global commit.gpgsign true
|
||||
git commit -m "feat: signed via gitsign"
|
||||
git verify-commit HEAD
|
||||
```
|
||||
|
||||
### Conventional Commits + commitlint
|
||||
```js
|
||||
// commitlint.config.js
|
||||
export default {
|
||||
extends: ['@commitlint/config-conventional'],
|
||||
rules: { 'subject-max-length': [2, 'always', 72] },
|
||||
};
|
||||
```
|
||||
|
||||
### Interactive rebase cleanup (before push)
|
||||
```bash
|
||||
git rebase -i origin/main # 매 squash, reword, reorder
|
||||
```
|
||||
|
||||
### git log advanced query
|
||||
```bash
|
||||
# 매 작가별 last week
|
||||
git log --since='1 week ago' --pretty=format:'%h %an %s'
|
||||
# 매 specific file 의 changes (move 추적)
|
||||
git log --follow -p src/auth.ts
|
||||
# 매 grep in patches
|
||||
git log -G 'eval\(' --oneline
|
||||
```
|
||||
|
||||
### release-please automation
|
||||
```yaml
|
||||
- uses: googleapis/release-please-action@v4
|
||||
with: { release-type: node }
|
||||
# 매 Conventional Commits → CHANGELOG.md + version bump PR
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Feature branch | rebase + squash-merge |
|
||||
| Long-running branch | merge commit (주의) |
|
||||
| Hotfix | cherry-pick to release |
|
||||
| Breaking change | BREAKING CHANGE footer + major bump |
|
||||
| Compliance | signed commits + protected branch |
|
||||
|
||||
**기본값**: 매 Conventional Commits + signed + squash-merge.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Source-Control]] · [[Version_Control_Systems]]
|
||||
- 변형: [[버전_관리_시스템_VCS]]
|
||||
- 응용: [[CI_CD_Pipeline]] · [[Husky]]
|
||||
- Adjacent: [[Code_Property_Graph]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: commit message 생성, PR description, changelog draft, post-mortem timeline 정리.
|
||||
**언제 X**: 매 actual git operations — automation 이 deterministic.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **"WIP" commit**: 매 squash 전 cleanup.
|
||||
- **거대 commit**: 매 review 불가 — split.
|
||||
- **Force-push to shared branch**: 매 history rewrite, others lose work.
|
||||
- **Unsigned in regulated**: 매 SOC2/SLSA 위반.
|
||||
- **`git add .` blindly**: 매 secret 유출 위험.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: Conventional Commits 1.0; Sigstore gitsign docs; Git docs.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Conventional Commits + signing + bisect |
|
||||
@@ -0,0 +1,152 @@
|
||||
---
|
||||
id: wiki-2026-0508-concrete-syntax-tree-cst
|
||||
title: Concrete Syntax Tree (CST)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Parse Tree, CST, Lossless Syntax Tree]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [parser, ast, tooling, language-engineering]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Rust/JS
|
||||
framework: tree-sitter/rowan
|
||||
---
|
||||
|
||||
# Concrete Syntax Tree (CST)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 source 의 every token (whitespace, comment 포함) 까지 보존하는 lossless tree"**. AST 가 semantic-only 인 반면 CST 는 매 source 의 round-trip 가능. 매 modern tooling — tree-sitter, rowan (rust-analyzer), Roslyn — 매 CST 위에서 매 IDE feature, refactoring, formatter 를 매 build.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 vs AST
|
||||
- **AST**: semantic node 만 (`if`, `BinaryOp`, etc) — comment, whitespace 버림.
|
||||
- **CST**: 모든 token + trivia 보존 — `source == reprint(cst)`.
|
||||
- CST → AST 의 lowering 가능, 역은 매 lossy.
|
||||
|
||||
### 매 핵심 properties
|
||||
- **Lossless**: print 시 원본 byte-for-byte 복구.
|
||||
- **Error-tolerant**: incomplete/invalid code 도 partial tree.
|
||||
- **Incremental**: edit 시 affected subtree 만 reparse (tree-sitter).
|
||||
- **Untyped or weakly-typed**: 모든 node 가 동질 — typed wrapper 로 navigate.
|
||||
|
||||
### 매 응용
|
||||
1. IDE: syntax highlight, fold, outline, indent.
|
||||
2. Refactoring: rename, extract method (preserve formatting).
|
||||
3. Formatter: prettier, rustfmt — CST 로 layout 결정.
|
||||
4. Linter: tree-sitter queries.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### tree-sitter parsing
|
||||
```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: number = 1;');
|
||||
// Walk
|
||||
const cursor = tree.walk();
|
||||
do { console.log(cursor.nodeType, cursor.startIndex, cursor.endIndex); }
|
||||
while (cursor.gotoNextSibling() || cursor.gotoFirstChild());
|
||||
```
|
||||
|
||||
### tree-sitter query (S-expression)
|
||||
```scheme
|
||||
; Find all function declarations
|
||||
(function_declaration
|
||||
name: (identifier) @func.name
|
||||
parameters: (formal_parameters) @func.params)
|
||||
|
||||
; Find unused imports
|
||||
(import_statement
|
||||
source: (string) @import.source) @import
|
||||
```
|
||||
|
||||
### Incremental edit
|
||||
```javascript
|
||||
const oldTree = parser.parse(oldSrc);
|
||||
const newSrc = oldSrc.slice(0, 10) + 'INSERTED' + oldSrc.slice(10);
|
||||
oldTree.edit({
|
||||
startIndex: 10, oldEndIndex: 10, newEndIndex: 18,
|
||||
startPosition: {row: 0, column: 10},
|
||||
oldEndPosition: {row: 0, column: 10},
|
||||
newEndPosition: {row: 0, column: 18},
|
||||
});
|
||||
const newTree = parser.parse(newSrc, oldTree); // reuses unchanged subtrees
|
||||
```
|
||||
|
||||
### rowan (rust-analyzer) typed wrapper
|
||||
```rust
|
||||
// Untyped GreenNode + typed SyntaxNode wrapper
|
||||
use rowan::{GreenNode, SyntaxNode};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u16)]
|
||||
enum SyntaxKind { L_PAREN, R_PAREN, IDENT, FN_KW, FN_DEF, ROOT, /* ... */ }
|
||||
|
||||
struct FnDef(SyntaxNode<MyLang>);
|
||||
impl FnDef {
|
||||
fn name(&self) -> Option<String> {
|
||||
self.0.children().find(|n| n.kind() == SyntaxKind::IDENT)
|
||||
.map(|n| n.text().to_string())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Lossless rewrite (rename)
|
||||
```rust
|
||||
// Replace token in CST and reprint — preserves comments/whitespace.
|
||||
fn rename(node: &SyntaxNode, old: &str, new: &str) -> String {
|
||||
let mut out = String::new();
|
||||
for tok in node.descendants_with_tokens() {
|
||||
if let Some(t) = tok.as_token() {
|
||||
if t.kind() == SyntaxKind::IDENT && t.text() == old { out.push_str(new); }
|
||||
else { out.push_str(t.text()); }
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Compiler / type checker | AST (semantic 충분) |
|
||||
| IDE / LSP / formatter | CST (lossless 필수) |
|
||||
| Refactoring tool | CST + typed wrapper |
|
||||
| Quick analysis script | tree-sitter query |
|
||||
| New language design | rowan or tree-sitter base |
|
||||
|
||||
**기본값**: User-facing tool 이면 매 CST. Compiler internal pass 면 매 AST.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Parser]]
|
||||
- 변형: [[AST]]
|
||||
- 응용: [[Prettier]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Source-to-source transformation, IDE-grade tooling, codemods.
|
||||
**언제 X**: Pure semantic analysis (AST 만 충분).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Regex on source**: 매 fragile — CST query 사용.
|
||||
- **AST 로 formatter**: comment 손실 — CST 필수.
|
||||
- **Hand-rolled parser**: error recovery 빠짐 — tree-sitter/lark 사용.
|
||||
- **Full reparse on every keystroke**: incremental edit API 사용.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (tree-sitter docs, rust-analyzer rowan, Roslyn architecture).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — CST vs AST + tree-sitter/rowan patterns |
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
id: wiki-2026-0508-continuous-delivery-지속적-제공-cd
|
||||
title: "Continuous Delivery (지속적 제공, CD)"
|
||||
category: 10_Wiki/Topics
|
||||
status: duplicate
|
||||
canonical_id: wiki-2026-0508-continuous-delivery
|
||||
duplicate_of: "[[Continuous Delivery]]"
|
||||
aliases: []
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: redirected
|
||||
tags: [duplicate, cd, devops]
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
---
|
||||
|
||||
# Continuous Delivery (지속적 제공, CD)
|
||||
|
||||
> **이 문서는 [[Continuous Delivery]] 의 중복본입니다.** Canonical 문서로 redirect.
|
||||
|
||||
## 핵심 요약 (Korean specialization)
|
||||
- 매 한국어 title 의 alias — 매 동일 concept (Continuous Delivery)
|
||||
- 매 Korean wiki 검색 entry-point 로만 유지
|
||||
- 매 정식 content 는 [[Continuous Delivery]] 참조
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Continuous Delivery]] (canonical)
|
||||
|
||||
## 🕓 변경 이력
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
id: wiki-2026-0508-continuous-discovery
|
||||
title: Continuous Discovery
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [continuous user research, weekly discovery, Teresa Torres method]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [product, research, discovery, ux]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: process
|
||||
framework: product-discovery
|
||||
---
|
||||
|
||||
# Continuous Discovery
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 continuous discovery 의 의미: 매 매 week 의 매 customer 와 매 conversation, 매 product decision 에 매 feed"**. 매 Teresa Torres 의 *Continuous Discovery Habits* (2021) 가 매 popularize. 매 2026 modern product team 의 매 default — 매 quarterly research → 매 weekly cadence.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Torres 의 trio
|
||||
- **Product manager** + **Designer** + **Engineer** 의 매 함께 discovery
|
||||
- 매 1명만 매 user 와 talk → 매 telephone game
|
||||
- 매 trio 함께 → 매 shared understanding
|
||||
|
||||
### 매 weekly cadence
|
||||
- 매 week 의 매 1+ customer interview
|
||||
- 매 opportunity solution tree 의 매 update
|
||||
- 매 assumption test 의 매 1+ run
|
||||
|
||||
### 매 Opportunity Solution Tree
|
||||
- **Outcome** (top): business outcome (매 retention +5%)
|
||||
- **Opportunities**: 매 customer needs / pain points
|
||||
- **Solutions**: 매 ideas
|
||||
- **Experiments**: 매 assumption tests
|
||||
|
||||
### 매 응용
|
||||
1. 매 PM 의 매 weekly research routine.
|
||||
2. 매 roadmap prioritization 의 매 evidence base.
|
||||
3. 매 PMF (product-market fit) 의 매 ongoing validation.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Opportunity Solution Tree 의 매 markdown
|
||||
```markdown
|
||||
# Outcome: Q2 의 weekly active users +20%
|
||||
|
||||
## Opportunity 1: 매 user 의 매 onboarding 에 confused
|
||||
- Solution 1.1: 매 interactive tutorial
|
||||
- Experiment: 매 prototype A/B test
|
||||
- Solution 1.2: 매 sample data preload
|
||||
- Experiment: 매 5 user 의 unmoderated test
|
||||
|
||||
## Opportunity 2: 매 power user 의 매 keyboard shortcut 의 X
|
||||
- Solution 2.1: 매 cmdK palette
|
||||
- Experiment: 매 beta cohort 측정
|
||||
```
|
||||
|
||||
### Interview 의 매 story-based prompt
|
||||
```
|
||||
매 X 안 됨: "Would you use feature Y?" (매 hypothetical)
|
||||
매 O: "Tell me about the last time you tried to <task>.
|
||||
Walk me through what happened, step by step."
|
||||
```
|
||||
|
||||
### Assumption Mapping
|
||||
```
|
||||
Importance
|
||||
Low ─────────► High
|
||||
┌──────────┬──────────┐
|
||||
Evidence │ Skip │ TEST │
|
||||
Low │ │ FIRST │
|
||||
├──────────┼──────────┤
|
||||
Evidence │ Document│ Build │
|
||||
High │ │ │
|
||||
└──────────┴──────────┘
|
||||
```
|
||||
|
||||
### 매 weekly recurring 의 calendar block
|
||||
```
|
||||
Mon 10am-11am: 매 trio sync (review 의 last week 결과)
|
||||
Wed 2pm-3pm: 매 customer interview slot 1
|
||||
Thu 2pm-3pm: 매 customer interview slot 2
|
||||
Fri 11am-12pm: 매 OST update + experiment plan
|
||||
```
|
||||
|
||||
### Research Repository (Notion / Dovetail / Reduct)
|
||||
```
|
||||
/research
|
||||
/interviews
|
||||
2026-05-08-jane-doe-acme-corp.md
|
||||
2026-05-09-john-smith-beta-inc.md
|
||||
/insights
|
||||
onboarding-confusion-pattern.md
|
||||
/opportunity-solution-tree.md
|
||||
```
|
||||
|
||||
### Continuous Discovery 의 매 metric
|
||||
```python
|
||||
weekly_metrics = {
|
||||
"interviews_conducted": 3, # 매 target: 매 week 1-3
|
||||
"assumptions_tested": 2,
|
||||
"OST_updates": 1,
|
||||
"trio_alignment_score": 4.5, # 매 self-reported 1-5
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Early-stage startup | 매 founder-led, 매 5+ interviews/week |
|
||||
| Growth-stage product | 매 trio cadence, 매 2-3/week |
|
||||
| Enterprise B2B | 매 fewer (1-2/week), 매 deeper (60min) |
|
||||
| 매 dev tool | 매 dogfood + community Discord/Slack |
|
||||
| 매 heavily regulated | 매 IRB-style consent + 매 anonymization |
|
||||
|
||||
**기본값**: 매 weekly trio + 매 minimum 1 interview/week + 매 OST 의 living document.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[Continuous Delivery]] · [[Continuous Integration]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 interview transcript 의 thematic coding, 매 OST 의 draft, 매 assumption 의 listing, 매 research synthesis.
|
||||
**언제 X**: 매 actual customer conversation 의 X (매 LLM persona 의 fake user 의 dangerous). 매 sensitive PII 의 매 raw transcript.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Quarterly research**: 매 too slow, 매 stale by build time.
|
||||
- **PM 만 single-handed**: 매 trio 의 X — 매 designer/eng 의 context loss.
|
||||
- **매 leading question**: "Don't you hate when X?" → 매 yes-bias.
|
||||
- **매 OST 의 set-and-forget**: 매 living document 의 X 인 dead artifact.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Torres, *Continuous Discovery Habits*; Product Talk blog).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Continuous Discovery full content |
|
||||
@@ -0,0 +1,166 @@
|
||||
---
|
||||
id: wiki-2026-0508-data-array-textures
|
||||
title: Data Array Textures
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Texture Array, GL_TEXTURE_2D_ARRAY, WebGL2 Array Texture]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [webgl, gpu, texture, graphics, rendering]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: glsl
|
||||
framework: webgl2
|
||||
---
|
||||
|
||||
# Data Array Textures
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 N 장 의 동일 size texture 의 single bind"**. 매 GL_TEXTURE_2D_ARRAY 의 atlas 의 alternative 의 sub-texel bleed 의 X 의 mipmap-safe 의 layered access 의 enable. 매 2026 년 의 WebGPU 의 default storage 의 voxel terrain, sprite atlas, lookup table 의 standard.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 vs Atlas
|
||||
- **Atlas**: 매 single 2D texture 의 grid. 매 mipmap 의 bleed problem.
|
||||
- **Array texture**: 매 layer 의 independent. 매 mipmap-safe. 매 single bind 의 N draw call 의 1 draw call 의 reduction.
|
||||
|
||||
### 매 제약
|
||||
- 매 모든 layer 의 same size + same format.
|
||||
- 매 max_array_layers (보통 2048) 의 hardware limit.
|
||||
- 매 sampler 의 layer index 의 third coord (z) 로 access.
|
||||
|
||||
### 매 응용
|
||||
1. Voxel/Minecraft-like terrain (block type → layer index).
|
||||
2. Sprite animation (frame → layer).
|
||||
3. LUT (lookup table) batch.
|
||||
4. Instanced material variation.
|
||||
5. ML inference의 batched feature map.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### WebGL2 array texture upload
|
||||
```javascript
|
||||
const gl = canvas.getContext('webgl2');
|
||||
const tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
|
||||
|
||||
const W = 64, H = 64, LAYERS = 16;
|
||||
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, W, H, LAYERS);
|
||||
|
||||
for (let i = 0; i < LAYERS; i++) {
|
||||
const pixels = loadLayer(i); // Uint8Array(W*H*4)
|
||||
gl.texSubImage3D(
|
||||
gl.TEXTURE_2D_ARRAY, 0,
|
||||
0, 0, i, // x, y, layer offset
|
||||
W, H, 1,
|
||||
gl.RGBA, gl.UNSIGNED_BYTE, pixels
|
||||
);
|
||||
}
|
||||
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
```
|
||||
|
||||
### GLSL 300 es sampling
|
||||
```glsl
|
||||
#version 300 es
|
||||
precision highp float;
|
||||
precision highp sampler2DArray;
|
||||
|
||||
uniform sampler2DArray uBlocks;
|
||||
in vec2 vUV;
|
||||
flat in int vBlockType;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = texture(uBlocks, vec3(vUV, float(vBlockType)));
|
||||
}
|
||||
```
|
||||
|
||||
### WebGPU equivalent
|
||||
```javascript
|
||||
const tex = device.createTexture({
|
||||
size: [W, H, LAYERS],
|
||||
format: 'rgba8unorm',
|
||||
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
|
||||
dimension: '2d', // array via depthOrArrayLayers
|
||||
});
|
||||
|
||||
device.queue.writeTexture(
|
||||
{ texture: tex, origin: [0, 0, layer] },
|
||||
pixels,
|
||||
{ bytesPerRow: W * 4 },
|
||||
{ width: W, height: H, depthOrArrayLayers: 1 }
|
||||
);
|
||||
```
|
||||
|
||||
### WGSL sampling
|
||||
```wgsl
|
||||
@group(0) @binding(0) var blocks: texture_2d_array<f32>;
|
||||
@group(0) @binding(1) var samp: sampler;
|
||||
|
||||
@fragment
|
||||
fn fs_main(@location(0) uv: vec2f, @location(1) @interpolate(flat) layer: u32) -> @location(0) vec4f {
|
||||
return textureSample(blocks, samp, uv, layer);
|
||||
}
|
||||
```
|
||||
|
||||
### Three.js DataArrayTexture
|
||||
```javascript
|
||||
import { DataArrayTexture, RGBAFormat, UnsignedByteType } from 'three';
|
||||
|
||||
const data = new Uint8Array(W * H * LAYERS * 4);
|
||||
// fill data...
|
||||
const tex = new DataArrayTexture(data, W, H, LAYERS);
|
||||
tex.format = RGBAFormat;
|
||||
tex.type = UnsignedByteType;
|
||||
tex.needsUpdate = true;
|
||||
material.uniforms.uBlocks.value = tex;
|
||||
```
|
||||
|
||||
### Mipmap generation
|
||||
```javascript
|
||||
gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
|
||||
gl.generateMipmap(gl.TEXTURE_2D_ARRAY);
|
||||
// → each layer mipmapped independently → no atlas-style bleed
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| < 16 unique textures, dynamic | Texture atlas (simple, cached) |
|
||||
| Many same-size layers, mipmap critical | Array texture |
|
||||
| Different sizes / formats | Bindless / texture array of handles (WebGPU) |
|
||||
| Voxel terrain | Array texture (layer = block type) |
|
||||
| Cubemap variant | TextureCubeArray |
|
||||
|
||||
**기본값**: 매 same-size + N > 8 → array texture.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[WebGL 20|WebGL2]] · [[WebGPU]]
|
||||
- 변형: [[Texture Atlas]]
|
||||
- 응용: [[실시간 물리 시뮬레이션 동기화|Real-time Physics Simulation]]
|
||||
- Adjacent: [[Mipmap]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 shader code generation 의 boilerplate 의 GLSL/WGSL 의 sample. 매 LLM 의 layer index 의 binding 의 OK.
|
||||
**언제 X**: 매 driver-specific 의 size limit 의 query 는 runtime 의 `getParameter`. 매 LLM 의 hardcode 의 X.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Mixed sizes의 attempt**: 매 array texture 의 disqualify. 매 atlas 또는 bindless.
|
||||
- **Layer count 의 over 2048**: 매 split 의 multi-array-texture 또는 bindless.
|
||||
- **Mipmap 의 atlas로**: 매 bleed 의 inevitable. 매 array texture 의 fix.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Khronos WebGL2 spec, WebGPU spec, Three.js docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — array texture / WebGL2 + WebGPU usage |
|
||||
@@ -0,0 +1,153 @@
|
||||
---
|
||||
id: wiki-2026-0508-debugger-techniques
|
||||
title: Debugger Techniques
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Debugging, Debug Tooling]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [debugging, devtools, troubleshooting]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: Multi
|
||||
framework: gdb/lldb/Chrome DevTools
|
||||
---
|
||||
|
||||
# Debugger Techniques
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 print 보다 breakpoint 가 빠르고, breakpoint 보다 reverse-debug 이 깊다."**. Debugger techniques 는 breakpoint, watchpoint, conditional, log-point, time-travel, post-mortem (core dump) 의 매 toolkit. 2026 stack: Chrome DevTools (live), VS Code DAP, gdb/lldb, rr (record-replay), Pernosco (cloud time-travel).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Breakpoint Type
|
||||
- **Line**: 매 source line 정지.
|
||||
- **Conditional**: 매 expression true 일 때만.
|
||||
- **Log-point** ("tracepoint"): 매 정지 안하고 log 찍음.
|
||||
- **Function**: 매 fn enter.
|
||||
- **Watchpoint**: 매 memory address change.
|
||||
- **Exception**: 매 throw caught/uncaught.
|
||||
- **DOM**: 매 Chrome — node modification.
|
||||
- **XHR/fetch**: 매 URL pattern.
|
||||
- **Event listener**: 매 click/keydown 등.
|
||||
|
||||
### 매 Time-Travel Debugging
|
||||
- **rr** (Linux): record once, replay backwards/forwards — 매 nondeterministic bug 의 답.
|
||||
- **Pernosco**: rr trace 의 cloud UI — 매 expression 의 모든 변경 이력.
|
||||
- **WinDbg TTD** (Windows).
|
||||
- **Chrome DevTools "Replay panel"** (2025+ experimental).
|
||||
|
||||
### 매 응용
|
||||
1. Heisenbug — 매 conditional + log-point.
|
||||
2. Crash post-mortem — 매 core dump + gdb.
|
||||
3. Performance — 매 sampling + breakpoint.
|
||||
4. Memory leak — 매 heap snapshot diff.
|
||||
5. Distributed — 매 OpenTelemetry trace.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Chrome conditional breakpoint
|
||||
```javascript
|
||||
// 매 in DevTools right-click line → Add conditional breakpoint
|
||||
// expression: user.id === 42 && cart.total > 1000
|
||||
// 또는 logpoint: console.log('cart', cart, 'time', performance.now())
|
||||
```
|
||||
|
||||
### gdb scripted debugging
|
||||
```bash
|
||||
gdb --batch -x debug.gdb ./app core.12345
|
||||
# debug.gdb
|
||||
set pagination off
|
||||
bt full
|
||||
info threads
|
||||
thread apply all bt
|
||||
print *some_struct
|
||||
```
|
||||
|
||||
### lldb Python script
|
||||
```bash
|
||||
(lldb) script
|
||||
>>> frame = lldb.frame
|
||||
>>> for var in frame.variables: print(var.name, var.value)
|
||||
```
|
||||
|
||||
### rr record-replay (Linux)
|
||||
```bash
|
||||
rr record ./buggy_program
|
||||
rr replay
|
||||
# 매 in rr's gdb
|
||||
(rr) reverse-continue
|
||||
(rr) reverse-step
|
||||
(rr) watch -l some_var
|
||||
```
|
||||
|
||||
### Node.js inspector + Chrome
|
||||
```bash
|
||||
node --inspect-brk=0.0.0.0:9229 server.js
|
||||
# 매 chrome://inspect
|
||||
```
|
||||
|
||||
### Python pdb / debugpy
|
||||
```python
|
||||
import pdb; pdb.set_trace() # 매 classic
|
||||
breakpoint() # 매 PEP 553 (python 3.7+)
|
||||
# 매 VS Code remote: debugpy.listen(('0.0.0.0', 5678)); debugpy.wait_for_client()
|
||||
```
|
||||
|
||||
### eBPF dynamic tracing
|
||||
```bash
|
||||
sudo bpftrace -e 'uprobe:./app:malloc { @[ustack] = count(); }'
|
||||
```
|
||||
|
||||
### Conditional log-point pattern
|
||||
```javascript
|
||||
// 매 production-safe lazy log — no perf cost when disabled
|
||||
if (DEBUG) console.log('state', JSON.stringify(state));
|
||||
// 매 better — feature flag gated
|
||||
if (flags.debugCart) logger.debug({ cart, user });
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| Web (Chromium) | DevTools Sources panel |
|
||||
| Node.js | --inspect + DevTools / VS Code |
|
||||
| C/C++ Linux | gdb / lldb + rr |
|
||||
| C/C++ macOS | lldb + Instruments |
|
||||
| Python | debugpy + VS Code |
|
||||
| Heisenbug | rr + Pernosco |
|
||||
| Production crash | core dump + gdb |
|
||||
| Distributed | OTel trace |
|
||||
|
||||
**기본값**: 매 IDE breakpoint → 부족시 rr / TTD.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[중단점 (Breakpoints)]]
|
||||
- 변형: [[동적 런타임 분석 (Dynamic Runtime Analysis)]]
|
||||
- 응용: [[Flame_Graphs]] · [[Logging_and_Error_Handling]]
|
||||
- Adjacent: [[Analyze runtime performance]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: stack trace 해석, log clustering, hypothesis generation, repro script.
|
||||
**언제 X**: 매 step-into 같은 deterministic 작업 — IDE 가 직접.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **printf-only**: 매 build cycle 낭비 — debugger 사용.
|
||||
- **Production breakpoint**: 매 thread freeze — log-point 사용.
|
||||
- **No source map**: 매 minified frame 해독 불가.
|
||||
- **Trust gut without repro**: 매 unreliable repro 면 가설 무한 반복.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: Chrome DevTools docs; gdb manual; rr-project.org; Pernosco docs.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — breakpoint taxonomy + rr/TTD + multi-lang |
|
||||
@@ -0,0 +1,189 @@
|
||||
---
|
||||
id: wiki-2026-0508-deepfake-detection
|
||||
title: Deepfake Detection
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Deepfake Detection, Synthetic Media Detection, AI-Generated Content Detection]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, ml, forensics, deepfake, detection]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Python
|
||||
framework: PyTorch
|
||||
---
|
||||
|
||||
# Deepfake Detection
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 generative model 의 fingerprint 의 수확"**. 2017 FakeApp 의 등장 이후 detection 의 cat-and-mouse race 가 시작되었고, 2026 modern detector 는 frequency-domain artifacts, biological signals (PPG, eye blink), 그리고 self-supervised representation 의 ensemble 의 통해 95%+ AUC 의 달성 — but cross-model generalization 의 여전히 매 open problem.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Detection 패러다임
|
||||
- **Frequency-domain**: GAN/Diffusion 의 upsampling artifact (DCT spectrum 의 grid pattern, FFT 의 high-freq 결손).
|
||||
- **Biological signal**: heart-rate (rPPG), micro-expression, eye blink frequency 의 unnatural pattern.
|
||||
- **Identity consistency**: face embedding 의 video-level temporal drift.
|
||||
- **Self-supervised**: CLIP/DINOv2 feature 의 OOD detection.
|
||||
|
||||
### 매 Generation 종류
|
||||
- **Face swap**: DeepFaceLab, FaceFusion, Roop.
|
||||
- **Face reenactment**: First Order Motion Model, LivePortrait (2024).
|
||||
- **Full-body**: Wav2Lip, SadTalker, EMO (Alibaba 2024).
|
||||
- **Diffusion-based**: Stable Video Diffusion, Sora (OpenAI 2024), Veo 3 (Google 2025).
|
||||
|
||||
### 매 응용
|
||||
1. Newsroom 의 fact-checking pipeline (Reuters, AP).
|
||||
2. Social platform 의 watermark + detection (Meta, TikTok, X).
|
||||
3. Identity verification (KYC, banking — Persona, Onfido).
|
||||
4. Forensic 증거 분석 (court-admissible chain of custody).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Frequency-domain CNN (Frank et al. baseline)
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from torch.fft import fft2, fftshift
|
||||
|
||||
class FrequencyDeepfakeDetector(nn.Module):
|
||||
def __init__(self, num_classes=2):
|
||||
super().__init__()
|
||||
self.backbone = nn.Sequential(
|
||||
nn.Conv2d(1, 32, 3, padding=1), nn.ReLU(),
|
||||
nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(),
|
||||
nn.AdaptiveAvgPool2d(8), nn.Flatten(),
|
||||
nn.Linear(64 * 64, num_classes),
|
||||
)
|
||||
|
||||
def forward(self, x): # x: (B, 3, H, W) RGB
|
||||
gray = x.mean(1, keepdim=True)
|
||||
spec = fftshift(fft2(gray)).abs().log1p()
|
||||
return self.backbone(spec)
|
||||
```
|
||||
|
||||
### rPPG-based liveness (heart-rate from face video)
|
||||
```python
|
||||
import numpy as np
|
||||
from scipy.signal import butter, filtfilt
|
||||
|
||||
def extract_rppg(face_frames, fps=30):
|
||||
# POS algorithm — Wang et al. 2017
|
||||
rgb_signal = np.stack([f.reshape(-1, 3).mean(0) for f in face_frames])
|
||||
rgb_norm = rgb_signal / rgb_signal.mean(0)
|
||||
proj = rgb_norm @ np.array([[0, 1, -1], [-2, 1, 1]]).T
|
||||
s = proj[:, 0] + (proj[:, 0].std() / proj[:, 1].std()) * proj[:, 1]
|
||||
b, a = butter(4, [0.7, 4.0], btype='band', fs=fps)
|
||||
return filtfilt(b, a, s - s.mean())
|
||||
|
||||
def is_live(rppg, fps=30):
|
||||
fft = np.abs(np.fft.rfft(rppg))
|
||||
freqs = np.fft.rfftfreq(len(rppg), 1/fps) * 60 # BPM
|
||||
peak_bpm = freqs[fft.argmax()]
|
||||
return 50 <= peak_bpm <= 180 # 매 plausible HR range
|
||||
```
|
||||
|
||||
### CLIP-based zero-shot detector
|
||||
```python
|
||||
import open_clip
|
||||
import torch
|
||||
|
||||
model, _, preprocess = open_clip.create_model_and_transforms(
|
||||
'ViT-L-14', pretrained='laion2b_s32b_b82k')
|
||||
tokenizer = open_clip.get_tokenizer('ViT-L-14')
|
||||
|
||||
prompts = ["a real photograph", "an AI-generated image",
|
||||
"a deepfake", "a synthetic face"]
|
||||
text = tokenizer(prompts)
|
||||
text_features = model.encode_text(text)
|
||||
text_features /= text_features.norm(dim=-1, keepdim=True)
|
||||
|
||||
def score(image_pil):
|
||||
img = preprocess(image_pil).unsqueeze(0)
|
||||
img_feat = model.encode_image(img)
|
||||
img_feat /= img_feat.norm(dim=-1, keepdim=True)
|
||||
sims = (img_feat @ text_features.T).softmax(-1)
|
||||
return sims[0, 1:].sum().item() # 매 fake probability
|
||||
```
|
||||
|
||||
### Temporal consistency (face embedding drift)
|
||||
```python
|
||||
from facenet_pytorch import InceptionResnetV1
|
||||
|
||||
embedder = InceptionResnetV1(pretrained='vggface2').eval()
|
||||
|
||||
def temporal_drift(face_crops):
|
||||
embs = embedder(torch.stack(face_crops))
|
||||
embs = embs / embs.norm(dim=-1, keepdim=True)
|
||||
consec_sim = (embs[:-1] * embs[1:]).sum(-1)
|
||||
# 매 swapped face 의 unnatural jitter 의 detect
|
||||
return 1.0 - consec_sim.mean().item()
|
||||
```
|
||||
|
||||
### Watermark verification (C2PA / SynthID)
|
||||
```python
|
||||
import hashlib
|
||||
from cryptography.hazmat.primitives.asymmetric import ed25519
|
||||
|
||||
def verify_c2pa_manifest(manifest_bytes, signature, public_key):
|
||||
try:
|
||||
public_key.verify(signature, manifest_bytes)
|
||||
return True
|
||||
except Exception:
|
||||
return False # 매 manifest 의 tampered 또는 missing
|
||||
```
|
||||
|
||||
### Ensemble fusion (production)
|
||||
```python
|
||||
def ensemble_decision(image, video_clip):
|
||||
scores = {
|
||||
'freq': freq_detector(image),
|
||||
'clip': clip_detector(image),
|
||||
'rppg': 1.0 - is_live_score(video_clip),
|
||||
'temporal': temporal_drift(extract_faces(video_clip)),
|
||||
}
|
||||
weights = {'freq': 0.3, 'clip': 0.25, 'rppg': 0.25, 'temporal': 0.2}
|
||||
return sum(w * scores[k] for k, w in weights.items())
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Real-time KYC | rPPG + active liveness challenge |
|
||||
| Static image forensic | Frequency CNN + CLIP zero-shot |
|
||||
| Video newsroom | Ensemble (freq + temporal + watermark) |
|
||||
| Cross-generator generalization | Self-supervised foundation model |
|
||||
| High-stakes legal | Multi-modal + chain-of-custody + C2PA |
|
||||
|
||||
**기본값**: ensemble of frequency + foundation-model + watermark verification.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Computer Vision]]
|
||||
- 응용: [[Content Moderation]]
|
||||
- Adjacent: [[C2PA]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: feature engineering 의 brainstorm, dataset curation script, false-positive 분석.
|
||||
**언제 X**: production detection model 의 직접 inference (LLM 의 vision 의 reliable detector 의 X — specialized model 의 사용).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Single-detector reliance**: GAN-trained detector 의 diffusion-generated content 의 fail.
|
||||
- **No cross-generator eval**: train/test 의 same generator 의 inflated metric.
|
||||
- **Ignoring compression artifacts**: JPEG/H.264 의 frequency signal 의 destroy.
|
||||
- **Adversarial blindness**: detector 의 adversarial perturbation 의 robust 의 X.
|
||||
- **Watermark-only**: open-source generator 의 watermark 의 strip.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (FaceForensics++ benchmark, DFDC, Frank et al. ICML 2020, C2PA spec v2.1).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — frequency/biological/CLIP detection patterns + ensemble |
|
||||
@@ -0,0 +1,155 @@
|
||||
---
|
||||
id: wiki-2026-0508-devsecops-framework
|
||||
title: DevSecOps Framework
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [DevSecOps, Shift-Left Security, Secure SDLC]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [devsecops, security, shift-left, sdlc]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: YAML/Python
|
||||
framework: GitHub Actions/Semgrep/Trivy
|
||||
---
|
||||
|
||||
# DevSecOps Framework
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 security 가 PR 단계부터 매일 실행되는 자동 체크가 되는 것."**. DevSecOps 는 매 plan-code-build-test-release-deploy-operate-monitor 8단계 의 매 step 마다 security control 을 embed 하는 매 shift-left framework. 2026 표준: SAST + SCA + IaC scan + secret scan + DAST + RASP + supply-chain (SLSA L3) + ASPM platform.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 8-Stage Embed
|
||||
1. **Plan**: threat model (STRIDE), security stories.
|
||||
2. **Code**: IDE plugin (Semgrep, SonarLint), pre-commit (lint-staged + secret).
|
||||
3. **Build**: SBOM (Syft), reproducible build, sign (cosign).
|
||||
4. **Test**: SAST (Semgrep, CodeQL), SCA (Trivy, Snyk), IaC (Checkov).
|
||||
5. **Release**: provenance (SLSA), policy (OPA gatekeeper).
|
||||
6. **Deploy**: admission control, signed image verify, secrets via Vault.
|
||||
7. **Operate**: RASP, WAF, runtime detection (Falco).
|
||||
8. **Monitor**: SIEM (Splunk), anomaly detection, incident response.
|
||||
|
||||
### 매 Tool Categories 2026
|
||||
- **SAST**: Semgrep, CodeQL, Snyk Code.
|
||||
- **SCA**: Trivy, Snyk Open Source, Dependabot.
|
||||
- **DAST**: ZAP, Burp, Nuclei.
|
||||
- **IaC**: Checkov, tfsec, KICS.
|
||||
- **Secret scan**: gitleaks, TruffleHog.
|
||||
- **Container**: Trivy, Grype.
|
||||
- **K8s**: kube-bench, Falco, Kyverno.
|
||||
- **ASPM**: Phoenix, Apiiro, ArmorCode — aggregate + prioritize.
|
||||
|
||||
### 매 응용
|
||||
1. Web app secure SDLC.
|
||||
2. K8s cluster hardening.
|
||||
3. Cloud infra (Terraform/Pulumi) compliance.
|
||||
4. Container registry policy.
|
||||
5. Supply-chain integrity (SLSA L3).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### GitHub Actions DevSecOps gate
|
||||
```yaml
|
||||
name: secure-pr
|
||||
on: pull_request
|
||||
permissions: { contents: read, security-events: write, id-token: write }
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gitleaks/gitleaks-action@v2 # 매 secrets
|
||||
- uses: returntocorp/semgrep-action@v1 # 매 SAST
|
||||
with: { config: 'p/owasp-top-ten p/security-audit' }
|
||||
- uses: aquasecurity/trivy-action@master # 매 SCA + container
|
||||
with: { scan-type: fs, severity: 'CRITICAL,HIGH', exit-code: 1 }
|
||||
- uses: bridgecrewio/checkov-action@master # 매 IaC
|
||||
```
|
||||
|
||||
### Pre-commit secret scan
|
||||
```yaml
|
||||
# .pre-commit-config.yaml
|
||||
repos:
|
||||
- repo: https://github.com/gitleaks/gitleaks
|
||||
rev: v8.18.0
|
||||
hooks: [{ id: gitleaks }]
|
||||
```
|
||||
|
||||
### OPA admission policy (K8s)
|
||||
```rego
|
||||
package k8s.image
|
||||
violation[{"msg": msg}] {
|
||||
input.review.object.spec.containers[_].image
|
||||
not startswith(input.review.object.spec.containers[_].image, "ghcr.io/myorg/")
|
||||
msg := "image must come from approved registry"
|
||||
}
|
||||
```
|
||||
|
||||
### Cosign verify in admission
|
||||
```yaml
|
||||
apiVersion: policy.sigstore.dev/v1beta1
|
||||
kind: ClusterImagePolicy
|
||||
spec:
|
||||
images: [{ glob: "ghcr.io/myorg/**" }]
|
||||
authorities:
|
||||
- keyless:
|
||||
identities: [{ issuer: "https://token.actions.githubusercontent.com", subject: ".*myorg/.*" }]
|
||||
```
|
||||
|
||||
### Falco runtime detection rule
|
||||
```yaml
|
||||
- rule: Shell in container
|
||||
desc: Detect shell exec inside container
|
||||
condition: container.id != host and proc.name in (bash, sh, zsh)
|
||||
output: "Shell %proc.name in container=%container.name image=%container.image.repository"
|
||||
priority: WARNING
|
||||
```
|
||||
|
||||
### SBOM + provenance attest
|
||||
```bash
|
||||
syft packages oci:./image.tar -o spdx-json > sbom.spdx.json
|
||||
cosign attest --predicate sbom.spdx.json --type spdx ghcr.io/org/app@sha256:...
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool stack |
|
||||
|---|---|
|
||||
| TS/Python monorepo | Semgrep + Trivy + gitleaks |
|
||||
| Terraform cloud infra | Checkov + tfsec |
|
||||
| K8s cluster | Falco + Kyverno + cosign |
|
||||
| Compliance heavy | ASPM platform (Phoenix/Apiiro) |
|
||||
| Air-gapped / regulated | Semgrep self-host + Trivy DB mirror |
|
||||
|
||||
**기본값**: 매 Semgrep + Trivy + gitleaks + Checkov + cosign + Falco.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[보안 및 시스템 신뢰성 표준|OWASP Top 10]] · [[안전한 소프트웨어 개발 수명주기(SSDLC)]]
|
||||
- 변형: [[애플리케이션_보안_태세_관리ASPM]]
|
||||
- 응용: [[SAST]] · [[보안 및 시스템 신뢰성 표준|DAST]] · [[SCA_Fundamentals|SCA]] · [[Secret_Management]]
|
||||
- Adjacent: [[보안 및 시스템 신뢰성 표준|Zero-Trust Architecture]] · [[CI_CD_Pipeline]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: vuln triage, false-positive filter, remediation PR draft, threat-model brainstorm.
|
||||
**언제 X**: 매 actual scan — specialized engine 이 빠르고 정확.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Security as gate-only**: 매 alert flood 만 — fix automation 없음.
|
||||
- **Tool sprawl**: 매 5개 SAST 가 noise — ASPM 으로 dedupe.
|
||||
- **No baseline**: 매 legacy CVE 전체가 critical — accept + monitor.
|
||||
- **Bypass culture**: 매 dev 가 `// eslint-disable security/*` — guard 무력화.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: NIST SSDF SP 800-218; OWASP DevSecOps maturity; SLSA v1.0; Falco docs.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — 8-stage + tool stack 2026 |
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
---
|
||||
id: wiki-2026-0508-digital-intellectual-property-ri
|
||||
title: Digital Intellectual Property Rights
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Digital IP, Software IP, Digital Rights]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [legal, ip, licensing, copyright]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: legal
|
||||
framework: licenses
|
||||
---
|
||||
|
||||
# Digital Intellectual Property Rights
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 digital IP 의 의미: 매 software / data / model 의 매 ownership, license, attribution 권리"**. 매 copyright (default) + 매 license (grant) + 매 patent (algorithm) + 매 trade secret 의 4 axis. 매 2026 AI 시대 의 매 training data 권리, 매 model weights 권리, 매 LLM output 권리 의 매 hot frontier.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 4 axis
|
||||
- **Copyright**: 매 expression (code, art, text) 의 default 보호 — 매 author 의 lifetime + 70년
|
||||
- **License**: 매 author 의 매 grant — MIT, Apache, GPL, proprietary
|
||||
- **Patent**: 매 invention (algorithm, system) — 매 20년, 매 applied required
|
||||
- **Trade secret**: 매 confidential 정보 — 매 indefinite, 매 reasonable protection 요구
|
||||
|
||||
### Open Source 의 매 spectrum
|
||||
- **Permissive**: MIT, Apache 2.0, BSD — 매 commercial use OK
|
||||
- **Weak copyleft**: LGPL, MPL — 매 modified file 만 share
|
||||
- **Strong copyleft**: GPL, AGPL — 매 entire derivative work share
|
||||
- **Source-available**: BUSL, SSPL — 매 commercial restriction (NOT OSI-approved)
|
||||
|
||||
### 매 AI/ML specific (2026)
|
||||
- **Training data**: 매 fair use 논쟁 (NYT v. OpenAI, Authors Guild v. Anthropic)
|
||||
- **Model weights**: 매 copyrightable? (매 unsettled, 매 case law evolving)
|
||||
- **AI output**: 매 US Copyright Office (2023) — 매 human authorship required
|
||||
- **Style transfer**: 매 artist 의 매 trademark 가능성
|
||||
|
||||
### 매 응용
|
||||
1. 매 OSS dependency audit (license compatibility).
|
||||
2. 매 employee invention assignment.
|
||||
3. 매 LLM output 의 commercial use 결정.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### License File 의 매 MIT
|
||||
```
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Acme Corp
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND...
|
||||
```
|
||||
|
||||
### SPDX 의 매 file header
|
||||
```typescript
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2026 Acme Corp
|
||||
```
|
||||
|
||||
### License Audit 의 매 tooling
|
||||
```bash
|
||||
# 매 npm 의 license check
|
||||
npx license-checker --production --summary
|
||||
|
||||
# 매 SBOM 생성 (CycloneDX)
|
||||
npx @cyclonedx/cyclonedx-npm --output-format JSON --output-file sbom.json
|
||||
|
||||
# 매 incompatible license 의 매 fail
|
||||
npx license-checker --failOn 'GPL-3.0;AGPL-3.0'
|
||||
```
|
||||
|
||||
### CLA / DCO (Contributor)
|
||||
```bash
|
||||
# DCO sign-off
|
||||
git commit -s -m "feat: add foo"
|
||||
# Signed-off-by: Jane <jane@acme.com>
|
||||
```
|
||||
|
||||
### REUSE Compliance (EU 표준)
|
||||
```toml
|
||||
# .reuse/dep5
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
|
||||
Files: src/*
|
||||
Copyright: 2026 Acme Corp
|
||||
License: Apache-2.0
|
||||
|
||||
Files: vendor/*
|
||||
Copyright: 2024 Original Author
|
||||
License: MIT
|
||||
```
|
||||
|
||||
### AI Model Card 의 매 license clarity
|
||||
```markdown
|
||||
# Model Card: acme-llm-v2
|
||||
|
||||
## License
|
||||
- **Weights**: Llama 3 Community License (Meta)
|
||||
- **Code**: Apache 2.0 (Acme)
|
||||
- **Training data**: Mixed (CC-BY, public domain, licensed proprietary)
|
||||
|
||||
## Permitted Use
|
||||
- Commercial use < 700M MAU OK (per Llama license)
|
||||
- Fine-tuning OK
|
||||
- Redistributing weights: see Llama license restrictions
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Internal-only project | 매 proprietary, 매 no public license |
|
||||
| Open source library | 매 MIT (max adoption) / Apache 2.0 (patent grant) |
|
||||
| Want commercial fork prevention | 매 AGPL / BUSL |
|
||||
| Enterprise SaaS | 매 proprietary EULA + 매 SOC2 |
|
||||
| AI model release | 매 OpenRAIL / 매 community license + 매 model card |
|
||||
|
||||
**기본값**: 매 Apache 2.0 (OSS) / 매 proprietary EULA (commercial).
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[Copyright]]
|
||||
- 응용: [[SBOM]]
|
||||
- Adjacent: [[GDPR]] · [[Ensuring Data Privacy]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 license compatibility 의 first-pass check, 매 EULA draft 의 starter, 매 model card 의 generation.
|
||||
**언제 X**: 매 actual legal advice — 매 lawyer required. 매 jurisdiction-specific (US v. EU v. JP) 의 매 LLM error 위험.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 license 의 X (no LICENSE file)**: 매 default = all rights reserved → 매 사용 불가.
|
||||
- **매 GPL code 의 매 proprietary product 에 mix**: 매 entire codebase 의 GPL infect.
|
||||
- **매 LLM output 의 무비판 commercial 사용**: 매 training data attribution 위험.
|
||||
- **매 employee NDA 없음**: 매 trade secret 의 protection 불가.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (OSI license list, SPDX, US Copyright Office AI guidance 2023).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Digital IP rights full content |
|
||||
@@ -0,0 +1,137 @@
|
||||
---
|
||||
id: wiki-2026-0508-digital-thread-integration
|
||||
title: Digital Thread Integration
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Digital Thread, Industrial Data Thread]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [iiot, digital-thread, manufacturing, plm]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: Python/SQL
|
||||
framework: OPC UA/MQTT/Kafka
|
||||
---
|
||||
|
||||
# Digital Thread Integration
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 product lifecycle 의 모든 data 가 single linked thread 로 흐르는 것."**. Digital Thread 는 design (CAD) → engineering (PLM) → manufacturing (MES) → operations (IoT) → service (CRM) 까지 매 traceable, queryable 하게 연결하는 매 manufacturing/aerospace 의 backbone. 2026 의 standard: ISA-95 + OPC UA + Asset Administration Shell (AAS) + RAMI 4.0 + IDS data spaces.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Digital Thread vs Digital Twin
|
||||
- **Thread**: 매 data lineage — design intent ↔ as-built ↔ as-maintained.
|
||||
- **Twin**: 매 simulation model of a specific asset.
|
||||
- **관계**: Twin 은 Thread 의 cross-section snapshot.
|
||||
|
||||
### 매 Layer Stack
|
||||
1. **Edge**: PLC, sensor, OPC UA server.
|
||||
2. **Connectivity**: MQTT, OPC UA, MTConnect.
|
||||
3. **Stream**: Kafka / Pulsar — high-throughput.
|
||||
4. **Storage**: time-series (InfluxDB, TimescaleDB), data lake (Iceberg).
|
||||
5. **Semantic**: Asset Administration Shell, ontology (W3C SOSA/SSN).
|
||||
6. **Application**: PLM (Teamcenter, Windchill), MES, ERP.
|
||||
|
||||
### 매 응용
|
||||
1. Aerospace — 매 part traceability, certification.
|
||||
2. Automotive — 매 EV battery passport (EU 2027 mandate).
|
||||
3. Industrial maintenance — 매 predictive + service history.
|
||||
4. Pharma — 매 batch genealogy.
|
||||
5. EU Digital Product Passport — 매 sustainability.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### OPC UA client (Python)
|
||||
```python
|
||||
from asyncua import Client
|
||||
async def main():
|
||||
async with Client(url="opc.tcp://plant.local:4840") as c:
|
||||
node = c.get_node("ns=2;s=Line1.Press.Temp")
|
||||
async for v in node.subscribe_data_change(callback):
|
||||
pass
|
||||
```
|
||||
|
||||
### MQTT Sparkplug B (manufacturing-standard payload)
|
||||
```python
|
||||
import paho.mqtt.client as mqtt
|
||||
import sparkplug_b as sp
|
||||
payload = sp.getDdataPayload()
|
||||
sp.addMetric(payload, "Temp", None, sp.MetricDataType.Float, 72.5)
|
||||
client.publish("spBv1.0/PlantA/DDATA/Edge1/Press1", payload.SerializeToString())
|
||||
```
|
||||
|
||||
### Asset Administration Shell submodel
|
||||
```json
|
||||
{
|
||||
"idShort": "Nameplate",
|
||||
"submodelElements": [
|
||||
{"idShort":"ManufacturerName","value":"Acme"},
|
||||
{"idShort":"SerialNumber","value":"SN-A1B2"},
|
||||
{"idShort":"YearOfConstruction","value":"2026"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Kafka pipeline edge → lake
|
||||
```python
|
||||
from confluent_kafka import Producer
|
||||
import pyarrow.parquet as pq
|
||||
p = Producer({'bootstrap.servers':'kafka:9092','compression.type':'zstd'})
|
||||
p.produce('plant.line1.temp', key=part_id, value=msg.SerializeToString())
|
||||
# downstream Flink/Spark → Iceberg table
|
||||
```
|
||||
|
||||
### Digital Product Passport (EU 2027)
|
||||
```json
|
||||
{
|
||||
"productId": "urn:gtin:01234567890128",
|
||||
"carbonFootprintKg": 12.4,
|
||||
"materials": [{"name":"Li","massGrams":1200}],
|
||||
"recycledContentPercent": 18,
|
||||
"linkedTwin": "urn:twin:battery:SN-A1B2"
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Field bus modernization | OPC UA |
|
||||
| IoT-style telemetry | MQTT Sparkplug B |
|
||||
| Cross-vendor semantics | AAS / IDS |
|
||||
| Stream backbone | Kafka / Pulsar |
|
||||
| Time-series store | TimescaleDB / Influx |
|
||||
| Lake | Iceberg + Trino |
|
||||
|
||||
**기본값**: 매 OPC UA + MQTT Sparkplug B → Kafka → Iceberg.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Digital Twins]] · [[Digital Twins|Digital-Twin-Technology]]
|
||||
- 변형: [[클라우드 인프라 및 IaC 운영 표준|IoT]]
|
||||
- 응용: [[Engineering Metrics (DORA)]]
|
||||
- Adjacent: [[Digital Intellectual Property Rights]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: ontology mapping, anomaly summary, maintenance work-order draft.
|
||||
**언제 X**: 매 safety-critical PLC logic — formal verification 만.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Polling 오버**: 매 OPC UA subscribe 사용 — pub/sub.
|
||||
- **Untimestamped data**: 매 Thread 의 핵심은 시간 lineage.
|
||||
- **Vendor lock**: 매 proprietary protocol — open standards 사용.
|
||||
- **No identity**: 매 GS1, urn 등 stable id 필수.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: ISA-95 spec; OPC UA Part 1; Plattform Industrie 4.0 AAS spec; EU DPP regulation 2024.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Thread vs Twin + OPC UA/MQTT/AAS |
|
||||
@@ -0,0 +1,144 @@
|
||||
---
|
||||
id: wiki-2026-0508-dopamine
|
||||
title: Dopamine
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Reward System, Reinforcement Signal, Prediction Error]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [neuroscience, reinforcement-learning, motivation, ux]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: rl
|
||||
---
|
||||
|
||||
# Dopamine
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 reward prediction error 의 signal"**. 매 dopamine 의 modern view 는 pleasure 의 X, 매 *expected vs actual reward 의 차이* 의 broadcast. 매 Schultz (1997) 의 monkey VTA recording 의 RL 의 TD-error 의 isomorphism 의 establish. 매 product UX, addiction design, RL algorithm 의 shared substrate.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 RPE (Reward Prediction Error)
|
||||
- **Positive RPE**: 매 expected 보다 better. 매 dopamine burst.
|
||||
- **Zero RPE**: 매 fully predicted. 매 baseline firing.
|
||||
- **Negative RPE**: 매 expected 보다 worse. 매 firing dip.
|
||||
|
||||
### 매 RL 의 TD-error 와 의 mapping
|
||||
- 매 δ = r + γV(s') − V(s).
|
||||
- 매 dopamine neuron 의 firing rate 의 δ 의 encode (Schultz, Dayan, Montague 1997).
|
||||
|
||||
### 매 응용
|
||||
1. Variable-ratio schedule (slot machine, social media feed) — 매 maximal RPE.
|
||||
2. Habit formation (intermittent reward).
|
||||
3. Anhedonia / addiction 의 dopaminergic dysregulation.
|
||||
4. RL agent design (curiosity, intrinsic motivation).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### TD-learning (dopamine-analog)
|
||||
```python
|
||||
import numpy as np
|
||||
|
||||
def td_update(V, s, r, s_next, alpha=0.1, gamma=0.9):
|
||||
"""V: value table. δ = TD error = 'dopamine signal'."""
|
||||
delta = r + gamma * V[s_next] - V[s] # ← RPE
|
||||
V[s] += alpha * delta
|
||||
return delta # log this; it's the 'dopamine'
|
||||
|
||||
V = np.zeros(10)
|
||||
for episode in range(1000):
|
||||
s, r, s_next = sample_transition()
|
||||
rpe = td_update(V, s, r, s_next)
|
||||
```
|
||||
|
||||
### Curiosity-driven exploration (intrinsic dopamine analog)
|
||||
```python
|
||||
# Random Network Distillation (Burda 2018)
|
||||
class RND(nn.Module):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.target = nn.Sequential(nn.Linear(64, 128), nn.ReLU(), nn.Linear(128, 64))
|
||||
self.predictor = nn.Sequential(nn.Linear(64, 128), nn.ReLU(), nn.Linear(128, 64))
|
||||
for p in self.target.parameters(): p.requires_grad = False
|
||||
|
||||
def intrinsic_reward(self, obs):
|
||||
with torch.no_grad():
|
||||
target = self.target(obs)
|
||||
pred = self.predictor(obs)
|
||||
return ((target - pred) ** 2).mean(-1) # novelty bonus
|
||||
```
|
||||
|
||||
### Variable-ratio schedule simulator
|
||||
```python
|
||||
def variable_ratio_session(p_reward=0.1, n_pulls=100):
|
||||
rpe_log = []
|
||||
expected = p_reward # learned expectation
|
||||
for _ in range(n_pulls):
|
||||
r = 1.0 if np.random.rand() < p_reward else 0.0
|
||||
rpe = r - expected
|
||||
expected += 0.05 * rpe # slow learning
|
||||
rpe_log.append(rpe)
|
||||
return rpe_log
|
||||
# Pattern: high-amplitude RPE persists → "addictive" engagement
|
||||
```
|
||||
|
||||
### Hyperbolic discounting (dopamine-future)
|
||||
```python
|
||||
def hyperbolic_value(reward, delay, k=0.1):
|
||||
"""Real human/animal — closer to hyperbolic than exponential."""
|
||||
return reward / (1 + k * delay)
|
||||
```
|
||||
|
||||
### Opponent process (reward + aversion)
|
||||
```python
|
||||
# Two-system: dopamine (reward) + serotonin (aversion / patience)
|
||||
def dual_system_update(V_reward, V_aversion, r_pos, r_neg, s, s_next, alpha=0.1, gamma=0.9):
|
||||
delta_reward = r_pos + gamma * V_reward[s_next] - V_reward[s]
|
||||
delta_aversion = r_neg + gamma * V_aversion[s_next] - V_aversion[s]
|
||||
V_reward[s] += alpha * delta_reward
|
||||
V_aversion[s] += alpha * delta_aversion
|
||||
return delta_reward, delta_aversion
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
|
||||
| 상황 | Insight |
|
||||
|---|---|
|
||||
| Habit-forming product | Variable-ratio reward (Slot machine schedule) |
|
||||
| Sustained engagement | Mix predictable + unpredictable wins |
|
||||
| Avoid burnout | Avoid pure RPE-maximization (ethical concern) |
|
||||
| RL exploration stuck | Add intrinsic reward (RND, ICM) |
|
||||
| Anhedonia in user | Reduce expectation, surprise with low-cost wins |
|
||||
|
||||
**기본값**: 매 RPE-aware design — but 매 ethics 의 weight (manipulation 의 risk).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Reinforcement Learning]]
|
||||
- 응용: [[Habit Formation]] · [[Game Design]] · [[Recommender Systems]]
|
||||
- Adjacent: [[TD-Learning]] · [[Behavioral Economics]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 product UX 의 retention mechanic 의 audit. 매 dark-pattern 의 detection.
|
||||
**언제 X**: 매 clinical advice. 매 LLM 의 medical claim 의 X.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Dopamine = pleasure 의 simplification**: 매 X. 매 RPE 의 signal — pleasure 는 separate (opioid).
|
||||
- **Pure exploitation (no novelty)**: 매 user 의 RPE 의 0 의 disengage.
|
||||
- **Manipulative dark pattern**: 매 ethical violation. 매 design 의 audit 의 mandatory.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Schultz 1997 Science, Sutton & Barto 2018, Berridge 2007).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — RPE / TD-learning isomorphism + UX implication |
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
id: wiki-2026-0508-draw-call
|
||||
title: Draw Call
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Drawcall, GPU Submit, Render Command]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [graphics, gpu, performance, rendering]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: C++/Rust
|
||||
framework: Vulkan/Metal/D3D12/WebGPU
|
||||
---
|
||||
|
||||
# Draw Call
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 CPU 가 GPU 에게 매 한 batch 를 그리라고 매 instructing 하는 single command"**. 1990s OpenGL `glDrawArrays` 시대의 매 ms-cost overhead 가 매 modern explicit API (Vulkan/D3D12/Metal/WebGPU) + bindless + GPU-driven rendering 으로 매 micro-second 수준으로 떨어짐. 매 2026 — `vkCmdDrawIndexedIndirectCount` + mesh shader 가 매 norm.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 anatomy
|
||||
- Set pipeline (shader, blend, depth state).
|
||||
- Bind resources (vertex/index buffer, uniform, texture).
|
||||
- Issue draw (`drawIndexed`, `dispatch`).
|
||||
- Submit to queue.
|
||||
|
||||
### 매 cost source
|
||||
- **Driver validation**: legacy GL 의 매 main bottleneck.
|
||||
- **State change**: pipeline / RT / descriptor switch.
|
||||
- **CPU↔GPU sync**: fence wait, map/unmap.
|
||||
- **Command recording**: 매 modern API 에서 매 thread 분산 가능.
|
||||
|
||||
### 매 응용
|
||||
1. Draw call 수 줄임 → frame time 직접 감소.
|
||||
2. Batching (instancing, atlas, indirect).
|
||||
3. GPU-driven culling (compute → indirect).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Vulkan minimal draw
|
||||
```cpp
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
VkBuffer vbs[] = {vertexBuf}; VkDeviceSize off[] = {0};
|
||||
vkCmdBindVertexBuffers(cmd, 0, 1, vbs, off);
|
||||
vkCmdBindIndexBuffer(cmd, indexBuf, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindDescriptorSets(cmd, ..., 0, 1, &set, 0, nullptr);
|
||||
vkCmdDrawIndexed(cmd, indexCount, instanceCount, 0, 0, 0);
|
||||
```
|
||||
|
||||
### Instancing (1 call → N objects)
|
||||
```glsl
|
||||
// vertex shader
|
||||
layout(location = 0) in vec3 pos;
|
||||
layout(location = 4) in mat4 modelMatrix; // per-instance
|
||||
void main() { gl_Position = vp * modelMatrix * vec4(pos, 1); }
|
||||
```
|
||||
```cpp
|
||||
// CPU side
|
||||
vkCmdDrawIndexed(cmd, idxCount, 10000, 0, 0, 0); // 10k objects, 1 draw
|
||||
```
|
||||
|
||||
### Indirect draw (GPU-driven)
|
||||
```cpp
|
||||
struct VkDrawIndexedIndirectCommand {
|
||||
uint32_t indexCount, instanceCount, firstIndex;
|
||||
int32_t vertexOffset; uint32_t firstInstance;
|
||||
};
|
||||
// Compute shader culls & writes commands + count to GPU buffer.
|
||||
// CPU just calls:
|
||||
vkCmdDrawIndexedIndirectCount(cmd, drawBuf, 0, countBuf, 0, MAX_DRAWS, sizeof(Cmd));
|
||||
```
|
||||
|
||||
### Bindless (descriptor indexing)
|
||||
```glsl
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
layout(set=0, binding=0) uniform sampler2D textures[];
|
||||
layout(push_constant) uniform PC { uint texIndex; };
|
||||
void main() { color = texture(textures[nonuniformEXT(texIndex)], uv); }
|
||||
```
|
||||
|
||||
### Mesh shader (DX12 / Vulkan)
|
||||
```glsl
|
||||
#version 460
|
||||
#extension GL_EXT_mesh_shader : require
|
||||
layout(local_size_x = 32) in;
|
||||
layout(triangles, max_vertices = 64, max_primitives = 124) out;
|
||||
void main() {
|
||||
SetMeshOutputsEXT(vertCount, primCount);
|
||||
// amplify / cull per meshlet, no IA stage
|
||||
}
|
||||
```
|
||||
|
||||
### Multi-thread command recording (Vulkan)
|
||||
```cpp
|
||||
// 1 secondary CB per thread
|
||||
parallel_for(0, N, [&](int i) {
|
||||
VkCommandBuffer sec = secondaryCBs[threadId];
|
||||
vkBeginCommandBuffer(sec, ...);
|
||||
record_draws_for_chunk(sec, chunk[i]);
|
||||
vkEndCommandBuffer(sec);
|
||||
});
|
||||
vkCmdExecuteCommands(primaryCB, N, secondaryCBs.data());
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 同 mesh 수천 개 | Instancing |
|
||||
| Diverse mesh, frustum cullable | GPU-driven indirect + compute culling |
|
||||
| Many materials | Bindless texture + uber-shader |
|
||||
| Highly detailed geometry | Mesh shader + meshlet |
|
||||
| Legacy GL/GLES | Atlas + state sort + minimize binds |
|
||||
|
||||
**기본값**: Modern → indirect + bindless. Legacy → batch by state.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[GPU Pipeline]] · [[Real-time Rendering]]
|
||||
- 변형: [[Indirect Draw]]
|
||||
- 응용: [[Frustum Culling]] · [[Geometry Merging]]
|
||||
- Adjacent: [[Vulkan]] · [[Metal]] · [[WebGPU]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Renderer architecture, perf budget 분석, profiling 결과 해석.
|
||||
**언제 X**: Game design / art direction.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **One draw per object**: legacy 패턴 — instancing/indirect 사용.
|
||||
- **Excessive state changes**: shader/pipeline 매 frame 수천 번 swap.
|
||||
- **CPU-side culling 만**: GPU 보내서 매 compute 로 culling.
|
||||
- **Map/unmap loop**: persistent mapped buffer + ring 사용.
|
||||
- **Single thread record**: secondary CB + parallel_for.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Vulkan/D3D12 spec, Khronos best practices, GPU Zen).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — draw call cost + indirect/bindless/mesh shader |
|
||||
@@ -0,0 +1,199 @@
|
||||
---
|
||||
id: wiki-2026-0508-edtech-industry-trends
|
||||
title: Edtech Industry Trends
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [EdTech Trends, Education Technology, Learning Tech]
|
||||
duplicate_of: none
|
||||
source_trust_level: B
|
||||
confidence_score: 0.8
|
||||
verification_status: applied
|
||||
tags: [edtech, education, ai-tutor, lms, trends]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript
|
||||
framework: Next.js
|
||||
---
|
||||
|
||||
# Edtech Industry Trends
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 AI tutor 의 mass adoption + skill-based credentialing 의 rise"**. 2020 COVID 의 remote-learning 폭발 이후, 2023 GPT-4 의 ChatGPT 의 학습 의 disrupt — 2026 는 personalized AI tutor (Khanmigo, Duolingo Max), micro-credential (Coursera, Open Badges), 그리고 LXP (Learning Experience Platform) 의 LMS 의 대체 의 dominate trend.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 2026 핵심 trend
|
||||
- **AI tutor 의 ubiquity**: Khanmigo, Duolingo Max, ChatGPT for Education.
|
||||
- **Adaptive learning**: knowledge tracing (DKT, BKT), spaced-repetition.
|
||||
- **Micro-credential**: stackable certificate, Open Badges 3.0, blockchain anchored.
|
||||
- **VR/AR**: Meta Quest for Education, immersive lab.
|
||||
- **Skills-based hiring**: degree-optional, portfolio + assessment.
|
||||
- **Decline of MOOC giants**: Coursera/edX 의 plateau, niche bootcamp 의 rise.
|
||||
|
||||
### 매 Tech stack
|
||||
- **Frontend**: Next.js, React Native, Unity (immersive).
|
||||
- **AI**: GPT-5, Claude Opus 4.7, Gemini 2.5, fine-tuned tutor model.
|
||||
- **Backend**: PostgreSQL + pgvector, Redis, Kafka.
|
||||
- **Standard**: LTI 1.3, xAPI/cmi5, Open Badges, IMS Caliper.
|
||||
|
||||
### 매 응용
|
||||
1. K-12 의 personalized math tutor (Khan Academy).
|
||||
2. Higher-ed 의 AI TA (Georgia Tech Jill Watson 후속).
|
||||
3. Corporate L&D 의 skill graph (Degreed, Cornerstone).
|
||||
4. Language (Duolingo, Speak) 의 conversational AI.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### LTI 1.3 의 LMS launch
|
||||
```typescript
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
export async function ltiLaunch(req, res) {
|
||||
const idToken = req.body.id_token;
|
||||
const decoded = jwt.verify(idToken, getKey, {
|
||||
algorithms: ['RS256'],
|
||||
audience: process.env.LTI_CLIENT_ID,
|
||||
issuer: process.env.LTI_PLATFORM_ISSUER,
|
||||
});
|
||||
const user = {
|
||||
sub: decoded.sub,
|
||||
role: decoded['https://purl.imsglobal.org/spec/lti/claim/roles'],
|
||||
contextId: decoded['https://purl.imsglobal.org/spec/lti/claim/context'].id,
|
||||
};
|
||||
req.session.lti = user;
|
||||
res.redirect('/activity');
|
||||
}
|
||||
```
|
||||
|
||||
### Adaptive item selection (BKT)
|
||||
```typescript
|
||||
// Bayesian Knowledge Tracing
|
||||
function bktUpdate(p_known: number, correct: boolean,
|
||||
p_T = 0.1, p_S = 0.1, p_G = 0.2) {
|
||||
const p_obs = correct
|
||||
? (p_known * (1 - p_S)) / (p_known * (1 - p_S) + (1 - p_known) * p_G)
|
||||
: (p_known * p_S) / (p_known * p_S + (1 - p_known) * (1 - p_G));
|
||||
return p_obs + (1 - p_obs) * p_T; // 매 mastery prob 의 update
|
||||
}
|
||||
|
||||
function nextItem(skillStates, items) {
|
||||
// 매 ZPD: mastery 0.4-0.7 의 item 의 prefer
|
||||
return items
|
||||
.map(i => ({ i, score: Math.abs(skillStates[i.skill] - 0.55) }))
|
||||
.sort((a, b) => a.score - b.score)[0].i;
|
||||
}
|
||||
```
|
||||
|
||||
### AI tutor 의 Socratic prompt
|
||||
```typescript
|
||||
const tutorSystemPrompt = `You are a Socratic tutor. NEVER give the answer.
|
||||
- Ask one guiding question at a time.
|
||||
- If student is stuck, decompose the problem.
|
||||
- Validate effort, gently correct misconceptions.
|
||||
- Use student's prior turn to scaffold.
|
||||
- After 3 unsuccessful hints, offer worked example, not answer.
|
||||
|
||||
Subject: ${subject}
|
||||
Student grade: ${grade}
|
||||
Misconceptions log: ${misconceptions.join(', ')}`;
|
||||
|
||||
const response = await anthropic.messages.create({
|
||||
model: 'claude-opus-4-7',
|
||||
system: tutorSystemPrompt,
|
||||
messages: history,
|
||||
max_tokens: 400,
|
||||
});
|
||||
```
|
||||
|
||||
### xAPI 의 statement emit
|
||||
```typescript
|
||||
async function emitXAPI(actor, verb, object, result) {
|
||||
await fetch(`${LRS}/statements`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Experience-API-Version': '1.0.3',
|
||||
'Authorization': `Basic ${LRS_AUTH}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
actor: { account: { homePage: APP, name: actor.id } },
|
||||
verb: { id: `http://adlnet.gov/expapi/verbs/${verb}`, display: { 'en-US': verb } },
|
||||
object: { id: `${APP}/activities/${object.id}` },
|
||||
result: { score: { scaled: result.score }, completion: result.completed },
|
||||
timestamp: new Date().toISOString(),
|
||||
}),
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Open Badges 3.0 (verifiable credential)
|
||||
```json
|
||||
{
|
||||
"@context": ["https://www.w3.org/ns/credentials/v2",
|
||||
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"],
|
||||
"type": ["VerifiableCredential", "OpenBadgeCredential"],
|
||||
"issuer": {"id": "did:web:acme.edu", "name": "Acme Academy"},
|
||||
"issuanceDate": "2026-05-10T12:00:00Z",
|
||||
"credentialSubject": {
|
||||
"id": "did:example:learner123",
|
||||
"type": ["AchievementSubject"],
|
||||
"achievement": {
|
||||
"id": "https://acme.edu/badges/python-mastery",
|
||||
"name": "Python Mastery",
|
||||
"criteria": {"narrative": "Complete 5 projects + final exam ≥80%"}
|
||||
}
|
||||
},
|
||||
"proof": {"type": "Ed25519Signature2020", "...": "..."}
|
||||
}
|
||||
```
|
||||
|
||||
### Knowledge graph 의 skill prerequisite
|
||||
```cypher
|
||||
MATCH (target:Skill {name: 'Calculus I'})
|
||||
-[:REQUIRES*1..]->(pre:Skill)
|
||||
WITH collect(DISTINCT pre) AS prereqs, target
|
||||
MATCH (learner:User {id: $userId})-[:MASTERED]->(s:Skill)
|
||||
WITH prereqs, target, collect(s) AS mastered
|
||||
RETURN target,
|
||||
[p IN prereqs WHERE NOT p IN mastered] AS gap;
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| K-12 math/reading | Adaptive engine + AI tutor (Socratic) |
|
||||
| Higher-ed CS | Project-based + auto-grader + AI TA |
|
||||
| Corporate L&D | Skill graph + micro-credential + xAPI |
|
||||
| Language learning | Conversational AI + spaced repetition |
|
||||
| Niche bootcamp | Cohort + mentor + portfolio review |
|
||||
|
||||
**기본값**: AI tutor (Socratic) + adaptive engine + xAPI tracking + Open Badges credential.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Education Technology]]
|
||||
- 변형: [[LMS]]
|
||||
- 응용: [[Adaptive Learning]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Socratic tutor, content scaffolding generation, formative feedback.
|
||||
**언제 X**: high-stakes summative grading 의 LLM 의 sole arbiter 의 X.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Engagement-only metric**: time-on-app maximization 의 learning outcome 무관.
|
||||
- **AI 의 give answer**: tutor 의 cheating tool 의 변질.
|
||||
- **No interoperability**: LTI/xAPI 의 ignore — institution 의 lock-in.
|
||||
- **Privacy 무시**: FERPA/COPPA 의 minor 의 consent 의 fail.
|
||||
- **Credential inflation**: badge 의 rigor 의 X — recognition 의 erode.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (HolonIQ Edtech Funding Report 2025, IMS Global LTI/Caliper specs, Open Badges 3.0).
|
||||
- 신뢰도 B (industry trends 의 변동 빠름).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — LTI/BKT/AI-tutor/xAPI/Open-Badges patterns |
|
||||
@@ -0,0 +1,166 @@
|
||||
---
|
||||
id: wiki-2026-0508-efficiency
|
||||
title: Efficiency
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Performance Efficiency, Resource Efficiency, Cost Efficiency]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.88
|
||||
verification_status: applied
|
||||
tags: [performance, efficiency, optimization, sre, cost]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: prometheus
|
||||
---
|
||||
|
||||
# Efficiency
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 useful output / resource consumed — 매 latency, throughput, $cost, watt 매 dimension 별 측정"**. 매 1972 Knuth "premature optimization" warning 후 신중함이 default, 매 2026 cloud cost + carbon footprint + energy efficiency 가 first-class metric.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Efficiency dimensions
|
||||
- **Time**: latency p50/p95/p99, throughput RPS.
|
||||
- **Space**: memory RSS, disk IOPS, network bytes.
|
||||
- **Money**: $/request, $/MAU.
|
||||
- **Energy**: watt/op, gCO2eq/request.
|
||||
|
||||
### 매 측정 → 개선 cycle
|
||||
1. **Profile**: hotspot 의 identify (flamegraph).
|
||||
2. **Hypothesize**: bottleneck 의 type (CPU? IO? Lock?).
|
||||
3. **Optimize**: targeted change.
|
||||
4. **Verify**: A/B with baseline, metric 의 statistical sig.
|
||||
|
||||
### 매 응용
|
||||
1. API: cold-start 의 reduce.
|
||||
2. ML inference: quantization, batching, KV cache.
|
||||
3. CI: cache hit rate 의 maximize.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Latency histogram (Prometheus)
|
||||
```python
|
||||
from prometheus_client import Histogram
|
||||
LATENCY = Histogram('http_request_duration_seconds', 'HTTP latency',
|
||||
buckets=[0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5])
|
||||
|
||||
@LATENCY.time()
|
||||
def handle(req): ...
|
||||
```
|
||||
|
||||
### Cost-per-request rollup
|
||||
```sql
|
||||
-- BigQuery
|
||||
SELECT
|
||||
service,
|
||||
SUM(billable_seconds * cpu_cost_per_sec) AS compute_usd,
|
||||
COUNT(*) AS requests,
|
||||
SUM(billable_seconds * cpu_cost_per_sec) / COUNT(*) AS usd_per_req
|
||||
FROM service_metrics
|
||||
WHERE _PARTITIONDATE = CURRENT_DATE() - 1
|
||||
GROUP BY service
|
||||
ORDER BY usd_per_req DESC;
|
||||
```
|
||||
|
||||
### CPU flamegraph (py-spy)
|
||||
```bash
|
||||
# 매 production-safe sampling profiler
|
||||
py-spy record -o flame.svg -d 60 -p $(pgrep -f gunicorn)
|
||||
py-spy top -p $(pgrep -f gunicorn)
|
||||
```
|
||||
|
||||
### Memory profiling (memray)
|
||||
```bash
|
||||
memray run --live ./app.py
|
||||
memray flamegraph output.bin -o memflame.html
|
||||
```
|
||||
|
||||
### Async IO efficiency
|
||||
```python
|
||||
import asyncio, httpx
|
||||
|
||||
# BAD — sequential
|
||||
async def fetch_seq(urls):
|
||||
async with httpx.AsyncClient() as c:
|
||||
return [await c.get(u) for u in urls]
|
||||
|
||||
# GOOD — concurrent
|
||||
async def fetch_par(urls):
|
||||
async with httpx.AsyncClient() as c:
|
||||
return await asyncio.gather(*[c.get(u) for u in urls])
|
||||
```
|
||||
|
||||
### Carbon-aware scheduling
|
||||
```python
|
||||
import httpx
|
||||
async def carbon_intensity(region: str) -> float:
|
||||
r = await httpx.AsyncClient().get(
|
||||
f"https://api.electricitymaps.com/v3/carbon-intensity/latest?zone={region}",
|
||||
headers={"auth-token": "TOKEN"})
|
||||
return r.json()["carbonIntensity"] # gCO2eq/kWh
|
||||
|
||||
# 매 batch job 매 low-carbon window 의 schedule
|
||||
async def maybe_run(region):
|
||||
ci = await carbon_intensity(region)
|
||||
if ci < 200: await run_batch()
|
||||
else: await asyncio.sleep(900)
|
||||
```
|
||||
|
||||
### LLM inference batching
|
||||
```python
|
||||
from vllm import LLM, SamplingParams
|
||||
llm = LLM(model="meta-llama/Llama-3.3-70B-Instruct",
|
||||
tensor_parallel_size=4,
|
||||
max_num_seqs=256) # 매 batch 의 throughput
|
||||
sp = SamplingParams(max_tokens=256)
|
||||
outs = llm.generate(prompts, sp) # 매 single forward pass 로 batch
|
||||
```
|
||||
|
||||
### Cache efficiency dashboard
|
||||
```promql
|
||||
# Prometheus query — cache hit ratio
|
||||
sum(rate(cache_hits_total[5m])) /
|
||||
(sum(rate(cache_hits_total[5m])) + sum(rate(cache_misses_total[5m])))
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Latency-critical (real-time) | tail-latency optimize, drop p99 outliers |
|
||||
| Throughput (batch) | parallelism, vectorize |
|
||||
| Cost 제약 | spot instance, autoscale, cache |
|
||||
| Green ops | carbon-aware scheduling, region selection |
|
||||
|
||||
**기본값**: 매 profile-first, 매 measure both before/after, 매 single-dimension fixation 매 X.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Site Reliability Engineering]]
|
||||
- 변형: [[Latency]]
|
||||
- 응용: [[Flame_Graphs]] · [[Profiling]]
|
||||
- Adjacent: [[FinOps]] · [[Green Software]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: profile output → bottleneck classification, optimization 후보 ranking.
|
||||
**언제 X**: 매 micro-benchmark 매 LLM 의 single-shot 평가 X — 매 측정 우선.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Premature optimization**: profile 없이 optimize.
|
||||
- **Single-metric obsession**: latency 만 보고 cost 폭증.
|
||||
- **Synthetic benchmark**: production traffic shape 무시.
|
||||
- **No baseline**: 매 before 측정 없이 "fast" 주장.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (SRE Workbook ch.4, AWS Well-Architected Performance pillar).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — efficiency 4 dimension + measurement loop |
|
||||
@@ -0,0 +1,165 @@
|
||||
---
|
||||
id: wiki-2026-0508-electron-v8-memory-cage
|
||||
title: Electron V8 Memory Cage
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [V8 Sandbox, V8 Pointer Compression Cage, Electron Memory Limit]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [electron, v8, security, memory, sandbox]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: javascript
|
||||
framework: electron
|
||||
---
|
||||
|
||||
# Electron V8 Memory Cage
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 V8 의 4GB virtual address cage"**. 매 V8 의 pointer compression (32-bit offset within 4GB cage) 의 introduction 의 each isolate 의 4GB heap limit 의 hard cap 의 impose. 매 Electron 의 main + renderer + utility process 의 each 의 separate cage 의 hold. 매 2026 년 의 V8 의 sandbox 의 default-on 의 spectre/heap-corruption mitigation 의 standard.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 cage 구조
|
||||
- **4GB virtual region** per V8 isolate.
|
||||
- **32-bit compressed pointer** (relative to cage base).
|
||||
- **All heap allocations** must fit inside cage.
|
||||
- **External buffer (ArrayBuffer backing)** can live outside (with sandbox checks).
|
||||
|
||||
### 매 Electron implication
|
||||
- 매 main process: 매 4GB cap.
|
||||
- 매 renderer process: 매 4GB cap each (per BrowserWindow).
|
||||
- 매 utility process: 매 separate cage.
|
||||
- 매 large data → utility process 또는 native module.
|
||||
|
||||
### 매 응용
|
||||
1. Heavy LLM inference UI (chunk via utility process).
|
||||
2. Video editor (native module for frame buffers).
|
||||
3. Multi-window archive viewer (split heaps per window).
|
||||
4. Out-of-process computation (worker_threads / utilityProcess).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Diagnose hitting cage limit
|
||||
```javascript
|
||||
const v8 = require('v8');
|
||||
const stats = v8.getHeapStatistics();
|
||||
console.log({
|
||||
total_heap_size_mb: stats.total_heap_size / 1024 / 1024,
|
||||
heap_size_limit_mb: stats.heap_size_limit / 1024 / 1024, // ~4GB
|
||||
external_memory_mb: stats.external_memory / 1024 / 1024,
|
||||
});
|
||||
```
|
||||
|
||||
### utilityProcess for off-cage work (Electron 25+)
|
||||
```javascript
|
||||
const { utilityProcess } = require('electron');
|
||||
|
||||
const child = utilityProcess.fork(path.join(__dirname, 'heavy-worker.js'), [], {
|
||||
serviceName: 'pdf-parser',
|
||||
// own V8 cage, own 4GB
|
||||
});
|
||||
child.postMessage({ task: 'parse', path: '/big.pdf' });
|
||||
child.on('message', (result) => { /* handle */ });
|
||||
```
|
||||
|
||||
### worker_thread (lighter, but shares process limits)
|
||||
```javascript
|
||||
const { Worker } = require('worker_threads');
|
||||
|
||||
const worker = new Worker('./inference-worker.js', {
|
||||
resourceLimits: { maxOldGenerationSizeMb: 3500 }
|
||||
});
|
||||
worker.postMessage({ tokens });
|
||||
worker.on('message', (output) => { /* ... */ });
|
||||
// NOTE: each worker has its own V8 cage
|
||||
```
|
||||
|
||||
### Native addon for >4GB buffers
|
||||
```cpp
|
||||
// node-addon-api: allocate outside V8 heap
|
||||
#include <napi.h>
|
||||
Napi::Value AllocLargeBuffer(const Napi::CallbackInfo& info) {
|
||||
size_t bytes = info[0].As<Napi::Number>().Int64Value();
|
||||
void* ptr = malloc(bytes); // outside V8 cage
|
||||
// wrap in ArrayBuffer with external backing store
|
||||
return Napi::ArrayBuffer::New(info.Env(), ptr, bytes,
|
||||
[](Napi::Env, void* data) { free(data); });
|
||||
}
|
||||
```
|
||||
|
||||
### Disable pointer compression (escape cage — NOT recommended)
|
||||
```bash
|
||||
# Only for dev / specific embedding; loses sandbox + perf
|
||||
electron --js-flags="--no-pointer-compression" .
|
||||
# Production: prefer process split
|
||||
```
|
||||
|
||||
### Memory-aware streaming pattern
|
||||
```javascript
|
||||
// Don't load 3GB JSON into V8 — stream + chunk
|
||||
const { pipeline } = require('stream/promises');
|
||||
const fs = require('fs');
|
||||
const { Transform } = require('stream');
|
||||
|
||||
await pipeline(
|
||||
fs.createReadStream('big.ndjson'),
|
||||
new Transform({
|
||||
transform(chunk, _, cb) {
|
||||
// process chunk — never accumulate full
|
||||
cb();
|
||||
}
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
### Per-window heap monitor
|
||||
```javascript
|
||||
mainWindow.webContents.on('render-process-gone', (event, details) => {
|
||||
if (details.reason === 'oom') {
|
||||
log.error('Renderer OOM — likely cage exhausted');
|
||||
relaunchWindow();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| < 1GB working set | Single renderer, no special handling |
|
||||
| 1-3GB | Monitor + GC pressure tuning |
|
||||
| 3-4GB approaching | utilityProcess 분리 |
|
||||
| > 4GB single dataset | Native addon + external buffer |
|
||||
| Many concurrent heavy ops | Multiple utilityProcess (each 4GB) |
|
||||
|
||||
**기본값**: 매 utilityProcess 의 split — 매 sandbox + cage 의 multiplication.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[V8 Engine]] · [[Electron]]
|
||||
- 변형: [[Chrome V8 Heap Analysis]]
|
||||
- Adjacent: [[Pointer Compression]] · [[V8 Sandbox]] · [[Garbage Collection]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 OOM crash diagnosis. 매 cage limit 의 explanation. 매 process-split refactor.
|
||||
**언제 X**: 매 V8 internal flag 의 latest 는 V8 release notes 의 verify.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Bigger `--max-old-space-size` only**: 매 4GB cap 의 hit. 매 size 만 의 늘림 의 X.
|
||||
- **Single-renderer 의 모든 work**: 매 cage 의 single 의 exhaust. 매 split.
|
||||
- **External buffer 의 forget GC**: 매 native addon 의 finalizer 의 mandatory.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (V8 pointer compression docs, Electron process model docs, V8 sandbox RFC).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — V8 cage / Electron process split |
|
||||
@@ -0,0 +1,225 @@
|
||||
---
|
||||
id: wiki-2026-0508-encapsulation-via-access-modifie
|
||||
title: Encapsulation via Access Modifiers
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Access Modifiers, Visibility Modifiers, Encapsulation]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [oop, encapsulation, access-modifier, language-design]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript
|
||||
framework: General
|
||||
---
|
||||
|
||||
# Encapsulation via Access Modifiers
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 internal state 의 hide + boundary 의 explicit"**. 1967 Simula 의 OOP 의 도입 후 매 Bertrand Meyer 의 "Design by Contract", Parnas 의 information hiding 원칙 의 codify — 2026 modern lang 는 `public/private/protected` 의 보다, JS `#private`, Rust module visibility, TS `readonly`, Java `sealed`, C# `init`-only 의 fine-grained capability 의 dominate.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Access modifier 의 종류 (lang 별)
|
||||
- **Java**: `public`, `protected`, package-private (default), `private`.
|
||||
- **C#**: `public`, `protected`, `internal`, `private`, `protected internal`, `private protected`, `file`.
|
||||
- **TypeScript**: `public` (default), `protected`, `private`, `#private` (true private — JS native).
|
||||
- **Rust**: `pub`, `pub(crate)`, `pub(super)`, `pub(in path)`, default private to module.
|
||||
- **Python**: convention only — `_underscore` (protected), `__double` (name-mangled).
|
||||
- **Kotlin**: `public` (default), `internal` (module), `protected`, `private`.
|
||||
|
||||
### 매 Encapsulation 의 layer
|
||||
- **Visibility**: who can see.
|
||||
- **Mutability**: `final`, `readonly`, `const`, `val`.
|
||||
- **Identity**: opaque type, newtype.
|
||||
- **Invariant**: setter validation, factory.
|
||||
|
||||
### 매 응용
|
||||
1. API 의 stable surface 의 maintain (semver).
|
||||
2. Library author 의 internal refactoring freedom.
|
||||
3. Test isolation (private — black-box test 의 강제).
|
||||
4. Security boundary (capability 의 leak 방지).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### TypeScript 의 `#private` (true private)
|
||||
```typescript
|
||||
class BankAccount {
|
||||
#balance = 0; // 매 runtime 의 private — TS `private` 의 erase 의 X
|
||||
readonly id: string;
|
||||
|
||||
constructor(id: string) { this.id = id; }
|
||||
|
||||
deposit(amount: number) {
|
||||
if (amount <= 0) throw new Error('positive only');
|
||||
this.#balance += amount;
|
||||
}
|
||||
get balance() { return this.#balance; }
|
||||
}
|
||||
|
||||
const a = new BankAccount('A1');
|
||||
// a.#balance = 999; // SyntaxError 의 compile + runtime
|
||||
```
|
||||
|
||||
### Rust 의 module visibility
|
||||
```rust
|
||||
mod auth {
|
||||
pub struct User {
|
||||
pub name: String,
|
||||
password_hash: String, // 매 module 외부 의 invisible
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub fn new(name: &str, pw: &str) -> Self {
|
||||
User { name: name.into(), password_hash: hash(pw) }
|
||||
}
|
||||
pub(crate) fn verify(&self, pw: &str) -> bool {
|
||||
self.password_hash == hash(pw)
|
||||
}
|
||||
}
|
||||
fn hash(s: &str) -> String { /* ... */ s.into() }
|
||||
}
|
||||
```
|
||||
|
||||
### Java sealed + record
|
||||
```java
|
||||
public sealed interface Shape permits Circle, Square, Triangle {}
|
||||
|
||||
public record Circle(double radius) implements Shape {
|
||||
public Circle { // 매 compact constructor 의 invariant
|
||||
if (radius < 0) throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
// 매 exhaustive switch 의 enable
|
||||
String describe(Shape s) {
|
||||
return switch (s) {
|
||||
case Circle c -> "circle r=" + c.radius();
|
||||
case Square sq -> "square";
|
||||
case Triangle t -> "tri";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### C# init-only + required
|
||||
```csharp
|
||||
public class Order
|
||||
{
|
||||
public required string Id { get; init; } // 매 set 의 only at init
|
||||
public DateTime Created { get; init; } = DateTime.UtcNow;
|
||||
private decimal _total;
|
||||
public decimal Total
|
||||
{
|
||||
get => _total;
|
||||
private set => _total = value >= 0 ? value :
|
||||
throw new ArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
var o = new Order { Id = "ORD-1" }; // 매 valid
|
||||
// o.Id = "X"; // 매 error: init-only
|
||||
```
|
||||
|
||||
### Python 의 convention + property
|
||||
```python
|
||||
class Vault:
|
||||
def __init__(self, secret):
|
||||
self._secret = secret # 매 protected (convention)
|
||||
self.__truly_hidden = "obfuscated" # 매 _Vault__truly_hidden
|
||||
|
||||
@property
|
||||
def secret(self):
|
||||
# 매 read-only 의 access
|
||||
return f"***{self._secret[-2:]}"
|
||||
|
||||
v = Vault("p@ssword")
|
||||
print(v.secret) # ***rd
|
||||
# v.secret = "x" # AttributeError
|
||||
```
|
||||
|
||||
### Capability-based design (no class)
|
||||
```typescript
|
||||
// 매 closure-based 의 information hiding
|
||||
function makeCounter() {
|
||||
let count = 0;
|
||||
return {
|
||||
inc: () => ++count,
|
||||
get: () => count,
|
||||
// 매 reset 의 reveal 안 하면 의 capability 의 absent
|
||||
};
|
||||
}
|
||||
const c = makeCounter();
|
||||
c.inc(); c.inc();
|
||||
console.log(c.get()); // 2 — count 의 access 의 X
|
||||
```
|
||||
|
||||
### Friend / internal API (Kotlin)
|
||||
```kotlin
|
||||
// 매 internal 의 same module 만의 access
|
||||
internal class IndexBuilder {
|
||||
internal fun rebuild() { /* ... */ }
|
||||
}
|
||||
|
||||
// 매 @PublishedApi 의 inline function 의 internal API 의 publish
|
||||
@PublishedApi
|
||||
internal fun secretImpl() = 42
|
||||
|
||||
inline fun publicWrapper() = secretImpl()
|
||||
```
|
||||
|
||||
### Newtype 의 opaque ID
|
||||
```rust
|
||||
pub struct UserId(u64); // 매 tuple struct 의 inner 의 private
|
||||
|
||||
impl UserId {
|
||||
pub fn new(id: u64) -> Self { UserId(id) }
|
||||
pub fn value(&self) -> u64 { self.0 }
|
||||
}
|
||||
|
||||
// 매 raw u64 의 mistakenly UserId 로 의 X — type-safe boundary
|
||||
fn get_user(id: UserId) { /* ... */ }
|
||||
// get_user(123); // compile error
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Library API | `pub` 의 minimal surface, internal 의 default |
|
||||
| Domain model | private field + factory + invariant |
|
||||
| DTO/value | `record` / `data class` / immutable |
|
||||
| JS/TS browser code | `#private` (true private) 의 default |
|
||||
| Cross-module refactoring | `internal`/`pub(crate)` 의 prefer |
|
||||
|
||||
**기본값**: most restrictive 의 default. 매 explicit 하 expand.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Object-Oriented Programming (OOP)]] · [[Information Hiding]]
|
||||
- 변형: [[Module System]]
|
||||
- 응용: [[API Design]] · [[Library Design]] · [[Refactoring_Best_Practices|Refactoring]]
|
||||
- Adjacent: [[Abstraction]] · [[SOLID]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: API surface review, accessor pattern 의 generate, visibility audit.
|
||||
**언제 X**: language-specific subtle case (Kotlin internal mangling 등) 의 verify 필수.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Public field**: encapsulation 의 broken — invariant 의 enforce 의 X.
|
||||
- **Getter/setter for everything**: encapsulation 의 illusion (Tell Don't Ask 위반).
|
||||
- **Reflection 의 private 의 bypass**: test 의 implementation 의 lock.
|
||||
- **Java private 의 inner class**: enclosing class 의 implicit access — confusion.
|
||||
- **TS `private` 의 trust**: runtime 의 erase — `#private` 사용.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Bloch "Effective Java" Item 15, Parnas 1972 "Decomposition", JLS, ECMA-262).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — TS/Rust/Java/C#/Kotlin/Python access patterns |
|
||||
@@ -0,0 +1,154 @@
|
||||
---
|
||||
id: wiki-2026-0508-engineering-metrics-dora
|
||||
title: Engineering Metrics (DORA)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [DORA, DORA Metrics, Four Keys, DevOps Research and Assessment]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [devops, metrics, dora, sre, engineering]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: yaml
|
||||
framework: github-actions
|
||||
---
|
||||
|
||||
# Engineering Metrics (DORA)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 deployment frequency, lead time, change fail rate, MTTR — 4 metric 으로 매 engineering org 의 health 측정"**. 매 2014 Google DORA team 의 launch, 매 2021 SPACE framework 보완, 매 2026 GitHub/GitLab/Datadog 의 native dashboard 의 default.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Four Keys
|
||||
- **Deployment Frequency (DF)**: 매 production deploy 의 빈도. Elite = on-demand (multiple/day).
|
||||
- **Lead Time for Changes (LT)**: 매 commit → production. Elite = < 1 day.
|
||||
- **Change Failure Rate (CFR)**: 매 deploy 의 incident 유발 비율. Elite = 0–15%.
|
||||
- **Mean Time to Recovery (MTTR)**: 매 incident → restore. Elite = < 1 hour.
|
||||
|
||||
### 매 Performance tier
|
||||
- **Elite**: DF on-demand · LT < 1day · CFR 0–15% · MTTR < 1h.
|
||||
- **High**: DF weekly–daily · LT 1day–1wk · CFR 16–30% · MTTR < 1day.
|
||||
- **Medium**: DF monthly · LT 1wk–1mo · CFR 16–30% · MTTR 1day–1wk.
|
||||
- **Low**: DF < monthly · LT > 1mo.
|
||||
|
||||
### 매 응용
|
||||
1. Sprint retro 매 주 review.
|
||||
2. Quarterly engineering OKR target.
|
||||
3. Hiring/promo signal (team-level, 매 individual 아님).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### GitHub Actions deployment frequency
|
||||
```yaml
|
||||
# .github/workflows/deploy.yml
|
||||
name: deploy
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: ./deploy.sh
|
||||
- name: Emit DORA event
|
||||
run: |
|
||||
curl -X POST https://api.dora-collector.internal/events \
|
||||
-H "Authorization: Bearer ${{ secrets.DORA_TOKEN }}" \
|
||||
-d '{"type":"deploy","sha":"${{ github.sha }}","ts":"'$(date -u +%FT%TZ)'"}'
|
||||
```
|
||||
|
||||
### Lead time calculation (SQL)
|
||||
```sql
|
||||
-- commits joined with deploys
|
||||
SELECT
|
||||
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (deploy_ts - commit_ts))/3600) AS p50_hours,
|
||||
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (deploy_ts - commit_ts))/3600) AS p95_hours
|
||||
FROM dora_events
|
||||
WHERE deploy_ts >= NOW() - INTERVAL '30 days';
|
||||
```
|
||||
|
||||
### Change failure rate from incidents
|
||||
```python
|
||||
# rolling 30d CFR
|
||||
def cfr(deploys: list[dict], incidents: list[dict]) -> float:
|
||||
bad_deploys = {i["deploy_sha"] for i in incidents if i["caused_by_deploy"]}
|
||||
return len(bad_deploys) / max(len(deploys), 1)
|
||||
```
|
||||
|
||||
### MTTR via PagerDuty
|
||||
```python
|
||||
import httpx, statistics
|
||||
def mttr(api_key: str, since: str) -> float:
|
||||
r = httpx.get("https://api.pagerduty.com/incidents",
|
||||
headers={"Authorization": f"Token token={api_key}"},
|
||||
params={"since": since, "statuses[]": "resolved"})
|
||||
durations = [(i["resolved_at_ts"] - i["created_at_ts"]) for i in r.json()["incidents"]]
|
||||
return statistics.median(durations) / 60 # minutes
|
||||
```
|
||||
|
||||
### Four Keys dashboard (Datadog)
|
||||
```yaml
|
||||
# datadog-dora.yaml
|
||||
widgets:
|
||||
- title: Deployment Frequency
|
||||
query: "sum:dora.deploy{*}.as_count().rollup(sum, 86400)"
|
||||
- title: Lead Time p50
|
||||
query: "p50:dora.lead_time_seconds{*}"
|
||||
- title: CFR
|
||||
query: "sum:dora.deploy_failed{*} / sum:dora.deploy{*}"
|
||||
- title: MTTR p50
|
||||
query: "p50:dora.incident_resolve_seconds{*}"
|
||||
```
|
||||
|
||||
### Trunk-based config (lead time 단축)
|
||||
```yaml
|
||||
# .github/branch-protection.yml
|
||||
required_status_checks:
|
||||
strict: true
|
||||
contexts: [ci/test, ci/lint]
|
||||
required_pull_request_reviews:
|
||||
required_approving_review_count: 1
|
||||
dismiss_stale_reviews: true
|
||||
restrictions: null # 매 직접 push 매 X — PR-only
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Startup (<20 eng) | DF + LT 매 우선, MTTR 매 secondary |
|
||||
| Regulated industry | CFR 매 primary (release safety) |
|
||||
| Platform team | All 4, 매 weekly review |
|
||||
| Individual perf review | 매 X — team metric only |
|
||||
|
||||
**기본값**: 매 four-keys-platform (Google open source) self-host + Grafana.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[DevOps]] · [[Site Reliability Engineering]]
|
||||
- 응용: [[Continuous Delivery]] · [[Continuous Integration]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: deploy log → metric extraction, incident root-cause 분류 (deploy 유발 여부).
|
||||
**언제 X**: 매 individual contributor scoring 매 X — DORA 매 team-level only.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Goodharting**: DF 만 chase 하고 quality 무시 → CFR 폭증.
|
||||
- **Individual scoring**: developer 별 LT 측정 → gaming (small commits 만).
|
||||
- **Vanity rollups**: org-wide average — 팀 distribution 의 hide.
|
||||
- **No CFR**: deploy 만 count, failure track X → false elite signal.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (DORA "State of DevOps" 2014–2024 reports, Google Cloud 공식).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — DORA four-keys 정의 + dashboard pattern |
|
||||
@@ -0,0 +1,158 @@
|
||||
---
|
||||
id: wiki-2026-0508-ensuring-data-privacy
|
||||
title: Ensuring Data Privacy
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Data Privacy, Privacy Engineering, GDPR Compliance]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [privacy, gdpr, security, compliance]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: applied
|
||||
tech_stack:
|
||||
language: Python/TypeScript
|
||||
framework: OneTrust/Fides/OPA
|
||||
---
|
||||
|
||||
# Ensuring Data Privacy
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 personal data 가 lawful basis + minimum + purpose-limited 로 다뤄진다."**. Data privacy engineering 은 매 GDPR/CCPA/LGPD/K-PIPA 의 legal requirement 를 매 storage, processing, transfer, retention 의 매 단계 에 deterministic control 로 구현. 2026 stack: classification + DLP + tokenization/PETs (DP, FHE, TEE) + consent management + DSAR automation + privacy-by-design.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Privacy Principle (GDPR Art.5)
|
||||
1. **Lawfulness, fairness, transparency** — consent / legitimate interest.
|
||||
2. **Purpose limitation** — 매 collected purpose 외 사용 금지.
|
||||
3. **Data minimization** — 매 필요한 최소.
|
||||
4. **Accuracy** — correctable.
|
||||
5. **Storage limitation** — retention schedule.
|
||||
6. **Integrity & confidentiality** — encryption.
|
||||
7. **Accountability** — DPO, audit, DPIA.
|
||||
|
||||
### 매 PET (Privacy-Enhancing Tech) 2026
|
||||
- **Pseudonymization**: tokenization, format-preserving encryption (FPE).
|
||||
- **Anonymization**: k-anonymity, l-diversity, t-closeness.
|
||||
- **Differential Privacy**: ε,δ noise — Apple, US Census, Chrome.
|
||||
- **Federated learning**: 매 model travels, data stays.
|
||||
- **Homomorphic encryption (FHE)**: 매 compute on encrypted — Microsoft SEAL, OpenFHE.
|
||||
- **Confidential computing (TEE)**: Intel TDX, AMD SEV-SNP, Apple Private Cloud Compute.
|
||||
- **Zero-Knowledge Proofs**: identity 증명 without disclose.
|
||||
|
||||
### 매 응용
|
||||
1. EU GDPR + 한국 PIPA + 중국 PIPL compliance.
|
||||
2. Healthcare HIPAA, PCI-DSS payment.
|
||||
3. ML training without raw data (FL, DP).
|
||||
4. Cross-border transfer (SCC, BCR, DPF).
|
||||
5. Right to be forgotten (RTBF) automation.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Data classification + DLP
|
||||
```python
|
||||
# 매 PII detection — Microsoft Presidio
|
||||
from presidio_analyzer import AnalyzerEngine
|
||||
analyzer = AnalyzerEngine()
|
||||
results = analyzer.analyze(text=user_input, language='en',
|
||||
entities=['EMAIL_ADDRESS','PHONE_NUMBER','CREDIT_CARD','PERSON','KR_RRN'])
|
||||
for r in results: redact_or_mask(text, r.start, r.end)
|
||||
```
|
||||
|
||||
### Format-preserving tokenization
|
||||
```python
|
||||
# 매 ff3-1 — preserves format (e.g., card number)
|
||||
from ff3 import FF3Cipher
|
||||
c = FF3Cipher(key, tweak)
|
||||
token = c.encrypt("4242424242424242") # → 16-digit string
|
||||
plain = c.decrypt(token)
|
||||
```
|
||||
|
||||
### Differential Privacy noise
|
||||
```python
|
||||
import numpy as np
|
||||
def laplace_mechanism(true_val, sensitivity, epsilon):
|
||||
return true_val + np.random.laplace(0, sensitivity / epsilon)
|
||||
# 매 query: count of users in segment
|
||||
noisy_count = laplace_mechanism(true_count=1234, sensitivity=1, epsilon=1.0)
|
||||
```
|
||||
|
||||
### k-anonymity check
|
||||
```python
|
||||
import pandas as pd
|
||||
def k_anonymity(df: pd.DataFrame, quasi_ids: list[str]) -> int:
|
||||
return df.groupby(quasi_ids).size().min()
|
||||
# 매 ensure k>=5 before release
|
||||
assert k_anonymity(df, ['zip','age','gender']) >= 5
|
||||
```
|
||||
|
||||
### DSAR (Data Subject Access Request) automation
|
||||
```python
|
||||
async def dsar_export(user_id: str) -> bytes:
|
||||
bundle = {
|
||||
'profile': await db.users.find_one({'_id':user_id}),
|
||||
'orders': [o async for o in db.orders.find({'userId':user_id})],
|
||||
'logs': await elasticsearch_export(user_id),
|
||||
}
|
||||
return json.dumps(bundle, default=str).encode()
|
||||
|
||||
async def dsar_erasure(user_id: str):
|
||||
await db.users.update_one({'_id':user_id},
|
||||
{'$set': {'email':None,'name':None,'erasedAt':datetime.utcnow()}})
|
||||
await s3.delete_objects(Bucket='pii', Prefix=f'users/{user_id}/')
|
||||
```
|
||||
|
||||
### Consent record (Fides/IAB TCF)
|
||||
```typescript
|
||||
const consent = {
|
||||
userId: 'u_123',
|
||||
purposes: { analytics: true, marketing: false, personalization: true },
|
||||
vendors: { google: true },
|
||||
timestamp: new Date().toISOString(),
|
||||
version: 'tcf-2.2',
|
||||
signature: hmac(record),
|
||||
};
|
||||
await db.consents.insertOne(consent);
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| EU users | GDPR + Schrems II SCC |
|
||||
| 한국 users | PIPA — 개인정보처리방침, 위탁 동의 |
|
||||
| Aggregate analytics | Differential Privacy |
|
||||
| Payment data | PCI-DSS tokenization |
|
||||
| ML training | Federated learning + DP |
|
||||
| Cross-org compute | TEE (Confidential Computing) |
|
||||
|
||||
**기본값**: 매 minimize + classify + tokenize + consent ledger + DSAR API.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Practical-Cryptography]] · [[보안 및 시스템 신뢰성 표준|Symmetric-Encryption]]
|
||||
- 변형: [[보안 및 시스템 신뢰성 표준|Zero-Trust Architecture]]
|
||||
- 응용: [[Anomaly-Detection]] · [[Information-Society]]
|
||||
- Adjacent: [[Digital Intellectual Property Rights]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: privacy policy 검토, DSAR response draft, PIA 질문 generation.
|
||||
**언제 X**: 매 PII 를 third-party LLM 에 raw 로 전송 — anonymize 먼저.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Hash = anonymized 오해**: 매 hash 는 pseudonymization, GDPR 적용.
|
||||
- **Consent on entry-only**: 매 ongoing — withdrawable, granular.
|
||||
- **Log PII**: 매 logger 가 leak source — redact filter.
|
||||
- **Forever retention**: 매 GDPR 위반 — TTL + erasure.
|
||||
- **Plaintext backup**: 매 encryption at rest 필수.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified: GDPR Art.5/17/25; ISO/IEC 27701; NIST SP 800-188; Microsoft Presidio docs.
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — principles + PETs + DSAR/DP patterns |
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
---
|
||||
id: wiki-2026-0508-enterprise-scale-monorepo-manage
|
||||
title: Enterprise Scale Monorepo Management
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Monorepo, Polyrepo vs Monorepo, Bazel, Nx, Turborepo]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [monorepo, build-system, devops, ci-cd, scaling]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: nx-turborepo-bazel
|
||||
---
|
||||
|
||||
# Enterprise Scale Monorepo Management
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 single repo, many projects — 매 build graph 의 일관성"**. 매 monorepo 의 핵심은 모든 코드를 하나의 VCS root 안에 두되, 매 build 시스템이 dependency graph 를 이해해서 affected projects 만 build/test 한다는 점. Google (Piper/Bazel), Meta (Buck2), Microsoft (Rush), 그리고 매 OSS 의 Nx/Turborepo 가 이 패러다임을 driving.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Monorepo 가치
|
||||
- **Atomic cross-project changes**: 매 API + caller 의 한 PR 안에서 변경.
|
||||
- **Shared tooling**: 매 lint, format, build, test 의 unified config.
|
||||
- **Visibility**: 매 모든 코드 의 grep-able.
|
||||
- **Refactor confidence**: 매 type-checker 가 모든 caller 를 검증.
|
||||
|
||||
### 매 도전 과제
|
||||
- **Build time scaling**: 매 naive build 의 N² growth — affected detection 필수.
|
||||
- **VCS performance**: 매 git 의 100GB+ repo 에서 sparse checkout / VFS 필요.
|
||||
- **Permissions**: 매 single repo + multiple teams = CODEOWNERS / branch protection.
|
||||
- **CI cost**: 매 모든 commit 의 모든 project rebuild 의 X — incremental + cache.
|
||||
|
||||
### 매 도구 선택
|
||||
1. **Nx** (TypeScript-heavy, mid-large): smart caching + computation graph.
|
||||
2. **Turborepo** (Vercel, JS/TS): Rust-based, simple config, remote cache.
|
||||
3. **Bazel** (polyglot, mega-scale): hermetic builds, network-distributed.
|
||||
4. **Pants** (Python-heavy): similar to Bazel, lighter setup.
|
||||
5. **Rush** (.NET / TS): Microsoft's pnpm-based.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Nx workspace structure
|
||||
```bash
|
||||
my-org/
|
||||
├── nx.json
|
||||
├── package.json
|
||||
├── tsconfig.base.json
|
||||
├── apps/
|
||||
│ ├── web/ # Next.js app
|
||||
│ └── api/ # NestJS API
|
||||
├── libs/
|
||||
│ ├── ui/ # shared React components
|
||||
│ ├── data-access/# API clients
|
||||
│ └── utils/
|
||||
└── tools/
|
||||
```
|
||||
|
||||
### nx.json with affected + cache
|
||||
```json
|
||||
{
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "nx-cloud",
|
||||
"options": {
|
||||
"cacheableOperations": ["build", "test", "lint", "e2e"],
|
||||
"accessToken": "${NX_CLOUD_TOKEN}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"targetDefaults": {
|
||||
"build": { "dependsOn": ["^build"], "inputs": ["production", "^production"] },
|
||||
"test": { "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"] }
|
||||
},
|
||||
"namedInputs": {
|
||||
"default": ["{projectRoot}/**/*", "sharedGlobals"],
|
||||
"production": ["default", "!{projectRoot}/**/*.spec.ts", "!{projectRoot}/jest.config.ts"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Affected detection in CI
|
||||
```yaml
|
||||
# .github/workflows/ci.yml
|
||||
jobs:
|
||||
affected:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with: { fetch-depth: 0 }
|
||||
- uses: nrwl/nx-set-shas@v4
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: npx nx affected -t lint test build --parallel=4
|
||||
- run: npx nx affected -t e2e --parallel=1
|
||||
```
|
||||
|
||||
### Turborepo pipeline
|
||||
```json
|
||||
// turbo.json
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"globalDependencies": ["**/.env.*local"],
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
|
||||
},
|
||||
"test": { "dependsOn": ["build"], "outputs": ["coverage/**"] },
|
||||
"lint": {},
|
||||
"dev": { "cache": false, "persistent": true }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Bazel BUILD file (polyglot)
|
||||
```python
|
||||
# libs/ui/BUILD.bazel
|
||||
load("@npm//:defs.bzl", "npm_link_all_packages")
|
||||
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
|
||||
|
||||
ts_project(
|
||||
name = "ui",
|
||||
srcs = glob(["src/**/*.ts", "src/**/*.tsx"]),
|
||||
declaration = True,
|
||||
tsconfig = "//:tsconfig",
|
||||
deps = [
|
||||
"//libs/utils",
|
||||
"@npm//react",
|
||||
"@npm//@types/react",
|
||||
],
|
||||
visibility = ["//apps:__subpackages__"],
|
||||
)
|
||||
```
|
||||
|
||||
### CODEOWNERS for team boundaries
|
||||
```
|
||||
# CODEOWNERS
|
||||
/apps/web/ @org/frontend-team
|
||||
/apps/api/ @org/backend-team
|
||||
/libs/ui/ @org/design-system
|
||||
/libs/data-access/ @org/backend-team @org/frontend-team
|
||||
/.github/ @org/platform-team
|
||||
/tools/ @org/platform-team
|
||||
```
|
||||
|
||||
### Remote cache with Turborepo
|
||||
```bash
|
||||
# Self-hosted with turborepo-remote-cache
|
||||
docker run -p 3000:3000 \
|
||||
-e TURBO_TOKEN=secret \
|
||||
-e STORAGE_PROVIDER=s3 \
|
||||
-e STORAGE_PATH=my-bucket \
|
||||
ducktors/turborepo-remote-cache
|
||||
|
||||
# In repo:
|
||||
echo 'TURBO_API=http://cache.internal:3000' > .turbo/config.json
|
||||
echo 'TURBO_TOKEN=secret' >> .turbo/config.json
|
||||
turbo build --remote-only
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| <50 packages, JS/TS only | Turborepo (simplicity) |
|
||||
| 50-500 packages, type-heavy | Nx (project graph + generators) |
|
||||
| Polyglot (Go+Rust+TS+Python) | Bazel (hermeticity) |
|
||||
| Python ML monorepo | Pants v2 |
|
||||
| <10 packages | pnpm workspaces alone |
|
||||
|
||||
**기본값**: 매 TS/JS team 에게 Turborepo 또는 Nx (size dependent).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Version Control]]
|
||||
- 응용: [[Code Ownership]]
|
||||
- Adjacent: [[Bazel]] · [[Nx]] · [[Turborepo]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: refactoring across packages, generating new lib boilerplate (Nx generator), CODEOWNERS automation, dependency graph 분석.
|
||||
**언제 X**: 매 build cache invalidation logic 의 직접 결정 — Nx/Bazel hash algorithm 신뢰.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Single CI job for entire repo**: 매 affected detection 없이 매 commit 모든 build — 30분+ pipeline.
|
||||
- **No remote cache**: 매 each developer 가 cold rebuild — wasteful.
|
||||
- **Mixing app-specific and lib code**: 매 libs/ 와 apps/ 의 분리 안 함 — circular deps risk.
|
||||
- **Implicit dependencies**: 매 package.json 에 list 안 된 import — Bazel/Nx 가 catch.
|
||||
- **No CODEOWNERS**: 매 review fatigue + ownership 모호.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Nx Cloud docs 2026, Turborepo 2.0, Bazel 7).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — monorepo tooling matrix + Nx/Turbo/Bazel patterns |
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
id: wiki-2026-0508-feature-flags
|
||||
title: Feature Flags
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Feature Toggles, Feature Switches, Feature Gates]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [devops, deployment, experimentation, release-engineering]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript/Go
|
||||
framework: LaunchDarkly/Unleash/OpenFeature
|
||||
---
|
||||
|
||||
# Feature Flags
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 deploy 와 release 를 매 분리하는 runtime conditional"**. Pete Hodgson 의 매 4-axis taxonomy (release/experiment/ops/permission) 가 매 baseline. 매 modern stack — OpenFeature spec + provider (LaunchDarkly, Unleash, ConfigCat, Statsig) — 매 progressive delivery, A/B test, kill switch 의 매 통합 layer.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 4 종류 (Hodgson)
|
||||
- **Release toggle**: dark launch, gradual rollout (short-lived).
|
||||
- **Experiment toggle**: A/B/n test (medium-lived).
|
||||
- **Ops toggle**: kill switch, circuit breaker (medium-lived).
|
||||
- **Permission toggle**: per-user/tenant entitlement (long-lived).
|
||||
|
||||
### 매 axis
|
||||
- Lifetime: hours ↔ years.
|
||||
- Dynamism: build-time → runtime → request-time.
|
||||
- Scope: global → user → request.
|
||||
|
||||
### 매 응용
|
||||
1. Trunk-based development + dark launch.
|
||||
2. Canary / progressive rollout (1% → 100%).
|
||||
3. Kill switch (incident mitigation).
|
||||
4. A/B testing & holdout group.
|
||||
5. Tier-based feature gating (free/pro/enterprise).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### OpenFeature SDK (vendor-neutral)
|
||||
```typescript
|
||||
import { OpenFeature } from '@openfeature/server-sdk';
|
||||
import { LaunchDarklyProvider } from '@openfeature/launchdarkly-server-provider';
|
||||
|
||||
await OpenFeature.setProviderAndWait(new LaunchDarklyProvider(SDK_KEY));
|
||||
const client = OpenFeature.getClient();
|
||||
|
||||
const showNew = await client.getBooleanValue('new-checkout', false, {
|
||||
targetingKey: user.id,
|
||||
email: user.email,
|
||||
plan: user.plan,
|
||||
});
|
||||
return showNew ? renderNewCheckout() : renderOldCheckout();
|
||||
```
|
||||
|
||||
### Percentage rollout (deterministic hash)
|
||||
```go
|
||||
import "hash/fnv"
|
||||
func rollout(flagKey, userID string, percent int) bool {
|
||||
h := fnv.New32a()
|
||||
h.Write([]byte(flagKey + ":" + userID))
|
||||
return int(h.Sum32()%100) < percent
|
||||
}
|
||||
// Same user → same bucket across calls (sticky).
|
||||
```
|
||||
|
||||
### Kill switch (ops toggle)
|
||||
```typescript
|
||||
async function fetchRecommendations(userId: string) {
|
||||
if (await flags.getBooleanValue('reco-kill-switch', false)) {
|
||||
return []; // disable the feature instantly during incident
|
||||
}
|
||||
return recoService.fetch(userId);
|
||||
}
|
||||
```
|
||||
|
||||
### Multivariate experiment
|
||||
```typescript
|
||||
const variant = await client.getStringValue('checkout-variant', 'control', ctx);
|
||||
switch (variant) {
|
||||
case 'one-click': return <OneClickCheckout />;
|
||||
case 'wallet': return <WalletCheckout />;
|
||||
default: return <StandardCheckout />;
|
||||
}
|
||||
metrics.track('checkout_view', { variant, userId });
|
||||
```
|
||||
|
||||
### Local override (dev/test)
|
||||
```typescript
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
OpenFeature.setProvider(new InMemoryProvider({
|
||||
'new-checkout': { defaultVariant: 'on', variants: { on: true, off: false } },
|
||||
}));
|
||||
}
|
||||
```
|
||||
|
||||
### Flag cleanup (technical debt)
|
||||
```bash
|
||||
# Find old flags
|
||||
rg "getBooleanValue\\('old-checkout'" --type ts
|
||||
# Provider audit: list flags > 90 days old, no recent eval, 100% rollout → delete.
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Dark launch / gradual | Release toggle, percentage rollout |
|
||||
| Hypothesis test | Experiment toggle + analytics |
|
||||
| Incident mitigation | Ops toggle (always available) |
|
||||
| Tier / paid features | Permission toggle (long-lived) |
|
||||
| Build-time only | Compile flag (no runtime cost) |
|
||||
|
||||
**기본값**: OpenFeature SDK + managed provider (LaunchDarkly/Unleash). Kill switch 모든 critical path 에 매.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Continuous Delivery]] · [[Progressive Delivery]]
|
||||
- 변형: [[Kill Switch]]
|
||||
- 응용: [[Trunk-based Development]]
|
||||
- Adjacent: [[LaunchDarkly]] · [[Unleash]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Release strategy 설계, incident playbook, experiment platform 평가.
|
||||
**언제 X**: Static config — env var / config file 충분.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Flag debt**: 100% rolled-out flag 를 매 안 지움 → cyclomatic complexity 폭발.
|
||||
- **Nested flags**: A&&B&&C — 매 test space 매 explosion.
|
||||
- **Flag in hot loop**: per-request eval 의 매 latency — cache locally.
|
||||
- **No fallback**: provider 다운 시 feature 깨짐 — default + cached value.
|
||||
- **Flag = config 오용**: 진짜 config 는 매 config service 로.
|
||||
- **No analytics linkage**: experiment 인데 evaluation 안 records.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (martinfowler.com Feature Toggles, OpenFeature spec, LaunchDarkly docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — 4-axis taxonomy + OpenFeature/percentage/kill-switch 패턴 |
|
||||
@@ -0,0 +1,183 @@
|
||||
---
|
||||
id: wiki-2026-0508-figma-to-code-workflow
|
||||
title: Figma to Code Workflow
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Figma to React, Design to Code, Design Token Pipeline]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [figma, design-system, tokens, react, workflow]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: react
|
||||
---
|
||||
|
||||
# Figma to Code Workflow
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 design token 을 single source of truth — 매 Figma Variables → JSON → CSS/TS 의 자동 sync"**. 매 2023 Figma Variables launch 후 표준화, 매 2026 Figma Code Connect + Style Dictionary + LLM-assisted MCP server 가 default workflow.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Pipeline 단계
|
||||
1. **Design**: Figma Variables (color, spacing, typography).
|
||||
2. **Export**: Figma API or Tokens Studio plugin → JSON.
|
||||
3. **Transform**: Style Dictionary → CSS vars + TS types.
|
||||
4. **Consume**: components import tokens, 매 hardcode X.
|
||||
|
||||
### 매 Component sync 방식
|
||||
- **Code Connect**: Figma component ↔ React component pin.
|
||||
- **Storybook**: Figma plugin 의 design ↔ story link.
|
||||
- **Visual regression**: Chromatic — 매 token diff 의 detection.
|
||||
|
||||
### 매 응용
|
||||
1. Multi-brand theming: tokens swap → 매 component 의 unchanged.
|
||||
2. Dark mode: light/dark variable mode toggle.
|
||||
3. A11y: contrast token 자동 검증.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Figma Variables export (REST)
|
||||
```ts
|
||||
// scripts/fetch-figma-tokens.ts
|
||||
import { writeFileSync } from 'node:fs';
|
||||
const FILE_KEY = process.env.FIGMA_FILE_KEY!;
|
||||
const TOKEN = process.env.FIGMA_TOKEN!;
|
||||
|
||||
const r = await fetch(
|
||||
`https://api.figma.com/v1/files/${FILE_KEY}/variables/local`,
|
||||
{ headers: { 'X-Figma-Token': TOKEN } }
|
||||
);
|
||||
const { meta } = await r.json();
|
||||
writeFileSync('tokens/figma.json', JSON.stringify(meta, null, 2));
|
||||
```
|
||||
|
||||
### Style Dictionary config
|
||||
```js
|
||||
// style-dictionary.config.js
|
||||
module.exports = {
|
||||
source: ['tokens/**/*.json'],
|
||||
platforms: {
|
||||
css: {
|
||||
transformGroup: 'css',
|
||||
buildPath: 'src/styles/',
|
||||
files: [{ destination: 'tokens.css', format: 'css/variables' }]
|
||||
},
|
||||
ts: {
|
||||
transformGroup: 'js',
|
||||
buildPath: 'src/tokens/',
|
||||
files: [{
|
||||
destination: 'index.ts',
|
||||
format: 'javascript/es6',
|
||||
options: { outputReferences: true }
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Tailwind config consuming tokens
|
||||
```ts
|
||||
// tailwind.config.ts
|
||||
import tokens from './src/tokens';
|
||||
export default {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: tokens.color,
|
||||
spacing: tokens.spacing,
|
||||
fontSize: tokens.font.size
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Figma Code Connect (React)
|
||||
```tsx
|
||||
// Button.figma.tsx
|
||||
import figma from '@figma/code-connect';
|
||||
import { Button } from './Button';
|
||||
|
||||
figma.connect(Button, 'https://figma.com/file/X/?node-id=1:23', {
|
||||
props: {
|
||||
variant: figma.enum('Variant', { Primary: 'primary', Ghost: 'ghost' }),
|
||||
size: figma.enum('Size', { Small: 'sm', Medium: 'md', Large: 'lg' }),
|
||||
label: figma.textContent('Label')
|
||||
},
|
||||
example: ({ variant, size, label }) => (
|
||||
<Button variant={variant} size={size}>{label}</Button>
|
||||
)
|
||||
});
|
||||
```
|
||||
|
||||
### MCP server (Claude/Cursor 의 Figma read)
|
||||
```json
|
||||
// .mcp.json
|
||||
{
|
||||
"mcpServers": {
|
||||
"figma": {
|
||||
"command": "npx",
|
||||
"args": ["@figma/mcp-server", "--file", "FILE_KEY"],
|
||||
"env": { "FIGMA_TOKEN": "${FIGMA_TOKEN}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CI: token drift detection
|
||||
```yaml
|
||||
# .github/workflows/tokens.yml
|
||||
on: { schedule: [{ cron: '0 9 * * 1-5' }] }
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: pnpm i && pnpm tsx scripts/fetch-figma-tokens.ts
|
||||
- run: pnpm style-dictionary build
|
||||
- uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
title: 'chore: sync Figma tokens'
|
||||
branch: tokens/auto-sync
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Single brand, small | CSS vars manual export |
|
||||
| Multi-brand or theming | Style Dictionary + modes |
|
||||
| Tight design↔code coupling | Code Connect + Storybook |
|
||||
| LLM-assisted dev | Figma MCP server |
|
||||
|
||||
**기본값**: Figma Variables → Style Dictionary → Tailwind/CSS vars + Code Connect.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Design System]] · [[Large_Frontend_Projects|Frontend Architecture]]
|
||||
- 변형: [[Design Tokens]]
|
||||
- 응용: [[Storybook]] · [[Component Library]]
|
||||
- Adjacent: [[CSS_Architecture_and_Styling|Tailwind CSS]] · [[Visual Regression]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Figma MCP → component spec → React scaffold (props, variants 자동).
|
||||
**언제 X**: 매 pixel-perfect layout 매 manual hand-off 의 X — LLM 매 약함.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Hardcoded hex**: `color: #FF6B6B` 매 component 안에 — token swap 매 불가.
|
||||
- **One-way sync**: code → Figma 의 reverse 무시 → drift.
|
||||
- **No transform layer**: Figma JSON 매 직접 import — 매 platform-specific 변환 X.
|
||||
- **Ignoring modes**: light/dark 매 separate file → maintenance hell.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Figma Variables docs, Style Dictionary 4.x, Code Connect 1.x).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Figma → Style Dictionary → React pipeline |
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
id: wiki-2026-0508-figma
|
||||
title: Figma
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Figma Design, FigJam, Dev Mode]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [design, design-tool, collaboration, design-system]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript
|
||||
framework: Figma-Plugin-API/REST-API
|
||||
---
|
||||
|
||||
# Figma
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 browser-native, multiplayer, vector design tool 의 매 default standard"**. Field & Wallace 2012 시작 — CRDT-based multiplayer + WebGL canvas + plugin ecosystem 으로 매 Sketch/XD 를 매 시장에서 displace. 매 2025 Adobe 인수 무산 후 independent, AI 기능 (Make Designs, Visual Search) 추가, Dev Mode 가 매 디자인-코드 핸드오프 표준.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 architecture
|
||||
- WebGL canvas (GPU-accelerated vector rendering).
|
||||
- Multiplayer via OT/CRDT — sub-100ms cursor sync.
|
||||
- File = node tree (Document → Page → Frame → ...).
|
||||
- Component / variant / variable system.
|
||||
|
||||
### 매 핵심 primitive
|
||||
- **Frame**: layout container (auto-layout = flexbox-like).
|
||||
- **Component / Instance**: reusable + override.
|
||||
- **Variable**: design token (color, number, string, boolean) — mode 별 (light/dark).
|
||||
- **Style**: deprecated 추세, variable 로 대체.
|
||||
|
||||
### 매 응용
|
||||
1. Design system 운영 (component library, token).
|
||||
2. Prototyping (interactive flow).
|
||||
3. Dev handoff (Dev Mode + code generation).
|
||||
4. Whiteboard / brainstorming (FigJam).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Plugin: rename selection
|
||||
```typescript
|
||||
// manifest.json: { "main": "code.ts", "ui": "ui.html", "editorType": ["figma"] }
|
||||
figma.showUI(__html__, { width: 240, height: 120 });
|
||||
figma.ui.onmessage = (msg: { type: string; prefix: string }) => {
|
||||
if (msg.type === 'rename') {
|
||||
for (const node of figma.currentPage.selection) {
|
||||
node.name = `${msg.prefix}_${node.name}`;
|
||||
}
|
||||
figma.notify(`Renamed ${figma.currentPage.selection.length}`);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Variable mode swap (dark mode)
|
||||
```typescript
|
||||
const collection = figma.variables.getLocalVariableCollections()
|
||||
.find(c => c.name === 'Theme')!;
|
||||
const darkModeId = collection.modes.find(m => m.name === 'Dark')!.modeId;
|
||||
figma.currentPage.setExplicitVariableModeForCollection(collection, darkModeId);
|
||||
```
|
||||
|
||||
### REST API: export frames as PNG
|
||||
```typescript
|
||||
const FILE = 'abc123', TOKEN = process.env.FIGMA_TOKEN!;
|
||||
const r = await fetch(`https://api.figma.com/v1/files/${FILE}`, {
|
||||
headers: { 'X-Figma-Token': TOKEN }
|
||||
});
|
||||
const file = await r.json();
|
||||
const frameIds = file.document.children.flatMap(p =>
|
||||
p.children.filter(n => n.type === 'FRAME').map(n => n.id));
|
||||
const exp = await fetch(
|
||||
`https://api.figma.com/v1/images/${FILE}?ids=${frameIds.join(',')}&format=png&scale=2`,
|
||||
{ headers: { 'X-Figma-Token': TOKEN } }
|
||||
);
|
||||
const { images } = await exp.json(); // { id: url }
|
||||
```
|
||||
|
||||
### Token export → Style Dictionary
|
||||
```typescript
|
||||
// figma-token-bridge plugin output
|
||||
const tokens = figma.variables.getLocalVariables().map(v => ({
|
||||
name: v.name.replace(/\//g, '.'),
|
||||
value: v.valuesByMode[defaultMode],
|
||||
type: v.resolvedType,
|
||||
}));
|
||||
figma.ui.postMessage({ type: 'export', tokens });
|
||||
// Then transform to Style Dictionary JSON → CSS / iOS / Android.
|
||||
```
|
||||
|
||||
### Auto-layout (component definition)
|
||||
```typescript
|
||||
const frame = figma.createFrame();
|
||||
frame.layoutMode = 'HORIZONTAL';
|
||||
frame.primaryAxisAlignItems = 'CENTER';
|
||||
frame.counterAxisAlignItems = 'CENTER';
|
||||
frame.itemSpacing = 8;
|
||||
frame.paddingLeft = frame.paddingRight = 16;
|
||||
frame.paddingTop = frame.paddingBottom = 12;
|
||||
frame.cornerRadius = 8;
|
||||
```
|
||||
|
||||
### Webhook: sync to repo
|
||||
```typescript
|
||||
// Figma webhook → CI → token regenerate → PR
|
||||
app.post('/figma-webhook', async (req, res) => {
|
||||
if (req.body.event_type === 'FILE_UPDATE') {
|
||||
await exec('npm run tokens:pull && npm run tokens:build');
|
||||
await octokit.pulls.create({ /* ... */ });
|
||||
}
|
||||
res.sendStatus(200);
|
||||
});
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 디자인 시스템 신규 구축 | Variables + Component + auto-layout |
|
||||
| 디자인-코드 sync | Webhook + Style Dictionary pipeline |
|
||||
| Vector illustration | Figma 또는 매 Illustrator (Figma 충분 in 2026) |
|
||||
| 3D/motion | Figma X — Spline / After Effects |
|
||||
| Real-time whiteboard | FigJam |
|
||||
|
||||
**기본값**: Component + auto-layout + variable. Style 은 매 deprecated.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[FigJam]]
|
||||
- 응용: [[Design System]] · [[Dev Mode]]
|
||||
- Adjacent: [[Style Dictionary Pipelines|Style Dictionary]] · [[Storybook]] · [[Tokens Studio]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Design system architecture, plugin authoring, design-code pipeline.
|
||||
**언제 X**: Vector math 자체 — SVG/Skia primitive 학습 우선.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Detached instance 남발**: 매 component 의 의미 사라짐.
|
||||
- **Style + Variable 혼용**: 매 variable 로 통일.
|
||||
- **No naming convention**: `Frame 1234` 가 매 디자인 시스템 죽임.
|
||||
- **Manual handoff (JPG export)**: Dev Mode 또는 매 token pipeline 사용.
|
||||
- **Unversioned**: Branching feature (Org plan) 사용.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Figma docs, Plugin API ref, Dev Mode 2024 release notes).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Figma primitives + plugin/REST/token patterns |
|
||||
@@ -0,0 +1,175 @@
|
||||
---
|
||||
id: wiki-2026-0508-flame-graphs
|
||||
title: Flame Graphs
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Flamegraph, Stack Trace Visualization, Brendan Gregg Flame Graph]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [profiling, performance, observability, perf, ebpf]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: rust
|
||||
framework: perf-pyspy-pprof
|
||||
---
|
||||
|
||||
# Flame Graphs
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 stack trace 의 SVG-ified hierarchy"**. Brendan Gregg (2011) 가 만든 매 visualization — 매 x축은 alphabetical (NOT time), 매 y축은 stack depth, 매 width 는 sample count. 매 hot path 가 매 wide flat plateau 로 즉시 보임. 매 2026 현재 perf, eBPF, py-spy, async-profiler, pprof, Pyroscope 등 매 모든 profiler 가 native output.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 읽는 법
|
||||
- **Width = time spent** (sample count proportional). 매 wide = hot.
|
||||
- **Y = stack depth**. 매 bottom = entry, top = leaf.
|
||||
- **Color = arbitrary** (typically random hue per function — visual separation only).
|
||||
- **Plateau at top** = leaf function 의 CPU bound.
|
||||
- **Tower** = deep call chain (recursion 또는 framework overhead).
|
||||
|
||||
### 매 variant
|
||||
- **CPU flame graph**: 매 on-CPU sample 만 — classic.
|
||||
- **Off-CPU flame graph**: 매 blocked time (I/O, lock wait) — 매 latency 분석.
|
||||
- **Differential flame graph**: 매 두 profile 의 diff — red = slower, blue = faster.
|
||||
- **Icicle (inverted)**: top-down — 매 entry-point 분석에 좋음.
|
||||
- **Continuous profiling**: 매 Pyroscope / Grafana Phlare 가 매 production 에 항상 켜짐.
|
||||
|
||||
### 매 도구 매핑
|
||||
1. **Linux native**: `perf record -F 99 -g` + Brendan Gregg's FlameGraph perl script.
|
||||
2. **eBPF**: `bcc/profile`, `parca-agent` — kernel + user 통합.
|
||||
3. **Python**: `py-spy record -o flame.svg --pid $PID`.
|
||||
4. **JVM**: `async-profiler -e cpu -d 30 -f flame.html $PID`.
|
||||
5. **Go**: `go tool pprof -http=:8080 cpu.prof` (built-in flame graph).
|
||||
6. **Node.js**: `0x` or `clinic flame`.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Linux perf → flame graph
|
||||
```bash
|
||||
# 1. Sample 99 Hz for 30s, capture stacks
|
||||
sudo perf record -F 99 -a -g -- sleep 30
|
||||
|
||||
# 2. Convert to folded format
|
||||
sudo perf script | \
|
||||
~/FlameGraph/stackcollapse-perf.pl > out.folded
|
||||
|
||||
# 3. Render SVG
|
||||
~/FlameGraph/flamegraph.pl out.folded > flame.svg
|
||||
|
||||
# Open in browser → click to zoom, search regex highlights
|
||||
```
|
||||
|
||||
### Differential flame graph (before/after)
|
||||
```bash
|
||||
~/FlameGraph/stackcollapse-perf.pl < before.perf > before.folded
|
||||
~/FlameGraph/stackcollapse-perf.pl < after.perf > after.folded
|
||||
~/FlameGraph/difffolded.pl before.folded after.folded | \
|
||||
~/FlameGraph/flamegraph.pl --negate > diff.svg
|
||||
```
|
||||
|
||||
### Continuous profiling with Pyroscope (Go)
|
||||
```go
|
||||
import "github.com/grafana/pyroscope-go"
|
||||
|
||||
func main() {
|
||||
pyroscope.Start(pyroscope.Config{
|
||||
ApplicationName: "checkout-service",
|
||||
ServerAddress: "http://pyroscope:4040",
|
||||
Logger: pyroscope.StandardLogger,
|
||||
Tags: map[string]string{"region": "us-west-2"},
|
||||
ProfileTypes: []pyroscope.ProfileType{
|
||||
pyroscope.ProfileCPU,
|
||||
pyroscope.ProfileAllocObjects,
|
||||
pyroscope.ProfileInuseObjects,
|
||||
},
|
||||
})
|
||||
runServer()
|
||||
}
|
||||
```
|
||||
|
||||
### py-spy on running Python service
|
||||
```bash
|
||||
# 30s sample, draw flame graph
|
||||
py-spy record -o flame.svg --pid 12345 --duration 30 --rate 100
|
||||
|
||||
# Native + Python frames combined
|
||||
py-spy record -o flame.svg --pid 12345 --native
|
||||
|
||||
# Top-like live view
|
||||
py-spy top --pid 12345
|
||||
```
|
||||
|
||||
### async-profiler for JVM
|
||||
```bash
|
||||
# CPU profile (30s) → flamegraph HTML
|
||||
./profiler.sh -e cpu -d 30 -f flame.html $(jps | grep MyApp | awk '{print $1}')
|
||||
|
||||
# Allocation profile
|
||||
./profiler.sh -e alloc -d 60 -f alloc.html $PID
|
||||
|
||||
# Wall-clock (off-CPU + on-CPU)
|
||||
./profiler.sh -e wall -t -d 30 -f wall.html $PID
|
||||
```
|
||||
|
||||
### Off-CPU flame graph (eBPF / bcc)
|
||||
```bash
|
||||
# Capture off-CPU stacks (blocked time) for 30s
|
||||
sudo /usr/share/bcc/tools/offcputime -df -p $PID 30 > offcpu.folded
|
||||
~/FlameGraph/flamegraph.pl --color=io --title="Off-CPU" \
|
||||
offcpu.folded > offcpu.svg
|
||||
```
|
||||
|
||||
### pprof flame graph (Go built-in)
|
||||
```go
|
||||
import _ "net/http/pprof"
|
||||
|
||||
go func() { http.ListenAndServe("localhost:6060", nil) }()
|
||||
|
||||
// Then on dev machine:
|
||||
// go tool pprof -http=:8080 http://service:6060/debug/pprof/profile?seconds=30
|
||||
// → opens browser, click "View" → "Flame Graph"
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Production continuous | Pyroscope / Grafana Phlare / Polar Signals |
|
||||
| Linux ad-hoc | perf + FlameGraph |
|
||||
| Python | py-spy (zero-instrumentation) |
|
||||
| JVM | async-profiler (allocation + CPU + wall) |
|
||||
| Go | built-in pprof + go tool pprof |
|
||||
| Node | 0x or clinic flame |
|
||||
| Latency / blocked | Off-CPU flame graph (eBPF) |
|
||||
|
||||
**기본값**: 매 production 에 Pyroscope + 매 dev 에 native profiler.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Profiling]]
|
||||
- 응용: [[SRE]]
|
||||
- Adjacent: [[eBPF]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 flame graph 의 hot frame 식별 + optimization 제안, folded text → 자연어 summary, differential interpretation.
|
||||
**언제 X**: 매 visual exact pixel reading — 매 SVG 자체 사용.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Sampling rate too low**: 매 19 Hz — 매 short hot function miss. 매 99 Hz 표준.
|
||||
- **Without -g (no callgraphs)**: 매 perf record -g 누락 — 매 frames frame 만 보임.
|
||||
- **No frame pointers (Go ≤1.20, glibc)**: 매 stack unwind 실패 — `-fno-omit-frame-pointer` 또는 DWARF.
|
||||
- **Reading width as time order**: 매 x축은 time 의 X — alphabetical sort.
|
||||
- **Production profiling once a year**: 매 continuous 의 가치를 놓침.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Brendan Gregg 2011, Pyroscope/Grafana Labs 2026).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — flame graph reading guide + perf/py-spy/pprof recipes |
|
||||
@@ -0,0 +1,194 @@
|
||||
---
|
||||
id: wiki-2026-0508-formal-verification-of-software
|
||||
title: Formal Verification of Software
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Formal Methods, Program Verification]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [formal-methods, verification, correctness]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Coq/Lean/TLA+
|
||||
framework: Dafny/F*
|
||||
---
|
||||
|
||||
# Formal Verification of Software
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 prove correctness, 매 test correctness 의 X"**. Formal verification 의 mathematical proof 의 program 의 specification 에 대한 conformance — 매 testing 의 fundamental superset. 2026 의 industrial use 의 expanding (AWS s2n-tls, sel4, CompCert, Cardano, Dafny in MS, Lean 4 의 mathlib).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Spectrum of rigor
|
||||
1. **Type systems**: lightweight, daily (TypeScript, Rust borrow checker).
|
||||
2. **Property-based testing**: empirical, partial (QuickCheck).
|
||||
3. **Model checking**: finite-state exhaustive (TLA+, SPIN).
|
||||
4. **Deductive verification**: machine-checked proofs (Coq, Lean, Dafny, F*).
|
||||
5. **Refinement**: high-level spec → low-level impl preserves properties (Event-B).
|
||||
|
||||
### 매 Tools (2026 leaders)
|
||||
- **TLA+**: distributed system specs (used by AWS, Azure for protocols).
|
||||
- **Coq / Lean 4**: dependent types, proof assistant.
|
||||
- **Dafny**: verification-aware imperative language (MS).
|
||||
- **F***: ML-style with refinement types (HACL* crypto, EverParse).
|
||||
- **Kani / Creusot**: Rust verification.
|
||||
- **CBMC**: bounded model checker for C.
|
||||
|
||||
### 매 What gets verified
|
||||
- Algorithmic correctness (sorting, hashing).
|
||||
- Protocol safety (no deadlock, agreement).
|
||||
- Memory safety (no UAF, overflow).
|
||||
- Cryptographic implementations (HACL* used in Linux, Firefox).
|
||||
- Compiler correctness (CompCert).
|
||||
- OS kernel (seL4 — full functional correctness).
|
||||
|
||||
### 매 응용
|
||||
1. Safety-critical (avionics DO-178C Level A, automotive ISO 26262).
|
||||
2. Crypto libraries (HACL*, Project Everest).
|
||||
3. Distributed protocols (Paxos, Raft TLA+).
|
||||
4. Smart contracts (Cardano Plutus, MoveProver).
|
||||
5. Compilers / kernels (CompCert, seL4).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### TLA+ — distributed mutex spec
|
||||
```tla
|
||||
---- MODULE Mutex ----
|
||||
EXTENDS Naturals
|
||||
VARIABLES queue, holder
|
||||
|
||||
Init == queue = <<>> /\ holder = NULL
|
||||
|
||||
Request(p) == queue' = Append(queue, p) /\ UNCHANGED holder
|
||||
|
||||
Acquire == /\ queue # <<>>
|
||||
/\ holder = NULL
|
||||
/\ holder' = Head(queue)
|
||||
/\ queue' = Tail(queue)
|
||||
|
||||
MutualExclusion == \A p, q \in Procs : holder = p /\ holder = q => p = q
|
||||
|
||||
THEOREM Spec => []MutualExclusion
|
||||
====
|
||||
```
|
||||
|
||||
### Dafny — verified binary search
|
||||
```dafny
|
||||
method BinarySearch(a: array<int>, key: int) returns (idx: int)
|
||||
requires forall i, j :: 0 <= i < j < a.Length ==> a[i] <= a[j]
|
||||
ensures 0 <= idx ==> idx < a.Length && a[idx] == key
|
||||
ensures idx < 0 ==> forall i :: 0 <= i < a.Length ==> a[i] != key
|
||||
{
|
||||
var lo, hi := 0, a.Length;
|
||||
while lo < hi
|
||||
invariant 0 <= lo <= hi <= a.Length
|
||||
invariant forall i :: 0 <= i < lo ==> a[i] < key
|
||||
invariant forall i :: hi <= i < a.Length ==> a[i] > key
|
||||
{
|
||||
var mid := (lo + hi) / 2;
|
||||
if a[mid] < key { lo := mid + 1; }
|
||||
else if a[mid] > key { hi := mid; }
|
||||
else { return mid; }
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
```
|
||||
|
||||
### Lean 4 — proof of a simple lemma
|
||||
```lean
|
||||
theorem add_zero (n : Nat) : n + 0 = n := by
|
||||
induction n with
|
||||
| zero => rfl
|
||||
| succ k ih => simp [Nat.succ_add, ih]
|
||||
```
|
||||
|
||||
### F* refinement types
|
||||
```fsharp
|
||||
val divide : x:int -> y:int{y <> 0} -> int
|
||||
let divide x y = x / y
|
||||
|
||||
// Compiler proves y <> 0 at every call site — divide-by-zero impossible
|
||||
```
|
||||
|
||||
### Kani — Rust harness
|
||||
```rust
|
||||
#[kani::proof]
|
||||
fn check_sum_no_overflow() {
|
||||
let a: u32 = kani::any();
|
||||
let b: u32 = kani::any();
|
||||
kani::assume(a < 1000 && b < 1000);
|
||||
let sum = a + b;
|
||||
assert!(sum == a + b); // proven for ALL inputs in range
|
||||
}
|
||||
```
|
||||
|
||||
### CBMC — bounded check on C
|
||||
```c
|
||||
#include <assert.h>
|
||||
int main() {
|
||||
int x = nondet_int();
|
||||
__CPROVER_assume(x >= 0 && x < 100);
|
||||
int y = x * x;
|
||||
assert(y >= 0);
|
||||
return 0;
|
||||
}
|
||||
// cbmc file.c → reports counterexample if assertion fails
|
||||
```
|
||||
|
||||
### Property + spec hybrid (Hypothesis)
|
||||
```python
|
||||
from hypothesis import given, strategies as st
|
||||
|
||||
@given(st.lists(st.integers()))
|
||||
def test_sort_preserves_length(xs):
|
||||
assert len(sorted(xs)) == len(xs)
|
||||
|
||||
@given(st.lists(st.integers()))
|
||||
def test_sort_is_ordered(xs):
|
||||
s = sorted(xs)
|
||||
assert all(s[i] <= s[i+1] for i in range(len(s)-1))
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Web app daily | Strong types + property tests |
|
||||
| Distributed protocol | TLA+ model |
|
||||
| Crypto primitive | F* / HACL* |
|
||||
| Smart contract | MoveProver / Plutus |
|
||||
| OS / hypervisor | Coq / seL4-style |
|
||||
| Rust kernel code | Kani / Creusot |
|
||||
|
||||
**기본값**: types everywhere + property-based for parsers + TLA+ for distributed designs + reach for proof assistants only when life/billions on the line.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Computer_Science_and_Theory]]
|
||||
- 변형: [[Type-safe Error Handling Exhaustiveness Checking]] · [[TypeScript 타입 시스템 (TypeScript Type System)|Type Systems]]
|
||||
- 응용: [[Practical-Cryptography]] · [[SAST]]
|
||||
- Adjacent: [[Quality-Control]] · [[Test_Automation]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: draft TLA+ specs from prose descriptions, suggest invariants, explain failing proofs.
|
||||
**언제 X**: never trust LLM-generated proof without checker (Lean/Coq) verifying.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Spec ≠ implementation**: verify spec, ship different code.
|
||||
- **Unverified assumptions**: proofs depend on `axiom` blocks that hide bugs.
|
||||
- **Verify everything**: cost > benefit for typical CRUD.
|
||||
- **No model**: claim "formally verified" with handwaved diagram.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Lamport TLA+ book, Pierce SF, AWS Builders Library 2024 formal methods).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — spectrum + tool examples |
|
||||
@@ -0,0 +1,198 @@
|
||||
---
|
||||
id: wiki-2026-0508-frustum-culling
|
||||
title: Frustum Culling
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [View Frustum Culling, VFC, Camera Culling]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [graphics, rendering, culling, optimization, gpu]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: cpp
|
||||
framework: opengl-vulkan-unity
|
||||
---
|
||||
|
||||
# Frustum Culling
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 carmera 의 view volume (frustum) 밖 object 의 매 draw skip"**. 매 가장 기본적이고 가장 효과적인 매 visibility culling — 매 30-90% draw call 감소가 일반적. 매 modern engine (Unreal 5 Nanite, Unity HDRP, bevy) 은 매 GPU-driven culling 으로 매 millions of objects 를 매 compute shader 안에서 매 frame 마다 cull.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 frustum 표현
|
||||
- **6 planes**: near, far, left, right, top, bottom.
|
||||
- 매 plane equation: `ax + by + cz + d = 0` with `(a,b,c)` = inward normal.
|
||||
- 매 view-projection matrix 의 매 row combo 로 6 planes extract (Gribb-Hartmann).
|
||||
|
||||
### 매 bounding volume choice
|
||||
- **AABB (axis-aligned)**: 매 cheapest, 매 conservative — 매 large rotated objects 매 over-conservative.
|
||||
- **OBB (oriented)**: 매 tighter, 매 더 expensive.
|
||||
- **Sphere**: 매 cheapest test (single dot product), 매 loosest.
|
||||
- **Plane mask (frustum culling with masks)**: 매 children inherit parent 의 "fully inside" plane.
|
||||
|
||||
### 매 알고리즘 흐름
|
||||
1. View-projection matrix → 6 frustum planes.
|
||||
2. 매 object 의 BV 와 매 6 planes test.
|
||||
3. **Outside** any plane → cull.
|
||||
4. **Inside** all → render.
|
||||
5. **Intersect** → render (or recurse children if hierarchy).
|
||||
|
||||
### 매 modern (GPU-driven)
|
||||
- **Compute shader** 가 매 draw arguments buffer 를 build (`DrawIndirect`).
|
||||
- 매 millions of objects 도 매 sub-millisecond.
|
||||
- 매 hierarchical Z-buffer occlusion + frustum 결합 (Nanite).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Extract frustum planes from VP matrix (Gribb-Hartmann)
|
||||
```cpp
|
||||
struct Plane { glm::vec3 n; float d; };
|
||||
|
||||
void extractPlanes(const glm::mat4& vp, Plane out[6]) {
|
||||
auto m = glm::transpose(vp); // row-major helper
|
||||
out[0] = { glm::vec3(m[3]+m[0]), m[3].w + m[0].w }; // left
|
||||
out[1] = { glm::vec3(m[3]-m[0]), m[3].w - m[0].w }; // right
|
||||
out[2] = { glm::vec3(m[3]+m[1]), m[3].w + m[1].w }; // bottom
|
||||
out[3] = { glm::vec3(m[3]-m[1]), m[3].w - m[1].w }; // top
|
||||
out[4] = { glm::vec3(m[3]+m[2]), m[3].w + m[2].w }; // near
|
||||
out[5] = { glm::vec3(m[3]-m[2]), m[3].w - m[2].w }; // far
|
||||
for (int i = 0; i < 6; i++) {
|
||||
float len = glm::length(out[i].n);
|
||||
out[i].n /= len; out[i].d /= len;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Sphere vs frustum (cheapest)
|
||||
```cpp
|
||||
bool sphereInFrustum(const Plane planes[6], const glm::vec3& c, float r) {
|
||||
for (int i = 0; i < 6; i++)
|
||||
if (glm::dot(planes[i].n, c) + planes[i].d < -r) return false;
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### AABB vs frustum (positive vertex / p-vertex test)
|
||||
```cpp
|
||||
bool aabbInFrustum(const Plane planes[6], const glm::vec3& mn, const glm::vec3& mx) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
glm::vec3 p = {
|
||||
planes[i].n.x >= 0 ? mx.x : mn.x,
|
||||
planes[i].n.y >= 0 ? mx.y : mn.y,
|
||||
planes[i].n.z >= 0 ? mx.z : mn.z
|
||||
};
|
||||
if (glm::dot(planes[i].n, p) + planes[i].d < 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### BVH-based hierarchical culling
|
||||
```cpp
|
||||
void cullBVH(const BVHNode& node, const Plane planes[6], std::vector<int>& visible) {
|
||||
auto r = aabbVsFrustumIntersect(planes, node.aabb);
|
||||
if (r == OUTSIDE) return;
|
||||
if (r == INSIDE) { addAll(node, visible); return; }
|
||||
if (node.isLeaf) {
|
||||
for (int idx : node.objects)
|
||||
if (aabbInFrustum(planes, objs[idx].mn, objs[idx].mx))
|
||||
visible.push_back(idx);
|
||||
return;
|
||||
}
|
||||
cullBVH(*node.left, planes, visible);
|
||||
cullBVH(*node.right, planes, visible);
|
||||
}
|
||||
```
|
||||
|
||||
### GPU compute culling (HLSL)
|
||||
```hlsl
|
||||
// CullCS.hlsl
|
||||
StructuredBuffer<ObjectData> objects : register(t0);
|
||||
ConstantBuffer<FrustumCB> frustum : register(b0);
|
||||
RWStructuredBuffer<DrawArgs> drawArgs : register(u0);
|
||||
RWByteAddressBuffer counter : register(u1);
|
||||
|
||||
[numthreads(64, 1, 1)]
|
||||
void main(uint3 id : SV_DispatchThreadID) {
|
||||
if (id.x >= objects.Length) return;
|
||||
ObjectData o = objects[id.x];
|
||||
bool visible = true;
|
||||
[unroll] for (int i = 0; i < 6; i++) {
|
||||
float4 p = frustum.planes[i];
|
||||
if (dot(p.xyz, o.center) + p.w < -o.radius) { visible = false; break; }
|
||||
}
|
||||
if (visible) {
|
||||
uint slot;
|
||||
counter.InterlockedAdd(0, 1, slot);
|
||||
drawArgs[slot].vertexCount = o.indexCount;
|
||||
drawArgs[slot].instanceCount = 1;
|
||||
drawArgs[slot].firstIndex = o.firstIndex;
|
||||
drawArgs[slot].baseInstance = id.x;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Unity (Burst) culling job
|
||||
```csharp
|
||||
[BurstCompile]
|
||||
struct FrustumCullJob : IJobParallelFor {
|
||||
[ReadOnly] public NativeArray<float4> planes; // 6 planes
|
||||
[ReadOnly] public NativeArray<float4> bounds; // xyz=center, w=radius
|
||||
[WriteOnly] public NativeArray<bool> visible;
|
||||
|
||||
public void Execute(int i) {
|
||||
float4 b = bounds[i];
|
||||
for (int p = 0; p < 6; p++) {
|
||||
float4 pl = planes[p];
|
||||
if (math.dot(pl.xyz, b.xyz) + pl.w < -b.w) {
|
||||
visible[i] = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
visible[i] = true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| <1k objects, CPU | per-object sphere/AABB test |
|
||||
| 1k-100k, hierarchical | BVH / Octree + frustum |
|
||||
| 100k+ static, GPU | compute shader + DrawIndirect |
|
||||
| Massive (Nanite-class) | GPU-driven + HZB occlusion |
|
||||
| Animated skeletal | use skinned bounds (loose) |
|
||||
|
||||
**기본값**: 매 modern engine — GPU compute culling + BVH for spatial queries.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Real-Time Rendering]]
|
||||
- 응용: [[GPU-Driven Rendering]] · [[Nanite]]
|
||||
- Adjacent: [[BVH]] · [[Octree]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: plane extraction code 검토, false-cull bug 디버깅 (e.g., flipped normal), GPU shader skeleton.
|
||||
**언제 X**: 매 actual rendering decision 의 runtime correctness — unit test + visual verification.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **No bounding volume cache**: 매 frame 마다 매 mesh 의 bound 재계산 — pre-compute.
|
||||
- **Sphere only for everything**: 매 long thin object 매 over-conservative.
|
||||
- **Plane normalization 누락**: 매 distance comparison 부정확.
|
||||
- **Cull camera == render camera 가정**: 매 shadow camera, planar reflection 시 매 잘못.
|
||||
- **Animated bound 무시**: 매 skinned mesh 의 bound 가 매 outdated → pop in/out.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Real-Time Rendering 4th ed, Gribb-Hartmann 2001, Unreal Nanite docs 2026).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — frustum extraction + BV tests + GPU-driven |
|
||||
@@ -0,0 +1,150 @@
|
||||
---
|
||||
id: wiki-2026-0508-geometry-merging
|
||||
title: Geometry Merging
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Mesh Merging, Static Batching, Geometry Batching]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [graphics, optimization, rendering, gpu]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: C++/HLSL
|
||||
framework: Unity/Unreal/Three.js
|
||||
---
|
||||
|
||||
# Geometry Merging
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 여러 mesh 를 매 단일 vertex/index buffer 로 합쳐 매 draw call 수를 매 줄이는 기법"**. CPU-GPU command overhead 의 매 frame budget 의 매 dominant share 였던 시대의 매 staple optimization. 매 modern era — GPU instancing, indirect draw, mesh shader 가 매 알 수 있게 대체했지만 매 static scene, mobile, low-end 에서 매 still relevant.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 종류
|
||||
- **Static batching**: build-time 에 같은 material 의 static mesh 합침.
|
||||
- **Dynamic batching**: runtime 에 small mesh 를 transform & merge (CPU cost ↑).
|
||||
- **GPU instancing**: 같은 mesh 여러 transform — merging 의 modern 대체.
|
||||
- **Mesh atlas (texture array)**: material 통합으로 merge 가능 범위 확장.
|
||||
|
||||
### 매 trade-off
|
||||
- ↑ Throughput (fewer draw call).
|
||||
- ↓ Culling 정확도 (merged AABB 가 매 커짐).
|
||||
- ↑ Memory (per-vertex data 의 매 duplication).
|
||||
- ↓ Animation flexibility (static 한정).
|
||||
|
||||
### 매 응용
|
||||
1. Mobile 게임 — draw call 의 매 hard limit (~100-200).
|
||||
2. Architectural visualization — 매 thousands of small props.
|
||||
3. Tile-based world streaming.
|
||||
4. UI batching (text glyph atlas).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Manual merge (Three.js)
|
||||
```javascript
|
||||
import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
||||
const geos = props.map(p => p.geometry.clone().applyMatrix4(p.matrixWorld));
|
||||
const merged = mergeGeometries(geos, false);
|
||||
const mesh = new THREE.Mesh(merged, sharedMaterial);
|
||||
scene.add(mesh);
|
||||
// 1000 draw calls → 1
|
||||
```
|
||||
|
||||
### Unity static batching
|
||||
```csharp
|
||||
// Mark objects as static in Inspector → Unity merges at build time.
|
||||
// Or runtime:
|
||||
StaticBatchingUtility.Combine(rootGameObject);
|
||||
// Caveat: combined mesh 64k vertex 한도 (16-bit index).
|
||||
```
|
||||
|
||||
### GPU instancing (preferred over merge)
|
||||
```glsl
|
||||
// vertex shader (Unity URP)
|
||||
struct Attributes {
|
||||
float3 positionOS : POSITION;
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
UNITY_INSTANCING_BUFFER_START(Props)
|
||||
UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
|
||||
UNITY_INSTANCING_BUFFER_END(Props)
|
||||
|
||||
Varyings vert(Attributes IN) {
|
||||
UNITY_SETUP_INSTANCE_ID(IN);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Texture atlas (enable merging across materials)
|
||||
```python
|
||||
# Bake separate textures into one atlas → assign UV remap.
|
||||
import numpy as np
|
||||
atlas = np.zeros((2048, 2048, 4), np.uint8)
|
||||
uv_remap = {}
|
||||
for i, tex in enumerate(textures):
|
||||
x, y = (i % 8) * 256, (i // 8) * 256
|
||||
atlas[y:y+256, x:x+256] = tex
|
||||
uv_remap[i] = (x/2048, y/2048, 256/2048, 256/2048)
|
||||
# Then rewrite mesh UVs per material id.
|
||||
```
|
||||
|
||||
### Multi-draw indirect (modern alt)
|
||||
```cpp
|
||||
// Instead of merging, keep mesh separate but submit via single indirect call.
|
||||
struct DrawCmd { uint32_t indexCount, instanceCount, firstIndex, vertexOffset, firstInstance; };
|
||||
std::vector<DrawCmd> cmds; // one per visible mesh
|
||||
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, cmds.data(), cmds.size(), 0);
|
||||
```
|
||||
|
||||
### Hierarchical merge (octree)
|
||||
```python
|
||||
def merge_octree(node):
|
||||
if node.is_leaf and len(node.meshes) > 1:
|
||||
node.merged = merge(node.meshes)
|
||||
else:
|
||||
for c in node.children: merge_octree(c)
|
||||
# Coarse cull on octree node, fine draw merged buffer.
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 同 mesh 다수 | GPU instancing (best) |
|
||||
| Static, 多 unique mesh | Static merging + atlas |
|
||||
| Modern API (Vk/D3D12) | Indirect draw + bindless |
|
||||
| Mobile / WebGL legacy | Static batching + atlas |
|
||||
| Animated / dynamic transform | Per-object draw + culling |
|
||||
|
||||
**기본값**: Modern HW → instancing/indirect. Legacy → static merge + atlas.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Rendering Optimization]] · [[Draw Call]]
|
||||
- 변형: [[GPU Instancing]] · [[Indirect Draw]]
|
||||
- 응용: [[Texture Atlas]] · [[Octree]] · [[BVH]]
|
||||
- Adjacent: [[Frustum Culling]] · [[LOD]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Mobile / web renderer 최적화, asset pipeline 설계.
|
||||
**언제 X**: Highly dynamic scenes (animation/destruction).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Merge everything**: 매 culling 효과 무력화.
|
||||
- **Material 다른 mesh merge**: shader switch 강제 → benefit 없음.
|
||||
- **Skinned mesh static merge**: 매 animation broken.
|
||||
- **64k vertex 한계 모름**: 16-bit index 의 매 silent overflow.
|
||||
- **Modern API 에서 merge 만 사용**: indirect/instancing 무시.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Unity docs, Three.js BufferGeometryUtils, GPU Pro series).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — merging vs instancing/indirect 의 trade-off |
|
||||
@@ -0,0 +1,187 @@
|
||||
---
|
||||
id: wiki-2026-0508-global-network-positioning-gnp
|
||||
title: Global Network Positioning (GNP)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [GNP, Network Coordinates, Network Positioning, Vivaldi]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [networking, latency-prediction, distributed-systems, p2p, coordinates]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: go
|
||||
framework: vivaldi-coords
|
||||
---
|
||||
|
||||
# Global Network Positioning (GNP)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 host 를 매 low-D Euclidean space 의 point 로 embed — 매 distance 가 매 network latency 의 predictor"**. Ng & Zhang (SIGCOMM 2002) 의 GNP — 매 landmark 기반 절대 좌표 — 가 매 idea 의 시초. 매 후속작 Vivaldi (Dabek 2004) 가 매 decentralized 형태로 매 P2P / overlay network 에 광범위하게 사용. 매 2026 의 application 은 매 CDN edge selection, DHT routing, server placement.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 GNP (centralized) 의 idea
|
||||
- **Landmark hosts** (예: 15-20개) 가 매 Internet 곳곳에 배치.
|
||||
- 매 RTT 측정 후 landmark 들의 매 좌표를 매 fixed point 로 fitting (multidim scaling).
|
||||
- 매 new host 는 매 landmark 들에 ping → 매 자기 좌표 solve.
|
||||
- 매 두 host 간 RTT ≈ Euclidean distance.
|
||||
|
||||
### 매 Vivaldi (decentralized) 의 차이
|
||||
- Landmark X — 매 모든 peer 가 random subset 와 매 RTT 교환.
|
||||
- 매 spring relaxation: 매 over/under-estimated 매 vector 만큼 push/pull.
|
||||
- 매 height augmentation (extra non-Euclidean dim) 으로 매 access link 의 last-mile 표현.
|
||||
- 매 dynamic — peer churn 에 자동 적응.
|
||||
|
||||
### 매 application
|
||||
1. **CDN routing**: 매 client 좌표 → 매 nearest edge.
|
||||
2. **DHT optimization**: 매 finger table 을 매 latency-aware 로 선택.
|
||||
3. **Server selection**: 매 mirror / replica 중 가장 가까운 매 fetch.
|
||||
4. **Network tomography**: 매 latency map 시각화.
|
||||
5. **P2P overlays**: BitTorrent, Skype 가 매 사용 (legacy).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### GNP-style landmark fitting (NumPy)
|
||||
```python
|
||||
import numpy as np
|
||||
from scipy.optimize import minimize
|
||||
|
||||
def fit_landmarks(rtt_matrix, dim=4):
|
||||
"""rtt_matrix[i][j] = measured RTT between landmark i,j (ms)."""
|
||||
n = rtt_matrix.shape[0]
|
||||
x0 = np.random.rand(n * dim) * 50
|
||||
|
||||
def stress(x):
|
||||
coords = x.reshape(n, dim)
|
||||
err = 0.0
|
||||
for i in range(n):
|
||||
for j in range(i + 1, n):
|
||||
d = np.linalg.norm(coords[i] - coords[j])
|
||||
err += ((d - rtt_matrix[i, j]) / rtt_matrix[i, j]) ** 2
|
||||
return err
|
||||
|
||||
res = minimize(stress, x0, method='L-BFGS-B')
|
||||
return res.x.reshape(n, dim)
|
||||
|
||||
def position_new_host(rtts_to_landmarks, landmark_coords, dim=4):
|
||||
def stress(x):
|
||||
return sum(
|
||||
((np.linalg.norm(x - landmark_coords[i]) - rtts_to_landmarks[i])
|
||||
/ rtts_to_landmarks[i]) ** 2
|
||||
for i in range(len(rtts_to_landmarks))
|
||||
)
|
||||
res = minimize(stress, np.zeros(dim), method='L-BFGS-B')
|
||||
return res.x
|
||||
```
|
||||
|
||||
### Vivaldi spring relaxation step (Go)
|
||||
```go
|
||||
type Coord struct {
|
||||
Vec []float64 // Euclidean dims
|
||||
Height float64 // last-mile
|
||||
Err float64 // local error estimate
|
||||
}
|
||||
|
||||
const (
|
||||
Ce = 0.25 // error sensitivity
|
||||
Cc = 0.25 // coord change sensitivity
|
||||
)
|
||||
|
||||
// Update local coord after measuring rtt to peer with peerCoord
|
||||
func (c *Coord) Update(rtt float64, peerCoord Coord) {
|
||||
w := c.Err / (c.Err + peerCoord.Err)
|
||||
predicted := dist(c.Vec, peerCoord.Vec) + c.Height + peerCoord.Height
|
||||
es := math.Abs(predicted-rtt) / rtt
|
||||
c.Err = es*Ce*w + c.Err*(1-Ce*w)
|
||||
|
||||
delta := Cc * w
|
||||
direction := unit(sub(c.Vec, peerCoord.Vec))
|
||||
force := (rtt - predicted) * delta
|
||||
for i := range c.Vec {
|
||||
c.Vec[i] += direction[i] * force
|
||||
}
|
||||
c.Height = math.Max(0, c.Height+(rtt-predicted)*delta*0.5)
|
||||
}
|
||||
```
|
||||
|
||||
### Edge selection from coordinates
|
||||
```go
|
||||
func selectEdge(client Coord, edges []EdgeNode) *EdgeNode {
|
||||
var best *EdgeNode
|
||||
bestRTT := math.Inf(1)
|
||||
for i, e := range edges {
|
||||
rtt := dist(client.Vec, e.Coord.Vec) + client.Height + e.Coord.Height
|
||||
if rtt < bestRTT {
|
||||
bestRTT = rtt
|
||||
best = &edges[i]
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
```
|
||||
|
||||
### CDN-style anycast hybrid (BGP + GNP fallback)
|
||||
```python
|
||||
def route(client_ip):
|
||||
# Try anycast result first (BGP picks PoP)
|
||||
pop = anycast_lookup(client_ip)
|
||||
if pop and recent_health(pop):
|
||||
return pop
|
||||
# Fallback: use GNP coords from RIPE Atlas / Cedexis
|
||||
coord = lookup_client_coord(client_ip)
|
||||
return min(EDGES, key=lambda e: euclid(coord, e.coord) + e.height + coord.height)
|
||||
```
|
||||
|
||||
### Stress test (predicted vs actual)
|
||||
```python
|
||||
def evaluate(coords, ground_truth_rtt):
|
||||
rel_err = []
|
||||
for (i, j), actual in ground_truth_rtt.items():
|
||||
pred = np.linalg.norm(coords[i] - coords[j])
|
||||
rel_err.append(abs(pred - actual) / actual)
|
||||
return {
|
||||
'median_rel_err': np.median(rel_err),
|
||||
'p90_rel_err': np.percentile(rel_err, 90),
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Centralized infra, fixed landmarks | GNP |
|
||||
| P2P / dynamic peer set | Vivaldi |
|
||||
| <100 nodes | Direct measurement (skip embedding) |
|
||||
| Global CDN | Anycast + GNP fallback |
|
||||
| Triangle inequality violations frequent | Add height (Vivaldi) or non-Euclidean |
|
||||
|
||||
**기본값**: 매 modern usage — Vivaldi w/ height (4D + height).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Distributed Systems]]
|
||||
- 변형: [[Vivaldi]]
|
||||
- 응용: [[CDN]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 algorithm 설명, 매 stress function tuning 제안, embedding dimension 선택 기준.
|
||||
**언제 X**: 매 real-time coord update — 매 measured RTT 만이 truth.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **2D 만 사용**: 매 triangle inequality 자주 violated — 매 4D + height.
|
||||
- **No error tracking**: 매 Vivaldi 의 local error term 빠짐 → unstable.
|
||||
- **Static landmarks 의 churn 무시**: 매 landmark 매 fail 시 — health check 필수.
|
||||
- **Use embedding distance for security**: 매 거리는 매 latency proxy 일 뿐 — 매 trust 의 X.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Ng & Zhang SIGCOMM 2002, Dabek SIGCOMM 2004).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — GNP/Vivaldi math + edge selection patterns |
|
||||
@@ -0,0 +1,166 @@
|
||||
---
|
||||
id: wiki-2026-0508-google-code-jam-dataset
|
||||
title: Google Code Jam Dataset
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [GCJ Dataset, Code Jam Solutions Corpus, GCJ-297]
|
||||
duplicate_of: none
|
||||
source_trust_level: B
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [dataset, code-llm, benchmark, programming-competition, deduplication]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: huggingface-datasets
|
||||
---
|
||||
|
||||
# Google Code Jam Dataset
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 Google Code Jam 의 매 historical archive — 매 code clone detection / code LLM evaluation 의 standard corpus"**. Google 의 매 annual programming competition (2003-2023) 이 매 retire 되었지만 매 solution corpus 는 매 academic 으로 풍부 — 매 multiple solutions per problem, 매 다양한 언어 — 매 code clone, code translation, code-LM benchmark 의 raw material. 매 가장 많이 인용되는 매 GCJ-297 (Bui et al.) 로 매 297 problem × multiple langs.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 dataset 의 특이성
|
||||
- **Same-intent, varied implementations**: 매 단일 problem 에 매 thousands of correct solutions — 매 semantic equivalence 가 ground truth.
|
||||
- **Multi-language**: C++, Java, Python, Go, Kotlin, …
|
||||
- **Difficulty stratification**: Qualification → Round 1/2/3 → World Finals.
|
||||
- **Test cases**: official input/output 이 partial 공개 (sample only) — full hidden.
|
||||
|
||||
### 매 main variants
|
||||
1. **GCJ-297** (Bui et al. 2017): 297 problems, ~120k solutions, code clone benchmark.
|
||||
2. **CodeNet** (IBM 2021): 매 GCJ + AIZU — 14M solutions, 4053 problems, 55 langs (superset).
|
||||
3. **MBXP / HumanEval-X**: 매 not GCJ-derived 지만 매 같은 비교 대상 benchmark.
|
||||
4. **APPS**: Codeforces + AtCoder + Code Jam mix — 매 LLM coding benchmark.
|
||||
|
||||
### 매 use cases
|
||||
- **Code clone detection**: 매 Type-1/2/3/4 clone 의 ground truth.
|
||||
- **Code LLM eval**: 매 contamination 위험 매 큼 — 매 Code Jam 매 GitHub 에 publicly indexed.
|
||||
- **Translation**: 매 Java solution → 매 Python solution.
|
||||
- **Style transfer**: 매 verbose vs 매 idiomatic.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Loading via Hugging Face
|
||||
```python
|
||||
from datasets import load_dataset
|
||||
|
||||
# CodeNet (largest superset including GCJ)
|
||||
ds = load_dataset("Project-CodeNet/codenet", split="train", streaming=True)
|
||||
for ex in ds.take(3):
|
||||
print(ex["problem_id"], ex["language"], ex["status"], len(ex["code"]))
|
||||
```
|
||||
|
||||
### Filter for GCJ subset only
|
||||
```python
|
||||
gcj = ds.filter(lambda x: x["dataset_origin"] == "google_code_jam")
|
||||
print(gcj.info.splits)
|
||||
```
|
||||
|
||||
### Group solutions by problem_id (clone-detection setup)
|
||||
```python
|
||||
from collections import defaultdict
|
||||
buckets = defaultdict(list)
|
||||
for ex in gcj:
|
||||
if ex["status"] == "Accepted":
|
||||
buckets[ex["problem_id"]].append(ex)
|
||||
|
||||
# Pair within bucket = positive (clone), across bucket = negative
|
||||
positive_pairs = [(a, b) for sols in buckets.values()
|
||||
for a, b in itertools.combinations(sols, 2)]
|
||||
```
|
||||
|
||||
### Decontamination check (LLM training data)
|
||||
```python
|
||||
import hashlib
|
||||
def near_dup_hash(code: str, k=5) -> set[int]:
|
||||
tokens = code.split()
|
||||
return {hash(' '.join(tokens[i:i+k])) for i in range(len(tokens) - k)}
|
||||
|
||||
train_hashes = set()
|
||||
for ex in train_corpus:
|
||||
train_hashes |= near_dup_hash(ex["code"])
|
||||
|
||||
contaminated = [
|
||||
ex for ex in gcj_eval
|
||||
if len(near_dup_hash(ex["code"]) & train_hashes) / max(1, len(near_dup_hash(ex["code"]))) > 0.5
|
||||
]
|
||||
print(f"contamination ratio: {len(contaminated) / len(gcj_eval):.2%}")
|
||||
```
|
||||
|
||||
### Compile + run sandbox (judging on test cases)
|
||||
```python
|
||||
import subprocess, tempfile, pathlib
|
||||
|
||||
def judge(code: str, lang: str, stdin: str, expected: str, timeout=5):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
p = pathlib.Path(d) / ("sol." + {"python": "py", "cpp": "cpp"}[lang])
|
||||
p.write_text(code)
|
||||
if lang == "cpp":
|
||||
subprocess.run(["g++", "-O2", "-std=c++20", str(p), "-o", f"{d}/a"], check=True)
|
||||
cmd = [f"{d}/a"]
|
||||
else:
|
||||
cmd = ["python3", str(p)]
|
||||
try:
|
||||
r = subprocess.run(cmd, input=stdin, capture_output=True, text=True, timeout=timeout)
|
||||
return r.stdout.strip() == expected.strip()
|
||||
except subprocess.TimeoutExpired:
|
||||
return False
|
||||
```
|
||||
|
||||
### Train/eval split for code translation
|
||||
```python
|
||||
import random
|
||||
random.seed(0)
|
||||
problems = list(buckets.keys())
|
||||
random.shuffle(problems)
|
||||
train_pids = set(problems[:int(0.9 * len(problems))])
|
||||
|
||||
train, eval = [], []
|
||||
for pid, sols in buckets.items():
|
||||
java = [s for s in sols if s["language"] == "java"]
|
||||
py = [s for s in sols if s["language"] == "python"]
|
||||
pairs = list(itertools.product(java, py))
|
||||
(train if pid in train_pids else eval).extend(
|
||||
{"src": j["code"], "tgt": p["code"]} for j, p in pairs
|
||||
)
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Code clone benchmark | GCJ-297 (Bui et al.) |
|
||||
| LLM coding eval | APPS or HumanEval (less contaminated) |
|
||||
| Code translation | CodeNet pair-wise |
|
||||
| Style benchmark | GCJ multi-solution per problem |
|
||||
| Live evaluation | NEVER use GCJ alone (contamination) |
|
||||
|
||||
**기본값**: 매 LLM eval — APPS/HumanEval 매 main + GCJ 매 supplementary.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[HumanEval]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 dataset filter pipeline 작성, contamination 검사 design, problem grouping logic.
|
||||
**언제 X**: 매 LLM 자체 평가 — 매 GCJ 가 매 training data 에 포함되어 있을 확률 높음 (contamination).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **GCJ for SOTA LLM eval without dedup**: 매 contamination 으로 매 score inflation.
|
||||
- **Sample IO 만 사용**: 매 wrong-answer 가 매 test-case 통과 가능.
|
||||
- **No timeout in judging**: 매 infinite loop 으로 OOM/hang.
|
||||
- **Mixing accepted + WA**: 매 ground truth 의 정확성 저하.
|
||||
- **Ignoring problem difficulty**: 매 stratified eval 필수.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Bui et al. ICSE 2017, IBM Project CodeNet 2021, Hugging Face Hub).
|
||||
- 신뢰도 B (semi-public, scraped).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — GCJ corpus + CodeNet usage + decontamination |
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: wiki-2026-0508-hmd-head-mounted-display-기반-엑서게임
|
||||
title: HMD(Head-Mounted Display) 기반 엑서게임 환경
|
||||
category: 10_Wiki/Topics
|
||||
status: duplicate
|
||||
canonical_id: vr-exergame
|
||||
duplicate_of: "[[VR Exergame]]"
|
||||
aliases: []
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: redirected
|
||||
tags: [duplicate, vr, exergame, hmd]
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
---
|
||||
|
||||
# HMD(Head-Mounted Display) 기반 엑서게임 환경
|
||||
|
||||
> **이 문서는 [[VR Exergame]] 의 중복본입니다.** Canonical 문서로 redirect.
|
||||
|
||||
## 핵심 요약 (specialization aspects)
|
||||
- HMD 기반 exergame (운동게임) 환경 — 매 VR 헤드셋 (Quest 3, Vision Pro, PSVR2) 의 매 6DoF tracking + room-scale + presence 가 매 traditional Wii/Kinect 대비 매 immersion ↑.
|
||||
- 매 한국어 medical/rehab 문헌 에서 자주 등장 — 매 신체활동 + 인지자극 결합.
|
||||
- Canonical 문서가 매 hardware (HMD, controller, treadmill, haptic suit), 매 game design (Beat Saber, Supernatural, FitXR), 매 health outcome 측정을 통합 관리.
|
||||
|
||||
## 🔗 Graph
|
||||
|
||||
## 🕓 변경 이력
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | 중복 처리 — canonical 문서로 redirect |
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
id: wiki-2026-0508-high-resolution-time
|
||||
title: High Resolution Time
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [performance.now, Monotonic Time, HR Time, Hi-Res Timer]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [web-api, performance, timing, security]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: JavaScript/C
|
||||
framework: W3C-HRTime/POSIX
|
||||
---
|
||||
|
||||
# High Resolution Time
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 sub-millisecond 정밀도의 매 monotonic clock"**. W3C High Resolution Time spec — `performance.now()` 가 매 `Date.now()` 의 ms 한계 + wall-clock jitter 를 매 해결. 매 Spectre 후 — 모든 brower 가 매 timer 정밀도를 매 100µs ~ 1ms 로 매 reduce + cross-origin isolation 으로 매 5µs 회복.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 vs Date.now
|
||||
- `Date.now()`: wall clock, ms 단위, NTP 으로 점프 가능 (음수 delta!).
|
||||
- `performance.now()`: monotonic, fractional ms, navigation start 기준.
|
||||
|
||||
### 매 timer attack mitigation
|
||||
- Spectre/Meltdown (2018) → 매 brower 가 timer fuzz/round.
|
||||
- Default: 100µs ~ 1ms rounding + jitter.
|
||||
- COOP+COEP (cross-origin isolated) 시 → 5µs 정밀 + `SharedArrayBuffer`.
|
||||
|
||||
### 매 응용
|
||||
1. Animation frame timing (`rAF` callback).
|
||||
2. Performance profiling (`User Timing API`).
|
||||
3. WebGL/WebGPU frame budget tracking.
|
||||
4. Audio scheduling (`AudioContext.currentTime` 동기).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Basic timing
|
||||
```javascript
|
||||
const t0 = performance.now();
|
||||
heavyWork();
|
||||
const elapsed = performance.now() - t0;
|
||||
console.log(`took ${elapsed.toFixed(3)} ms`); // 12.345 ms
|
||||
```
|
||||
|
||||
### User Timing API (DevTools 표시)
|
||||
```javascript
|
||||
performance.mark('render-start');
|
||||
render();
|
||||
performance.mark('render-end');
|
||||
performance.measure('render', 'render-start', 'render-end');
|
||||
const [m] = performance.getEntriesByName('render');
|
||||
console.log(m.duration);
|
||||
// Visible in Chrome DevTools Performance panel.
|
||||
```
|
||||
|
||||
### Frame budget tracker
|
||||
```javascript
|
||||
let lastT = performance.now();
|
||||
function frame(now) {
|
||||
const dt = now - lastT;
|
||||
lastT = now;
|
||||
if (dt > 16.7) console.warn(`slow frame: ${dt.toFixed(1)}ms`);
|
||||
requestAnimationFrame(frame);
|
||||
}
|
||||
requestAnimationFrame(frame);
|
||||
```
|
||||
|
||||
### Cross-origin isolated (max precision)
|
||||
```http
|
||||
# Server response headers
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
```
|
||||
```javascript
|
||||
if (crossOriginIsolated) {
|
||||
// performance.now() granularity ~5µs
|
||||
// SharedArrayBuffer 가능
|
||||
}
|
||||
```
|
||||
|
||||
### POSIX equivalent (C)
|
||||
```c
|
||||
#include <time.h>
|
||||
struct timespec t0, t1;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t0);
|
||||
do_work();
|
||||
clock_gettime(CLOCK_MONOTONIC, &t1);
|
||||
double elapsed_ns = (t1.tv_sec - t0.tv_sec) * 1e9 + (t1.tv_nsec - t0.tv_nsec);
|
||||
```
|
||||
|
||||
### Rust std (cross-platform)
|
||||
```rust
|
||||
use std::time::Instant;
|
||||
let t0 = Instant::now();
|
||||
heavy_work();
|
||||
println!("took {:?}", t0.elapsed()); // sub-ns precision on modern HW
|
||||
```
|
||||
|
||||
### Debounce slow timers
|
||||
```javascript
|
||||
// If you measure dt < 0.1ms repeatedly, you're in fuzzed timer mode.
|
||||
function isolatedPrecisionAvailable() {
|
||||
const samples = Array.from({length: 100}, () => {
|
||||
const a = performance.now(); const b = performance.now();
|
||||
return b - a;
|
||||
});
|
||||
return samples.some(d => d > 0 && d < 0.05); // sub-100µs visible
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Wall-clock event log | `Date.now()` / `Date.toISOString()` |
|
||||
| Profile / micro-bench | `performance.now()` + User Timing |
|
||||
| Frame loop | rAF callback timestamp (매 monotonic) |
|
||||
| Audio sync | `AudioContext.currentTime` |
|
||||
| Cross-origin iframe | postMessage with monotonic delta |
|
||||
| Native (Linux/macOS) | `clock_gettime(CLOCK_MONOTONIC)` |
|
||||
| Native (Windows) | `QueryPerformanceCounter` |
|
||||
|
||||
**기본값**: Duration 측정엔 매 monotonic. 매 Date 는 user-facing timestamp 만.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[Long Tasks]]
|
||||
- 응용: [[Core Web Vitals Optimization (INP, LCP, CLS)|Core Web Vitals]]
|
||||
- Adjacent: [[Spectre]] · [[Cross-Origin Isolation]] · [[SharedArrayBuffer]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 성능 측정 코드 작성, profiling, frame budget 분석.
|
||||
**언제 X**: Persistent timestamp / event log 매 wall-clock 필요 시.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **`Date.now()` for delta**: NTP step 시 음수 / 점프 가능.
|
||||
- **`new Date()` 매 hot loop**: allocation cost + ms 한계.
|
||||
- **Assuming sub-ms precision**: COOP/COEP 없으면 매 1ms rounded.
|
||||
- **Cross-origin worker timing**: postMessage 의 매 ms 단위 transmit overhead.
|
||||
- **`setTimeout` 으로 정밀 timing**: 매 4ms+ minimum, jittery.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (W3C HR Time Level 3, MDN performance.now, Chrome timer reduction notes).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — performance.now + Spectre mitigation + COOP/COEP 5µs |
|
||||
@@ -0,0 +1,186 @@
|
||||
---
|
||||
id: wiki-2026-0508-husky
|
||||
title: Husky
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Husky Git Hooks, husky v9, lint-staged, pre-commit]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [git, hooks, devex, ci, lint-staged]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: javascript
|
||||
framework: husky-v9
|
||||
---
|
||||
|
||||
# Husky
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 npm-friendly git hooks 의 facto-standard"**. Husky 는 매 `.husky/` directory 안에 매 plain shell script 로 hook 정의 — 매 `git config core.hooksPath` 으로 자동 설정. 매 v9 (2024-2026) 부터 매 거의 zero-config: `npx husky init` → 매 husky/_/h prepare-commit-msg 등 매 wrapper 자동 생성. 매 lint-staged 와의 매 pairing 이 매 표준 setup.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 핵심 개념
|
||||
- **core.hooksPath = .husky/_**: Husky 가 매 이 path 로 git 을 redirect — 매 user 의 매 hook script 와 매 husky framework script 분리.
|
||||
- **Plain shell**: 매 `.husky/pre-commit` 의 매 첫 line shebang 없이 — Husky v9 가 매 `_/h` wrapper 통해 실행.
|
||||
- **Skip via env**: `HUSKY=0` 또는 `HUSKY_SKIP_HOOKS=1` — 매 CI 또는 emergency commit.
|
||||
- **prepare script**: `package.json` 의 `"prepare": "husky"` 가 매 install 시 자동 setup.
|
||||
|
||||
### 매 lint-staged 와의 결합
|
||||
- 매 staged files 만 lint/format → 매 commit 속도 ↑.
|
||||
- 매 prettier --write + eslint --fix + 매 자동 re-stage.
|
||||
- 매 large monorepo 에서도 매 fast (only changed paths).
|
||||
|
||||
### 매 hook 우선순위 (자주 쓰는)
|
||||
1. **pre-commit**: lint-staged + type-check (changed only).
|
||||
2. **commit-msg**: commitlint (Conventional Commits 검증).
|
||||
3. **pre-push**: full test suite + build smoke.
|
||||
4. **post-merge**: pnpm install if `package.json` changed.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Initial setup
|
||||
```bash
|
||||
# in repo root
|
||||
pnpm add -D husky lint-staged
|
||||
pnpm pkg set scripts.prepare="husky"
|
||||
pnpm prepare
|
||||
npx husky init # creates .husky/pre-commit with `npm test` placeholder
|
||||
```
|
||||
|
||||
### .husky/pre-commit (lint-staged + type-check)
|
||||
```sh
|
||||
npx lint-staged
|
||||
pnpm exec tsc --noEmit
|
||||
```
|
||||
|
||||
### lint-staged config (package.json)
|
||||
```json
|
||||
{
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx,js,jsx}": [
|
||||
"eslint --fix --max-warnings=0",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{json,md,yml,yaml}": ["prettier --write"],
|
||||
"*.css": ["stylelint --fix", "prettier --write"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### .husky/commit-msg (commitlint)
|
||||
```sh
|
||||
npx --no -- commitlint --edit "$1"
|
||||
```
|
||||
|
||||
```js
|
||||
// commitlint.config.js
|
||||
module.exports = {
|
||||
extends: ['@commitlint/config-conventional'],
|
||||
rules: {
|
||||
'subject-max-length': [2, 'always', 100],
|
||||
'scope-enum': [2, 'always', ['ui', 'api', 'docs', 'ci', 'deps']],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### .husky/pre-push (test + build)
|
||||
```sh
|
||||
pnpm test --run --silent
|
||||
pnpm build
|
||||
```
|
||||
|
||||
### Skip in CI / emergency
|
||||
```bash
|
||||
# CI: prepare script no-op when not in dev install
|
||||
# package.json
|
||||
{
|
||||
"scripts": {
|
||||
"prepare": "node -e \"if (process.env.CI) process.exit(0)\" && husky"
|
||||
}
|
||||
}
|
||||
|
||||
# Emergency commit (use sparingly)
|
||||
HUSKY=0 git commit -m "hotfix: critical patch"
|
||||
# or
|
||||
git commit --no-verify -m "..."
|
||||
```
|
||||
|
||||
### Monorepo: only run hooks if relevant
|
||||
```sh
|
||||
# .husky/pre-commit
|
||||
CHANGED=$(git diff --cached --name-only)
|
||||
echo "$CHANGED" | grep -q "^apps/web/" && (cd apps/web && pnpm lint-staged)
|
||||
echo "$CHANGED" | grep -q "^apps/api/" && (cd apps/api && pnpm lint-staged)
|
||||
```
|
||||
|
||||
### Conditional hook based on branch
|
||||
```sh
|
||||
# .husky/pre-push
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [ "$BRANCH" = "main" ]; then
|
||||
pnpm test --run
|
||||
pnpm build
|
||||
else
|
||||
pnpm test --run --bail=1
|
||||
fi
|
||||
```
|
||||
|
||||
### Adopt in existing repo
|
||||
```bash
|
||||
# After cloning, dependencies need install to run 'prepare'
|
||||
pnpm install # triggers `prepare` → husky sets core.hooksPath
|
||||
git config --get core.hooksPath # → .husky/_
|
||||
```
|
||||
|
||||
### Husky + pnpm workspaces filter
|
||||
```sh
|
||||
# .husky/pre-commit
|
||||
STAGED=$(git diff --cached --name-only)
|
||||
PKGS=$(echo "$STAGED" | awk -F/ '/^packages\// {print $2}' | sort -u)
|
||||
for p in $PKGS; do
|
||||
pnpm --filter "@repo/$p" lint-staged
|
||||
done
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| TS/JS project | Husky v9 + lint-staged |
|
||||
| Polyglot (Python, Go) | pre-commit framework (multi-lang) |
|
||||
| Heavy hooks (>10s) | move to pre-push, lighten pre-commit |
|
||||
| Solo dev hobby | optional — lint in CI alone may suffice |
|
||||
| Enterprise enforcement | husky + commitlint + branch protection |
|
||||
|
||||
**기본값**: 매 TS/JS team — Husky v9 + lint-staged + commitlint.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[pre-commit]] · [[lefthook]]
|
||||
- 응용: [[Lint-Staged]] · [[Conventional Commits]]
|
||||
- Adjacent: [[ESLint]] · [[Prettier]] · [[Biome]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 hook script 작성, lint-staged config 생성, commitlint rule 제안, monorepo conditional logic.
|
||||
**언제 X**: 매 binary install verification — local 환경에서 매 직접 실행.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **30s pre-commit**: 매 dev 가 매 --no-verify 습관화 → 매 hook 무용지물.
|
||||
- **Run full test in pre-commit**: 매 pre-push 로 옮기기.
|
||||
- **No CI fallback**: 매 hook 만 신뢰 → 매 --no-verify bypass 시 dirty commit.
|
||||
- **Husky 의 commit hook 안 비밀 커밋 검증 누락**: 매 detect-secrets / gitleaks pairing.
|
||||
- **Per-developer husky version drift**: 매 lockfile pin 필수.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Husky v9 docs 2026, lint-staged v15+).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Husky v9 + lint-staged + commitlint patterns |
|
||||
@@ -0,0 +1,188 @@
|
||||
---
|
||||
id: wiki-2026-0508-ifcjs
|
||||
title: IFCjs
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [That Open Engine, web-ifc, Three.js IFC, BIM viewer]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [bim, ifc, web, three-js, aec, webgl]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: web-ifc-three
|
||||
---
|
||||
|
||||
# IFCjs
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 browser 안의 IFC (Industry Foundation Classes) reader/viewer — 매 BIM 데이터를 매 Three.js scene 으로"**. IFCjs (현재 매 "That Open Engine" 으로 rebrand) 는 매 web-ifc (WASM IFC parser) + 매 Three.js based 매 viewer 의 묶음. 매 AEC (Architecture/Engineering/Construction) 매 web 진입의 standard. 매 2026 현재 매 OpenBIM 운동 의 매 핵심 component.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 stack 의 layer
|
||||
- **web-ifc (C++ → WASM)**: 매 IFC2x3 / IFC4 / IFC4x3 STEP file 의 매 streaming parser.
|
||||
- **web-ifc-three** (legacy): 매 Three.js mesh 로 변환, property set 추출.
|
||||
- **@thatopen/components**: 매 modern (2024+) — Three.js 위 UI/tool framework.
|
||||
- **@thatopen/ui**: 매 web-component 기반 panel/grid/property card.
|
||||
|
||||
### 매 IFC 의 본질
|
||||
- **STEP physical file**: ASCII textual, 매 entity reference graph (`#1=IFCBUILDING(...)`).
|
||||
- **EXPRESS schema**: 매 IFC4 는 매 1700+ entity types.
|
||||
- **Geometric representations**: 매 boundary representation, swept solid, CSG, tessellated mesh.
|
||||
- **Property sets (Psets)**: 매 entity 별 매 metadata bag.
|
||||
|
||||
### 매 web vs desktop trade-off
|
||||
- 매 desktop (Revit, ArchiCAD): full editing, plugin ecosystem.
|
||||
- 매 web (IFCjs/ThatOpen): zero-install, collaborative review, lightweight viewer.
|
||||
- 매 hybrid: 매 export IFC from Revit → web viewer.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Basic IFC viewer (ThatOpen Components 2024+)
|
||||
```ts
|
||||
import * as OBC from '@thatopen/components';
|
||||
import * as THREE from 'three';
|
||||
|
||||
const components = new OBC.Components();
|
||||
const worlds = components.get(OBC.Worlds);
|
||||
const world = worlds.create<
|
||||
OBC.SimpleScene, OBC.SimpleCamera, OBC.SimpleRenderer
|
||||
>();
|
||||
|
||||
const container = document.getElementById('app')!;
|
||||
world.scene = new OBC.SimpleScene(components);
|
||||
world.renderer = new OBC.SimpleRenderer(components, container);
|
||||
world.camera = new OBC.SimpleCamera(components);
|
||||
world.scene.setup();
|
||||
|
||||
components.init();
|
||||
|
||||
const fragments = components.get(OBC.FragmentsManager);
|
||||
const ifcLoader = components.get(OBC.IfcLoader);
|
||||
await ifcLoader.setup();
|
||||
|
||||
const file = await fetch('/models/building.ifc');
|
||||
const buffer = new Uint8Array(await file.arrayBuffer());
|
||||
const model = await ifcLoader.load(buffer);
|
||||
world.scene.three.add(model);
|
||||
```
|
||||
|
||||
### Property extraction via web-ifc directly
|
||||
```ts
|
||||
import { IfcAPI, IFCWALLSTANDARDCASE } from 'web-ifc';
|
||||
|
||||
const api = new IfcAPI();
|
||||
api.SetWasmPath('/wasm/');
|
||||
await api.Init();
|
||||
|
||||
const data = new Uint8Array(await fetch('/m.ifc').then(r => r.arrayBuffer()));
|
||||
const modelID = api.OpenModel(data);
|
||||
|
||||
const wallIDs = api.GetLineIDsWithType(modelID, IFCWALLSTANDARDCASE);
|
||||
for (let i = 0; i < wallIDs.size(); i++) {
|
||||
const id = wallIDs.get(i);
|
||||
const wall = api.GetLine(modelID, id, true); // recursive expand refs
|
||||
console.log(wall.GlobalId.value, wall.Name?.value);
|
||||
}
|
||||
api.CloseModel(modelID);
|
||||
```
|
||||
|
||||
### Picking + property panel
|
||||
```ts
|
||||
const highlighter = components.get(OBC.Highlighter);
|
||||
highlighter.setup({ world });
|
||||
|
||||
highlighter.events.select.onHighlight.add(async (fragmentMap) => {
|
||||
const indexer = components.get(OBC.IfcRelationsIndexer);
|
||||
for (const fragId in fragmentMap) {
|
||||
const expressIDs = [...fragmentMap[fragId]];
|
||||
for (const id of expressIDs) {
|
||||
const psets = await indexer.getEntityRelations(model, id, 'IsDefinedBy');
|
||||
console.log('expressID', id, 'psets', psets);
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Convert IFC → fragments (compact binary)
|
||||
```ts
|
||||
// fragments are ThatOpen's optimized binary mesh format
|
||||
const fragmentManager = components.get(OBC.FragmentsManager);
|
||||
const buffer = fragmentManager.export(model);
|
||||
await fetch('/upload', { method: 'POST', body: buffer });
|
||||
```
|
||||
|
||||
### Server-side conversion (Node + web-ifc-node)
|
||||
```ts
|
||||
import { IfcAPI } from 'web-ifc/web-ifc-api-node';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
const api = new IfcAPI();
|
||||
api.SetWasmPath('node_modules/web-ifc/');
|
||||
await api.Init();
|
||||
const buf = await fs.readFile('input.ifc');
|
||||
const id = api.OpenModel(buf);
|
||||
const flatMesh = api.LoadAllGeometry(id);
|
||||
// ... extract triangles, write to glTF
|
||||
```
|
||||
|
||||
### BIM clash detection (rough proxy)
|
||||
```ts
|
||||
import { Box3, Vector3 } from 'three';
|
||||
|
||||
function findClashes(meshes: THREE.Mesh[]) {
|
||||
const boxes = meshes.map(m => {
|
||||
const b = new Box3().setFromObject(m);
|
||||
return { box: b, mesh: m };
|
||||
});
|
||||
const clashes: [THREE.Mesh, THREE.Mesh][] = [];
|
||||
for (let i = 0; i < boxes.length; i++)
|
||||
for (let j = i + 1; j < boxes.length; j++)
|
||||
if (boxes[i].box.intersectsBox(boxes[j].box))
|
||||
clashes.push([boxes[i].mesh, boxes[j].mesh]);
|
||||
return clashes;
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Web-only IFC viewer | ThatOpen Components |
|
||||
| Server-side IFC parsing | web-ifc-node |
|
||||
| Property extraction only | web-ifc API directly |
|
||||
| Heavy editing | desktop (Revit) export |
|
||||
| Massive models (>1GB) | fragments format + tile streaming |
|
||||
| Clash detection on web | use AABB pre-filter + GPU mesh-mesh |
|
||||
|
||||
**기본값**: 매 modern AEC web app — ThatOpen Components + fragments.
|
||||
|
||||
## 🔗 Graph
|
||||
- 응용: [[Digital Twin]]
|
||||
- Adjacent: [[Three.js]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: IFC entity 의 mapping 설명 (IFC → glTF), property set 매 자연어 query, 매 UI panel scaffold.
|
||||
**언제 X**: 매 large IFC parsing performance 최적화 — 매 measure 매 직접.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Loading 1GB IFC into browser memory directly**: 매 OOM — 매 fragments + streaming 사용.
|
||||
- **Recursive GetLine on every entity**: 매 N² — 매 IfcRelationsIndexer 사용.
|
||||
- **Treating IFC as glTF**: 매 IFC 는 매 graph + semantics, 매 mesh-only X.
|
||||
- **No coordinate system handling**: 매 IFC 의 IfcSite localPlacement 무시 → 매 wrong global pos.
|
||||
- **Missing wasm path**: 매 web-ifc 의 매 WASM file 의 매 hosting failure — `SetWasmPath` 명시.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (ThatOpen Engine docs 2026, web-ifc GitHub).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — IFC stack + ThatOpen Components patterns |
|
||||
@@ -0,0 +1,182 @@
|
||||
---
|
||||
id: wiki-2026-0508-incremental-build
|
||||
title: Incremental Build
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Incremental Compilation, Cached Build, Build Cache]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [build, ci, performance, monorepo, caching]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: turborepo
|
||||
---
|
||||
|
||||
# Incremental Build
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 변경된 파일 + downstream 의존성만 rebuild — 매 hash-based caching 의 핵심"**. 매 1979 Make 의 mtime-based 시작, 매 2026 Turborepo/Nx/Bazel 의 content-addressed cache 가 default — 매 monorepo 에서 100x speedup 흔함.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 작동 원리
|
||||
- **Input hash**: 매 source files + deps + env → SHA256.
|
||||
- **Cache key**: hash → output artifacts (dist/, .d.ts).
|
||||
- **Hit**: cache 존재 → restore, skip work.
|
||||
- **Miss**: rebuild, store.
|
||||
|
||||
### 매 granularity
|
||||
- **File-level**: tsc --incremental (.tsbuildinfo).
|
||||
- **Task-level**: Turborepo (per-package).
|
||||
- **Action-level**: Bazel (per-rule, hermetic).
|
||||
|
||||
### 매 응용
|
||||
1. Monorepo CI: 매 affected package 만 test.
|
||||
2. Local dev: watch mode, 매 sub-second rebuild.
|
||||
3. Docker: layer caching = path 별 invalidation.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Turborepo pipeline
|
||||
```json
|
||||
// turbo.json
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"globalDependencies": ["tsconfig.base.json"],
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["src/**", "package.json", "tsconfig.json"],
|
||||
"outputs": ["dist/**", ".next/**"],
|
||||
"cache": true
|
||||
},
|
||||
"test": {
|
||||
"dependsOn": ["build"],
|
||||
"inputs": ["src/**", "test/**"],
|
||||
"outputs": ["coverage/**"]
|
||||
},
|
||||
"lint": { "cache": true, "outputs": [] }
|
||||
},
|
||||
"remoteCache": { "signature": true }
|
||||
}
|
||||
```
|
||||
|
||||
### TypeScript incremental
|
||||
```json
|
||||
// tsconfig.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": ".cache/tsbuild.json",
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../core" },
|
||||
{ "path": "../utils" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Nx affected
|
||||
```bash
|
||||
# Only test packages affected by changes since main
|
||||
nx affected --target=test --base=origin/main --head=HEAD --parallel=4
|
||||
|
||||
# Print affected graph
|
||||
nx graph --affected --base=origin/main
|
||||
```
|
||||
|
||||
### Vite HMR (sub-second)
|
||||
```ts
|
||||
// vite.config.ts
|
||||
import { defineConfig } from 'vite';
|
||||
export default defineConfig({
|
||||
server: {
|
||||
hmr: { overlay: true },
|
||||
watch: { usePolling: false, ignored: ['**/node_modules/**', '**/dist/**'] }
|
||||
},
|
||||
build: {
|
||||
rollupOptions: { cache: true }
|
||||
},
|
||||
cacheDir: '.cache/vite'
|
||||
});
|
||||
```
|
||||
|
||||
### GitHub Actions remote cache
|
||||
```yaml
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
.turbo
|
||||
node_modules/.cache
|
||||
key: turbo-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.sha }}
|
||||
restore-keys: turbo-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
||||
|
||||
- run: pnpm turbo run build test --cache-dir=.turbo
|
||||
```
|
||||
|
||||
### Bazel hermetic action
|
||||
```python
|
||||
# BUILD.bazel
|
||||
load("@npm//@bazel/typescript:index.bzl", "ts_project")
|
||||
ts_project(
|
||||
name = "core",
|
||||
srcs = glob(["src/**/*.ts"]),
|
||||
declaration = True,
|
||||
incremental = True,
|
||||
deps = ["//packages/utils"],
|
||||
)
|
||||
```
|
||||
|
||||
### Cache hit ratio metric
|
||||
```ts
|
||||
// scripts/cache-stats.ts
|
||||
import { execSync } from 'node:child_process';
|
||||
const out = execSync('turbo run build --dry=json').toString();
|
||||
const tasks = JSON.parse(out).tasks;
|
||||
const hits = tasks.filter((t: any) => t.cache.status === 'HIT').length;
|
||||
console.log(`cache hit: ${hits}/${tasks.length} = ${(hits/tasks.length*100).toFixed(1)}%`);
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Monorepo 10+ packages | Turborepo or Nx |
|
||||
| Strict reproducibility | Bazel (hermetic) |
|
||||
| Single TS app | tsc --incremental + Vite |
|
||||
| Docker images | BuildKit + multi-stage layer cache |
|
||||
|
||||
**기본값**: 매 Turborepo + remote cache (Vercel or self-hosted).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Continuous Integration]]
|
||||
- 응용: [[CI_CD_Pipeline]]
|
||||
- Adjacent: [[Dependency Graph]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 turbo.json/nx.json 의 generation, cache key tuning 추천.
|
||||
**언제 X**: 매 Bazel hermetic rule — 매 strict, LLM hallucination 위험.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Time-based keys**: `date +%s` cache key — 매 hit 0%.
|
||||
- **Untracked inputs**: env var, system clock 의존 → false hit.
|
||||
- **Cache everything**: lint output 까지 cache → debugging 의 hell.
|
||||
- **No remote cache**: CI 매 fresh 시작 → local-only 의 무의미.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Turborepo 2.x, Nx 20+, Bazel 7+ 공식 docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — incremental build 의 hash caching 정리 |
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
id: wiki-2026-0508-inferential-statistics
|
||||
title: Inferential Statistics
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Statistical Inference, Hypothesis Testing, Confidence Intervals]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.92
|
||||
verification_status: applied
|
||||
tags: [statistics, inference, hypothesis-testing, ab-testing, sre]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: scipy
|
||||
---
|
||||
|
||||
# Inferential Statistics
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 sample → population parameter 의 추정 + uncertainty 의 quantify"**. 매 1900s Fisher, Neyman, Pearson 의 frequentist framework, 매 2026 A/B test, SRE alerting, ML evaluation 의 backbone — Bayesian + bootstrap 의 modern hybrid 가 default.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Frequentist vs Bayesian
|
||||
- **Frequentist**: parameter fixed, data random. p-value, CI.
|
||||
- **Bayesian**: parameter random (prior), data fixed. Posterior, credible interval.
|
||||
- **Bootstrap**: distribution-free, resample n→inf 시뮬레이션.
|
||||
|
||||
### 매 Test 분류
|
||||
- **Parametric**: t-test, ANOVA, Z-test (assumes normal).
|
||||
- **Non-parametric**: Mann-Whitney U, Kruskal-Wallis, permutation.
|
||||
- **Sequential**: Always Valid Inference, mSPRT (peek-safe).
|
||||
|
||||
### 매 응용
|
||||
1. A/B test: conversion lift 측정.
|
||||
2. SRE: SLO breach 의 statistical significance.
|
||||
3. ML: model A vs B 의 holdout 비교.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Two-sample t-test
|
||||
```python
|
||||
import scipy.stats as st
|
||||
control = [12, 14, 11, 13, 12, 15, 13]
|
||||
treat = [16, 18, 15, 17, 19, 16, 18]
|
||||
res = st.ttest_ind(control, treat, equal_var=False)
|
||||
print(f"t={res.statistic:.3f} p={res.pvalue:.4f}")
|
||||
ci = res.confidence_interval(0.95)
|
||||
print(f"95% CI: [{ci.low:.2f}, {ci.high:.2f}]")
|
||||
```
|
||||
|
||||
### Bootstrap CI
|
||||
```python
|
||||
import numpy as np
|
||||
def bootstrap_mean_ci(x, n=10_000, alpha=0.05):
|
||||
rng = np.random.default_rng(42)
|
||||
boots = rng.choice(x, size=(n, len(x)), replace=True).mean(axis=1)
|
||||
return np.quantile(boots, [alpha/2, 1-alpha/2])
|
||||
|
||||
ci = bootstrap_mean_ci(np.array(control))
|
||||
print(f"Bootstrap 95% CI: {ci}")
|
||||
```
|
||||
|
||||
### Sample size calculation (power)
|
||||
```python
|
||||
from statsmodels.stats.power import TTestIndPower
|
||||
analysis = TTestIndPower()
|
||||
n = analysis.solve_power(effect_size=0.3, power=0.8, alpha=0.05)
|
||||
print(f"매 group 당 n = {int(np.ceil(n))}")
|
||||
```
|
||||
|
||||
### Sequential test (mSPRT, peek-safe)
|
||||
```python
|
||||
import numpy as np
|
||||
def msprt_log_likelihood(x, mu0=0, sigma=1, theta=0.1):
|
||||
n = len(x); xbar = np.mean(x); v = sigma**2
|
||||
tau2 = theta**2
|
||||
log_bf = 0.5*np.log(v/(v+n*tau2)) + (n**2 * (xbar-mu0)**2 * tau2) / (2*v*(v+n*tau2))
|
||||
return log_bf # > log(1/alpha) 매 reject H0
|
||||
```
|
||||
|
||||
### Bayesian A/B (PyMC)
|
||||
```python
|
||||
import pymc as pm
|
||||
with pm.Model() as m:
|
||||
p_a = pm.Beta("p_a", 1, 1)
|
||||
p_b = pm.Beta("p_b", 1, 1)
|
||||
pm.Binomial("y_a", n=10_000, p=p_a, observed=520)
|
||||
pm.Binomial("y_b", n=10_000, p=p_b, observed=580)
|
||||
diff = pm.Deterministic("diff", p_b - p_a)
|
||||
idata = pm.sample(2000, chains=4, random_seed=42)
|
||||
print(f"P(B > A) = {(idata.posterior['diff'] > 0).mean().item():.3f}")
|
||||
```
|
||||
|
||||
### Permutation test
|
||||
```python
|
||||
def permutation_test(a, b, n=10_000):
|
||||
diff_obs = np.mean(a) - np.mean(b)
|
||||
pool = np.concatenate([a, b])
|
||||
rng = np.random.default_rng(0)
|
||||
diffs = []
|
||||
for _ in range(n):
|
||||
rng.shuffle(pool)
|
||||
diffs.append(np.mean(pool[:len(a)]) - np.mean(pool[len(a):]))
|
||||
return np.mean(np.abs(diffs) >= abs(diff_obs))
|
||||
```
|
||||
|
||||
### SRE: Welch's test on latency p99
|
||||
```python
|
||||
# 매 deploy 전후 latency p99 비교
|
||||
from scipy.stats import ttest_ind
|
||||
before_p99 = np.array([124, 130, 128, 132, 125]) # ms
|
||||
after_p99 = np.array([142, 138, 145, 140, 144])
|
||||
t, p = ttest_ind(before_p99, after_p99, equal_var=False)
|
||||
if p < 0.01: print("매 regression detected — rollback")
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Fixed-N A/B | t-test or chi-squared |
|
||||
| Continuous monitoring | mSPRT or always-valid CI |
|
||||
| Small N, non-normal | Bootstrap or permutation |
|
||||
| Multi-arm + prior | Bayesian (Beta-Binomial) |
|
||||
|
||||
**기본값**: Bootstrap CI + sequential test 의 production A/B.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Statistics & Data Analysis]] · [[Probability Theory]]
|
||||
- 변형: [[Bayesian_Inference|Bayesian Inference]]
|
||||
- 응용: [[SRE]] · [[Anomaly-Detection]]
|
||||
- Adjacent: [[Type 1 vs Type 2 Errors]] · [[Power Analysis]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: test 선택 의 advice (data shape → test type), 의 result interpretation.
|
||||
**언제 X**: 매 multiple-comparison correction 매 자동화 X — domain knowledge 필요.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **p-hacking**: 매 multiple test 후 cherry-pick.
|
||||
- **Peeking**: fixed-N test 의 매 day 확인 → α inflation.
|
||||
- **Single point**: CI 매 보고 안하고 mean 만.
|
||||
- **N=∞ → significance ≠ effect size**: Cohen's d 도 같이.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Casella & Berger "Statistical Inference", scipy/statsmodels docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — frequentist + Bayesian + sequential pattern |
|
||||
@@ -0,0 +1,150 @@
|
||||
---
|
||||
id: wiki-2026-0508-information-society
|
||||
title: Information Society
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Post-Industrial Society, Network Society, Knowledge Economy]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [society, sociology, internet, economy, policy]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: na
|
||||
framework: na
|
||||
---
|
||||
|
||||
# Information Society
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 information 의 production · distribution · consumption 의 dominant economic activity 의 society"**. 매 Bell (1973) 의 post-industrial 의 prediction 의 Castells (1996) 의 network society 의 elaboration 의 2026 년 의 LLM 의 cognitive labor 의 partial automation 의 phase 의 entry. 매 attention economy + algorithmic curation + AI 의 mediation 의 defining traits.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 phase
|
||||
1. **Industrial (1800-1970)**: 매 goods + capital.
|
||||
2. **Post-industrial (1970-2000)**: 매 service + knowledge worker.
|
||||
3. **Network society (2000-2020)**: 매 internet, platform, social media.
|
||||
4. **AI-mediated (2020-)**: 매 algorithmic curation + LLM 의 cognitive labor automation.
|
||||
|
||||
### 매 핵심 dynamics
|
||||
- **Attention as scarce resource** (Simon 1971).
|
||||
- **Network effects** — value ∝ users² (Metcalfe).
|
||||
- **Power-law distribution** — winner-take-most (rich-get-richer).
|
||||
- **Surveillance capitalism** (Zuboff 2019) — behavioral data 의 commodification.
|
||||
|
||||
### 매 응용 / 영향
|
||||
1. Platform economy (Uber, Airbnb).
|
||||
2. Filter bubble + algorithmic polarization.
|
||||
3. Digital divide (access inequality).
|
||||
4. AI-driven labor displacement (knowledge work).
|
||||
5. Misinformation / generative content flood.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Network effect simulation
|
||||
```python
|
||||
import numpy as np
|
||||
|
||||
def network_value(n_users, type='metcalfe'):
|
||||
"""Value of a network as users grow."""
|
||||
if type == 'sarnoff': return n_users # broadcast
|
||||
if type == 'metcalfe': return n_users ** 2 # peer-to-peer
|
||||
if type == 'reed': return 2 ** n_users # group-forming
|
||||
raise ValueError(type)
|
||||
|
||||
# Implication: marginal user adds disproportionate value
|
||||
# → winner-take-most platform dynamics
|
||||
```
|
||||
|
||||
### Power-law follower distribution
|
||||
```python
|
||||
# Most social platforms: Pareto / Zipf distribution
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
n_users = 1_000_000
|
||||
followers = np.random.zipf(a=1.5, size=n_users)
|
||||
# top 1% holds ~50%+ of total reach
|
||||
top_1pct = np.sort(followers)[-n_users // 100:].sum() / followers.sum()
|
||||
print(f"Top 1% share: {top_1pct:.1%}")
|
||||
```
|
||||
|
||||
### Filter-bubble simulator (echo chamber)
|
||||
```python
|
||||
def update_belief(belief, exposed_content, alpha=0.1):
|
||||
# users see content aligned with their belief (algo-curated)
|
||||
aligned = [c for c in exposed_content if abs(c - belief) < 0.3]
|
||||
if aligned:
|
||||
belief += alpha * (np.mean(aligned) - belief)
|
||||
return belief
|
||||
|
||||
# Over many iterations → polarization (variance ↑, mean clusters)
|
||||
```
|
||||
|
||||
### Attention-economy revenue model
|
||||
```python
|
||||
def ad_revenue(daus, sessions_per_day, ads_per_session, cpm):
|
||||
impressions = daus * sessions_per_day * ads_per_session
|
||||
return impressions / 1000 * cpm
|
||||
|
||||
# Engagement-maximization → outrage / novelty → societal externalities
|
||||
```
|
||||
|
||||
### Digital-divide index
|
||||
```python
|
||||
def digital_divide_score(country):
|
||||
return 0.4 * country.broadband_penetration + \
|
||||
0.3 * country.literacy_rate + \
|
||||
0.2 * country.smartphone_penetration + \
|
||||
0.1 * country.ai_tool_access
|
||||
```
|
||||
|
||||
### LLM-mediated labor share (2026)
|
||||
```python
|
||||
# Productivity uplift studies (Brynjolfsson 2024, etc.)
|
||||
def cognitive_task_time_with_llm(baseline_hours, task_type):
|
||||
uplift = {
|
||||
'writing': 0.40, 'coding': 0.55, 'research': 0.30,
|
||||
'creative_strategy': 0.20, 'manual': 0.0
|
||||
}
|
||||
return baseline_hours * (1 - uplift.get(task_type, 0))
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
|
||||
| 상황 | Lens |
|
||||
|---|---|
|
||||
| Platform design | Network effects + power-law dynamics |
|
||||
| Content policy | Attention economy externalities |
|
||||
| Public policy | Digital divide + labor displacement |
|
||||
| Org strategy | Knowledge worker + AI augmentation |
|
||||
| Civic discourse | Filter bubble + misinformation |
|
||||
|
||||
**기본값**: 매 multi-lens — 매 single theory 의 over-generalize 의 risk.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[Network Society]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 frame analysis, multi-perspective synthesis. 매 tech-policy intersection 의 explanation.
|
||||
**언제 X**: 매 country-specific 의 latest stat 은 fact-check. 매 LLM 의 stale 의 risk.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Tech-determinist 의 simplification**: 매 society shapes tech 의 too. 매 reciprocal.
|
||||
- **Single-metric (GDP, DAU) 의 over-reliance**: 매 well-being externality 의 miss.
|
||||
- **AI = neutral 의 assumption**: 매 X. 매 training data + deployment context 의 bias 의 carry.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Bell 1973, Castells 1996, Zuboff 2019, Brynjolfsson 2024).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — network society + AI-mediated phase synthesis |
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
id: wiki-2026-0508-instancedmesh2
|
||||
title: InstancedMesh2
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [three-instanced-mesh2, three.js-instancedmesh2]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [three.js, webgl, performance, instancing, rendering]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript
|
||||
framework: three.js
|
||||
---
|
||||
|
||||
# InstancedMesh2
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 InstancedMesh의 진화형 — frustum culling, LOD, BVH, per-instance uniforms를 그대로 지원하는 instancing 솔루션"**. 매 three.js의 stock InstancedMesh가 모든 instance를 ALWAYS draw 하는 한계를 극복하기 위해 등장한 community library — agargaro/instanced-mesh가 매 2024-2026 사실상 표준으로 자리잡음.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 stock InstancedMesh의 한계
|
||||
- 매 frustum culling 부재 → off-screen instance도 GPU에 commit
|
||||
- 매 per-instance visibility toggle 부재
|
||||
- 매 LOD 미지원 — 매 distance 무관 동일 mesh draw
|
||||
- 매 raycasting brute-force — 매 매 instance 매 triangle scan
|
||||
|
||||
### 매 InstancedMesh2 추가 기능
|
||||
- **Per-instance frustum culling**: 매 BVH 기반 fast cull
|
||||
- **LOD groups**: 매 distance threshold 별 다른 geometry
|
||||
- **BVH acceleration**: 매 raycast O(log n)
|
||||
- **Per-instance uniforms**: 매 색상/sprite frame/animation time 등
|
||||
- **Shadow culling**: 매 shadow camera frustum 별도 cull
|
||||
|
||||
### 매 응용
|
||||
1. 매 RTS/시뮬레이션 — 매 1k+ unit 매 60fps.
|
||||
2. 매 archviz — 매 forest/도시 scenery instance.
|
||||
3. 매 particle alternative — 매 mesh-particle hybrid.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 매 기본 setup
|
||||
```typescript
|
||||
import { InstancedMesh2 } from '@three.ez/instanced-mesh';
|
||||
import * as THREE from 'three';
|
||||
|
||||
const geo = new THREE.BoxGeometry(1, 1, 1);
|
||||
const mat = new THREE.MeshStandardMaterial();
|
||||
const count = 10_000;
|
||||
|
||||
const mesh = new InstancedMesh2(geo, mat, { capacity: count });
|
||||
mesh.addInstances(count, (obj, idx) => {
|
||||
obj.position.set(
|
||||
(Math.random() - 0.5) * 200,
|
||||
0,
|
||||
(Math.random() - 0.5) * 200,
|
||||
);
|
||||
obj.color = new THREE.Color(Math.random(), Math.random(), Math.random());
|
||||
});
|
||||
mesh.computeBVH();
|
||||
scene.add(mesh);
|
||||
```
|
||||
|
||||
### 매 LOD groups
|
||||
```typescript
|
||||
const lod = new InstancedMesh2(geoHigh, mat, { capacity: 5000 });
|
||||
lod.addLOD(geoMid, mat, 30); // 30 units 부터 mid mesh
|
||||
lod.addLOD(geoLow, mat, 100); // 100 units 부터 low mesh
|
||||
lod.addShadowLOD(geoShadow, 50); // shadow 용 별도 LOD
|
||||
```
|
||||
|
||||
### 매 per-instance update
|
||||
```typescript
|
||||
mesh.updateInstances((obj, idx) => {
|
||||
obj.position.y = Math.sin(time + idx * 0.1);
|
||||
obj.rotation.y += 0.01;
|
||||
});
|
||||
```
|
||||
|
||||
### 매 frustum culling toggle
|
||||
```typescript
|
||||
mesh.perObjectFrustumCulled = true; // default
|
||||
mesh.sortObjects = true; // 매 transparent 매 back-to-front
|
||||
```
|
||||
|
||||
### 매 raycasting BVH
|
||||
```typescript
|
||||
mesh.computeBVH({ margin: 0 });
|
||||
const ray = new THREE.Raycaster();
|
||||
ray.setFromCamera(mouse, camera);
|
||||
const hits = ray.intersectObject(mesh);
|
||||
// hits[0].instanceId 매 정확한 instance
|
||||
```
|
||||
|
||||
### 매 instance 제거
|
||||
```typescript
|
||||
mesh.removeInstances([0, 5, 10]); // 매 batch 매 1 frame
|
||||
mesh.computeBVH(); // 매 dirty 면 rebuild
|
||||
```
|
||||
|
||||
### 매 color attribute
|
||||
```typescript
|
||||
mesh.setColorAt(idx, new THREE.Color('red'));
|
||||
mesh.instanceColor.needsUpdate = true;
|
||||
```
|
||||
|
||||
### 매 shader integration
|
||||
```typescript
|
||||
mat.onBeforeCompile = (shader) => {
|
||||
shader.vertexShader = shader.vertexShader.replace(
|
||||
'#include <begin_vertex>',
|
||||
`#include <begin_vertex>
|
||||
transformed += instanceMatrix[3].xyz * 0.01;`
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| <500 instance | 매 stock InstancedMesh |
|
||||
| 1k-100k 매 same geometry | InstancedMesh2 |
|
||||
| 매 different geometries | BatchedMesh |
|
||||
| 매 GPU-driven 매 indirect | 매 custom WebGPU |
|
||||
|
||||
**기본값**: 매 1k 이상 instance — InstancedMesh2.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[InstancedMesh]] · [[three.js]]
|
||||
- 변형: [[BatchedMesh]] · [[three-mesh-bvh]]
|
||||
- 응용: [[Frustum Culling]] · [[Draw Call]]
|
||||
- Adjacent: [[BVH]] · [[Raycasting|Raycaster]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 large-scale 동일 mesh scene — vegetation, crowd, debris.
|
||||
**언제 X**: 매 instance 별 geometry 다름 — BatchedMesh 사용.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **BVH 매 update 안 함**: 매 instance 이동 후 raycast 부정확.
|
||||
- **capacity 매 너무 크게**: 매 GPU memory 매 낭비.
|
||||
- **per-frame full update**: 매 dirty flag 만 flush.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (@three.ez/instanced-mesh v0.4+, three.js r170+).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — InstancedMesh2 라이브러리 사용법 + LOD/BVH 패턴 정리 |
|
||||
@@ -0,0 +1,184 @@
|
||||
---
|
||||
id: wiki-2026-0508-inversion
|
||||
title: Inversion
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Inversion of Control, Invert Thinking, Negative Visualization]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [thinking-model, ioc, di, mental-model, design]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: nestjs
|
||||
---
|
||||
|
||||
# Inversion
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 problem 의 reverse 매 stating — '매 fail 하는 방법' 의 enumerate, '매 control 의 누가 가지나' 의 flip"**. 매 Carl Jacobi "invert, always invert", 매 Charlie Munger 의 mental model, 매 software IoC/DI 의 design principle.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Inversion 3 layer
|
||||
- **Cognitive**: "매 success" 대신 "매 failure 의 path" 을 enumerate.
|
||||
- **Architectural (IoC)**: caller 가 control 하던 것을 framework 가 control.
|
||||
- **Dependency (DI)**: hard-coded `new Foo()` 대신 inject.
|
||||
|
||||
### 매 IoC 의 forms
|
||||
- **DI**: constructor/setter inject.
|
||||
- **Service Locator**: registry lookup.
|
||||
- **Events/Hooks**: publish-subscribe.
|
||||
- **Template Method**: framework 의 skeleton, user 의 fill-in.
|
||||
|
||||
### 매 응용
|
||||
1. Design review: failure mode enumeration.
|
||||
2. Testability: mock injection.
|
||||
3. Decision making: 매 worst case 의 list, 매 avoid.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### NestJS DI
|
||||
```ts
|
||||
@Injectable()
|
||||
export class UserRepo {
|
||||
findById(id: string) { /* ... */ }
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
// 매 instance 매 직접 만들지 않음 — framework 의 inject
|
||||
constructor(private readonly repo: UserRepo) {}
|
||||
async profile(id: string) { return this.repo.findById(id); }
|
||||
}
|
||||
|
||||
@Module({ providers: [UserRepo, UserService], exports: [UserService] })
|
||||
export class UserModule {}
|
||||
```
|
||||
|
||||
### Manual DI (no framework)
|
||||
```ts
|
||||
type Deps = { db: Database; cache: Cache; logger: Logger };
|
||||
export const makeUserService = ({ db, cache, logger }: Deps) => ({
|
||||
async findById(id: string) {
|
||||
const cached = await cache.get(id);
|
||||
if (cached) return cached;
|
||||
logger.debug('cache miss', id);
|
||||
return db.users.findUnique({ where: { id } });
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Premortem (failure inversion)
|
||||
```ts
|
||||
// scripts/premortem.ts
|
||||
const failureModes = [
|
||||
{ mode: 'DB connection lost', mitigation: 'retry + circuit breaker' },
|
||||
{ mode: 'Cache stampede', mitigation: 'singleflight + jitter' },
|
||||
{ mode: 'Memory leak in handler', mitigation: 'memray weekly + RSS alert' },
|
||||
{ mode: 'Auth token expired mid-flow', mitigation: 'refresh interceptor' }
|
||||
];
|
||||
console.table(failureModes);
|
||||
```
|
||||
|
||||
### Test seam via inversion
|
||||
```ts
|
||||
// 매 hard-coded fetch 대신 inject — testable
|
||||
type Fetcher = (url: string) => Promise<Response>;
|
||||
export const makeApi = (fetcher: Fetcher = fetch) => ({
|
||||
async get(path: string) {
|
||||
const r = await fetcher(`https://api.acme.com${path}`);
|
||||
return r.json();
|
||||
}
|
||||
});
|
||||
|
||||
// test
|
||||
const fakeFetch: Fetcher = async () => new Response(JSON.stringify({ ok: true }));
|
||||
expect(await makeApi(fakeFetch).get('/x')).toEqual({ ok: true });
|
||||
```
|
||||
|
||||
### Hook-based extension (template inversion)
|
||||
```ts
|
||||
// framework 의 lifecycle, user 의 hook 의 plug
|
||||
type Plugin = {
|
||||
beforeRequest?: (req: Request) => Request;
|
||||
afterResponse?: (res: Response) => Response;
|
||||
};
|
||||
|
||||
export class Server {
|
||||
private plugins: Plugin[] = [];
|
||||
use(p: Plugin) { this.plugins.push(p); }
|
||||
async handle(req: Request) {
|
||||
for (const p of this.plugins) req = p.beforeRequest?.(req) ?? req;
|
||||
let res = await this.process(req);
|
||||
for (const p of this.plugins) res = p.afterResponse?.(res) ?? res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Inverted error handling (Result type)
|
||||
```ts
|
||||
// 매 throw 대신 매 return 으로 invert — caller 의 forced handle
|
||||
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };
|
||||
|
||||
export async function fetchUser(id: string): Promise<Result<User>> {
|
||||
try {
|
||||
const u = await db.users.findUniqueOrThrow({ where: { id } });
|
||||
return { ok: true, value: u };
|
||||
} catch (e) {
|
||||
return { ok: false, error: e as Error };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Decision premortem prompt
|
||||
```ts
|
||||
// 매 launch 전 self-question
|
||||
const premortem = `
|
||||
1. 매 launch 6 month 후, 이 기능 매 fail 했다고 가정.
|
||||
2. 매 가장 가능한 5 failure cause 매 무엇?
|
||||
3. 매 매 cause 의 mitigation 매 무엇?
|
||||
`;
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Module 매 testable 만들기 | DI |
|
||||
| Framework 의 design | IoC + plugin hooks |
|
||||
| Decision making | Premortem (failure inversion) |
|
||||
| Error handling | Result type (return invert) |
|
||||
|
||||
**기본값**: constructor DI + premortem 매 architecture review 시.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Mental_Models|Mental Models]] · [[Software Design Principles]]
|
||||
- 변형: [[Dependency Injection]] · [[Inversion of Control]]
|
||||
- 응용: [[NestJS]] · [[Result Type]]
|
||||
- Adjacent: [[Encapsulation-via-Access-Modifiers]] · [[Testability]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 design 의 failure mode 의 brainstorm, IoC refactor 의 candidate 식별.
|
||||
**언제 X**: 매 trivial pure function 의 매 over-DI X — 매 simplicity 가 우선.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **DI everywhere**: simple value 도 inject → 매 boilerplate explosion.
|
||||
- **Service locator hell**: global registry 의 hidden dependency.
|
||||
- **No premortem**: 매 ship 후에야 매 failure 발견.
|
||||
- **Inversion theater**: interface 매 single impl 만 — 의 wrap 의 무의미.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Charlie Munger "Poor Charlie's Almanack", Martin Fowler "IoC Containers").
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — cognitive + IoC + DI inversion 통합 |
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
---
|
||||
id: wiki-2026-0508-issue-001-combat-reference-error
|
||||
title: Issue 001 Combat Reference Error Troubleshooting
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Reference Error Debugging, Runtime Reference Error]
|
||||
duplicate_of: none
|
||||
source_trust_level: B
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [debugging, reference-error, runtime, troubleshooting, combat-system]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: nodejs
|
||||
---
|
||||
|
||||
# Issue 001 Combat Reference Error Troubleshooting
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 ReferenceError 의 root cause 매 hoisting, TDZ, circular import, async timing 의 4 가지로 collapse"**. 매 case study (combat system 의 reference error) 를 통해 매 systematic debug pipeline 정리.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 ReferenceError 4 카테고리
|
||||
- **Undeclared**: variable 매 declare 안됨 (typo, missing import).
|
||||
- **TDZ**: `let`/`const` 매 init 전 access (temporal dead zone).
|
||||
- **Circular import**: A imports B, B imports A → 매 partially-loaded module.
|
||||
- **Async timing**: top-level await, dynamic import 의 race.
|
||||
|
||||
### 매 Combat case (post-mortem 요약)
|
||||
- **Symptom**: `ReferenceError: CombatEngine is not defined` 매 production only.
|
||||
- **Root cause**: Vite tree-shaking 의 side-effect import 의 elimination.
|
||||
- **Fix**: `package.json` 의 `"sideEffects": ["./src/combat/registry.ts"]`.
|
||||
|
||||
### 매 Debug 절차
|
||||
1. Reproduce: minimal repo.
|
||||
2. Stack trace: 매 first frame 의 file:line.
|
||||
3. Bisect: git bisect or feature flag.
|
||||
4. Verify: regression test 추가.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### TDZ 의 detection
|
||||
```ts
|
||||
// BAD — TDZ
|
||||
console.log(x); // ReferenceError
|
||||
let x = 1;
|
||||
|
||||
// GOOD — declare 먼저
|
||||
let x: number;
|
||||
x = 1;
|
||||
console.log(x);
|
||||
```
|
||||
|
||||
### Circular import resolve
|
||||
```ts
|
||||
// a.ts
|
||||
import { B } from './b';
|
||||
export class A { b = new B(); }
|
||||
|
||||
// b.ts — circular
|
||||
// import { A } from './a'; // 매 X
|
||||
// 매 type-only import 로 break:
|
||||
import type { A } from './a';
|
||||
export class B { parent?: A; }
|
||||
```
|
||||
|
||||
### Vite sideEffects 의 protect
|
||||
```json
|
||||
// package.json
|
||||
{
|
||||
"sideEffects": [
|
||||
"./src/combat/registry.ts",
|
||||
"./src/polyfills/*.ts",
|
||||
"*.css"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Webpack module federation 의 안전한 dynamic
|
||||
```ts
|
||||
const Combat = await import(/* webpackChunkName: "combat" */ './combat')
|
||||
.catch(err => {
|
||||
console.error('Combat module failed', err);
|
||||
return { CombatEngine: class FallbackEngine {} };
|
||||
});
|
||||
```
|
||||
|
||||
### Stack trace parser
|
||||
```ts
|
||||
function parseRefError(err: Error): { name: string; file?: string; line?: number } {
|
||||
const m = err.message.match(/(\w+) is not defined/);
|
||||
const frame = err.stack?.split('\n')[1]?.match(/at .* \((.+):(\d+):\d+\)/);
|
||||
return {
|
||||
name: m?.[1] ?? 'unknown',
|
||||
file: frame?.[1],
|
||||
line: frame ? Number(frame[2]) : undefined
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Regression test
|
||||
```ts
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { CombatEngine } from '@/combat';
|
||||
|
||||
describe('combat module loading', () => {
|
||||
it('exports CombatEngine after tree-shake', () => {
|
||||
expect(CombatEngine).toBeDefined();
|
||||
expect(typeof CombatEngine).toBe('function');
|
||||
});
|
||||
|
||||
it('registry has registered abilities', async () => {
|
||||
const { abilityRegistry } = await import('@/combat/registry');
|
||||
expect(abilityRegistry.size).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Sentry breadcrumb 의 capture
|
||||
```ts
|
||||
import * as Sentry from '@sentry/node';
|
||||
Sentry.init({
|
||||
beforeSend(event, hint) {
|
||||
if (hint.originalException instanceof ReferenceError) {
|
||||
event.tags = { ...event.tags, error_class: 'reference' };
|
||||
}
|
||||
return event;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| TDZ 의 의심 | 매 declaration 위치 의 audit |
|
||||
| Circular import | type-only import or DI |
|
||||
| Tree-shake elimination | sideEffects 명시 |
|
||||
| Async race | top-level await guard |
|
||||
|
||||
**기본값**: 매 minimal repro → bisect → regression test 의 add.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Debugger_Techniques]]
|
||||
- Adjacent: [[Source Maps]] · [[Sentry]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: stack trace + module graph paste → root cause hypothesis.
|
||||
**언제 X**: 매 production memory dump 매 직접 read X — local repro 가 우선.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Catch and ignore**: `try { ... } catch {}` — error 매 silently 사라짐.
|
||||
- **No regression test**: fix 후 test 매 추가 X → 매 regression repeat.
|
||||
- **Random side-effect import**: `import './magic'` — tree-shake 가 죽임.
|
||||
- **Production-only debug**: local 매 repro 안하고 prod 에서 console.log.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (MDN ReferenceError, Vite tree-shake docs).
|
||||
- 신뢰도 B (case-specific 의 detail).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — ReferenceError 의 4 카테고리 + combat case |
|
||||
@@ -0,0 +1,146 @@
|
||||
---
|
||||
id: wiki-2026-0508-jpeg-xl
|
||||
title: JPEG XL
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [jxl, jpeg-xl-format]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [image-format, compression, web-performance, codec]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: C++
|
||||
framework: libjxl
|
||||
---
|
||||
|
||||
# JPEG XL
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 royalty-free 차세대 image codec — 매 lossless JPEG transcoding + better-than-AVIF lossy"**. 매 ISO/IEC 18181 — 매 Cloudinary/Google이 design — 매 Safari 17+ 가 매 native 지원 — 매 2026 점진적 mainstream — 매 JPEG의 정신적 후계자.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 차별점
|
||||
- **lossless JPEG re-compress**: 매 기존 JPEG 의 평균 20% 매 추가 절감, 매 100% 매 reversible.
|
||||
- **wide gamut + HDR**: 매 BT.2100, PQ/HLG, alpha, animation.
|
||||
- **progressive decode**: 매 stream-as-you-go.
|
||||
- **CPU efficient**: 매 AVIF 보다 encode 매 빠름.
|
||||
|
||||
### 매 brower support (2026)
|
||||
- Safari 17+: native.
|
||||
- Chrome: behind flag — 매 unflag 검토 중.
|
||||
- Firefox: nightly flag.
|
||||
- 매 polyfill: jxl.js (WASM).
|
||||
|
||||
### 매 응용
|
||||
1. 매 photography archive 의 size 의 줄임.
|
||||
2. 매 CDN의 multi-format negotiation (jxl > avif > webp > jpeg).
|
||||
3. 매 raw → web pipeline의 매 single-format 통일.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 매 cjxl encode
|
||||
```bash
|
||||
cjxl input.png output.jxl -q 90 --effort 7
|
||||
# 매 distance 0.5-3.0 매 매우 high quality
|
||||
cjxl input.jpg out.jxl --lossless_jpeg=1 # 매 JPEG → JXL 매 lossless
|
||||
```
|
||||
|
||||
### 매 djxl decode
|
||||
```bash
|
||||
djxl out.jxl out.png
|
||||
djxl out.jxl out.jpg --jpeg_jxl_to_jpeg # 매 원본 JPEG bit-exact 복원
|
||||
```
|
||||
|
||||
### 매 sharp (Node.js)
|
||||
```javascript
|
||||
import sharp from 'sharp';
|
||||
await sharp('photo.jpg')
|
||||
.jxl({ quality: 85, effort: 7 })
|
||||
.toFile('photo.jxl');
|
||||
```
|
||||
|
||||
### 매 HTTP content negotiation
|
||||
```nginx
|
||||
map $http_accept $img_ext {
|
||||
~image/jxl ".jxl";
|
||||
~image/avif ".avif";
|
||||
~image/webp ".webp";
|
||||
default ".jpg";
|
||||
}
|
||||
location /img/ {
|
||||
try_files $uri$img_ext $uri =404;
|
||||
}
|
||||
```
|
||||
|
||||
### 매 picture element
|
||||
```html
|
||||
<picture>
|
||||
<source type="image/jxl" srcset="hero.jxl">
|
||||
<source type="image/avif" srcset="hero.avif">
|
||||
<source type="image/webp" srcset="hero.webp">
|
||||
<img src="hero.jpg" alt="hero">
|
||||
</picture>
|
||||
```
|
||||
|
||||
### 매 polyfill (WASM)
|
||||
```html
|
||||
<script type="module">
|
||||
import { decode } from 'https://unpkg.com/@jsquash/jxl';
|
||||
const buf = await fetch('photo.jxl').then(r => r.arrayBuffer());
|
||||
const imageData = await decode(buf);
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
</script>
|
||||
```
|
||||
|
||||
### 매 batch transcode
|
||||
```bash
|
||||
fd -e jpg . | parallel -j8 'cjxl {} {.}.jxl --lossless_jpeg=1'
|
||||
```
|
||||
|
||||
### 매 quality tuning
|
||||
```bash
|
||||
# 매 distance 매 lower = better quality
|
||||
# 매 1.0 매 visually lossless 의 일반적 target
|
||||
cjxl in.png out.jxl -d 1.0 -e 7
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 archival JPEG | 매 lossless JXL transcode |
|
||||
| 매 web photo modern | 매 JXL + AVIF fallback |
|
||||
| 매 universal 호환 | 매 JPEG/WebP 의 유지 |
|
||||
| 매 HDR/wide gamut | 매 JXL or AVIF |
|
||||
|
||||
**기본값**: 매 archival lossless transcode + web 의 multi-format negotiation.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Web Performance]]
|
||||
- 변형: [[AVIF]]
|
||||
- 응용: [[CDN]] · [[Page Experience Algorithm]]
|
||||
- Adjacent: [[Tree Shaking (번들 크기 최적화)]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 archive 매 size 의 reduce 매 reversible 요구.
|
||||
**언제 X**: 매 universal browser support 가 hard requirement.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **JPEG → JXL → JPEG quality 매 lossy**: 매 `--lossless_jpeg=1` 의 잊음.
|
||||
- **only JXL serve**: 매 Chrome user 매 broken image.
|
||||
- **--effort 9 매 production encode**: 매 CPU 의 30x.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (libjxl 0.10+, ISO/IEC 18181, Safari 17+).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — JPEG XL 인코딩/디코딩/HTTP negotiation 정리 |
|
||||
@@ -0,0 +1,132 @@
|
||||
---
|
||||
id: wiki-2026-0508-joern
|
||||
title: Joern
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [joern-cpg, code-property-graph-tool]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, sast, cpg, static-analysis, vulnerability]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Scala
|
||||
framework: ShiftLeft/Joern
|
||||
---
|
||||
|
||||
# Joern
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 Code Property Graph (CPG)를 query 하는 SAST 플랫폼 — 매 AST + CFG + DDG 통합 graph"**. 매 Yamaguchi 박사 논문에서 출발 — 매 ShiftLeft가 사실상의 사업화 — 매 2026 기준 매 C/C++/Java/Python/JS/Go 매 multi-language 매 OSS SAST 의 reference.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 CPG 란
|
||||
- AST (syntax) + CFG (control flow) + DDG (data dependence) 통합 단일 graph.
|
||||
- Node: function, identifier, literal, call, parameter, …
|
||||
- Edge: AST_PARENT, CFG, REACHING_DEF, CALL, …
|
||||
|
||||
### 매 query language
|
||||
- 매 CPGQL — Scala-based DSL.
|
||||
- 매 example: `cpg.call("strcpy").argument(2).reachableBy(cpg.parameter).p`
|
||||
|
||||
### 매 응용
|
||||
1. 매 vulnerability hunting — taint trace src→sink.
|
||||
2. 매 code review automation — pattern grep 보다 더 deep.
|
||||
3. 매 SBOM/SCA 보완 — first-party code의 weakness.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 매 install + import
|
||||
```bash
|
||||
brew install joern # 매 macOS
|
||||
joern
|
||||
joern> importCode(inputPath="/path/to/repo", projectName="myapp")
|
||||
joern> open("myapp")
|
||||
```
|
||||
|
||||
### 매 dangerous call 매 query
|
||||
```scala
|
||||
cpg.call.name("strcpy|gets|sprintf").l
|
||||
// 매 location 매 method 매 list
|
||||
cpg.call.name("strcpy").map(c => (c.method.name, c.lineNumber)).l
|
||||
```
|
||||
|
||||
### 매 taint flow (SQL injection)
|
||||
```scala
|
||||
def src = cpg.call.name("getParameter")
|
||||
def sink = cpg.call.name("executeQuery")
|
||||
sink.reachableByFlows(src).p
|
||||
```
|
||||
|
||||
### 매 custom rule (XSS)
|
||||
```scala
|
||||
def userInput = cpg.call.name(".*request.*get.*Param.*")
|
||||
def htmlSink = cpg.call.name(".*innerHTML.*|.*document\\.write.*")
|
||||
htmlSink.reachableByFlows(userInput).p
|
||||
```
|
||||
|
||||
### 매 method-level metric
|
||||
```scala
|
||||
cpg.method.where(_.numberOfLines.gt(100)).name.l
|
||||
cpg.method.controlStructure.size // 매 cyclomatic 근사
|
||||
```
|
||||
|
||||
### 매 export
|
||||
```scala
|
||||
cpg.runScript("exportCpg.sc", Map("outFile" -> "/tmp/cpg.bin.zip"))
|
||||
// 매 GraphML/dot 도 가능
|
||||
```
|
||||
|
||||
### 매 CI integration
|
||||
```yaml
|
||||
- name: Joern scan
|
||||
run: |
|
||||
joern-parse src/
|
||||
joern-scan --dump cpg.bin.zip > findings.json
|
||||
```
|
||||
|
||||
### 매 ocular (commercial fork)
|
||||
```scala
|
||||
// 매 ShiftLeft Ocular = Joern + secrets + IaC
|
||||
// 매 enterprise 매 secrets/license/SBOM 통합
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 quick grep | semgrep/CodeQL |
|
||||
| 매 deep taint multi-lang OSS | Joern |
|
||||
| 매 enterprise + secret + SBOM | ShiftLeft / Snyk Code |
|
||||
| 매 binary | Ghidra + plugin |
|
||||
|
||||
**기본값**: OSS multi-language SAST — Joern.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[SAST]] · [[Code_Property_Graph]]
|
||||
- 변형: [[CodeQL]] · [[Semgrep]]
|
||||
- 응용: [[보안 및 시스템 신뢰성 표준|OWASP Top 10]]
|
||||
- Adjacent: [[보안 및 시스템 신뢰성 표준|DAST]] · [[SCA_Fundamentals|SCA]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 cross-function taint trace 필요 — string-grep 매 부족할 때.
|
||||
**언제 X**: 매 single-line pattern — semgrep 매 빠르고 충분.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **CPG 매 too large 매 RAM**: 매 module 단위 분리 import.
|
||||
- **regex 매 method name 매 over-broad**: 매 false positive 폭발.
|
||||
- **flow 매 결과 매 그대로 trust**: 매 sanitizer 매 modeling 안 됐을 수도.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Joern 4.x, joern.io 2026).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — CPG/CPGQL 기반 SAST 패턴 정리 |
|
||||
@@ -0,0 +1,216 @@
|
||||
---
|
||||
id: wiki-2026-0508-logging-and-error-handling
|
||||
title: Logging and Error Handling
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Structured Logging, Observability Logging]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [observability, logging, error-handling]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript/Go
|
||||
framework: OpenTelemetry/pino/zap
|
||||
---
|
||||
|
||||
# Logging and Error Handling
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 logs 는 events, errors 는 values"**. 매 modern stack (2026) 의 structured JSON logging + correlation IDs + OpenTelemetry trace propagation 의 default. Errors 는 typed values (Result/Either) 의 throw 보다 explicit propagation 의 prefer.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Logging levels
|
||||
- **TRACE**: extreme detail, dev only.
|
||||
- **DEBUG**: variables, branch decisions.
|
||||
- **INFO**: lifecycle events (request start/end, job success).
|
||||
- **WARN**: degraded but recoverable (retry, fallback).
|
||||
- **ERROR**: failed operation, attention needed.
|
||||
- **FATAL**: process-terminating.
|
||||
|
||||
### 매 Structured logging
|
||||
- 매 string concatenation 의 X — JSON object emit.
|
||||
- 매 stable field names (`user_id`, `request_id`, `trace_id`).
|
||||
- 매 PII redaction at serialization (never log passwords, tokens).
|
||||
- 매 sampling (1% INFO in hot path) for cost control.
|
||||
|
||||
### 매 Error handling philosophies
|
||||
- **Exceptions**: Java, Python, Ruby. Easy default, but invisible control flow.
|
||||
- **Return values**: Go (`err`), Rust (`Result<T, E>`). Explicit, ugly.
|
||||
- **Effect systems**: Effect-TS, ZIO. Typed effects, composable.
|
||||
- **Panics**: Rust/Go for unrecoverable bugs.
|
||||
|
||||
### 매 응용
|
||||
1. SRE postmortems (logs as evidence).
|
||||
2. Distributed tracing (correlation across services).
|
||||
3. Audit trails (compliance — SOC 2, GDPR).
|
||||
4. Anomaly detection feeds.
|
||||
5. Customer support debugging.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Structured logging (TypeScript with pino)
|
||||
```typescript
|
||||
import pino from 'pino';
|
||||
|
||||
const logger = pino({
|
||||
level: process.env.LOG_LEVEL ?? 'info',
|
||||
redact: ['*.password', '*.token', 'req.headers.authorization'],
|
||||
formatters: {
|
||||
level: (label) => ({ level: label }),
|
||||
},
|
||||
});
|
||||
|
||||
logger.info(
|
||||
{ user_id: 123, request_id: req.id, latency_ms: 45 },
|
||||
'request handled',
|
||||
);
|
||||
```
|
||||
|
||||
### Trace correlation (OpenTelemetry)
|
||||
```typescript
|
||||
import { trace, context } from '@opentelemetry/api';
|
||||
|
||||
function handler(req, res) {
|
||||
const span = trace.getActiveSpan();
|
||||
const traceId = span?.spanContext().traceId;
|
||||
|
||||
logger.info({ trace_id: traceId, request_id: req.id }, 'received');
|
||||
|
||||
// child operation auto-inherits trace_id
|
||||
context.with(trace.setSpan(context.active(), span!), () => {
|
||||
processRequest(req);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Result type (Rust-style in TypeScript)
|
||||
```typescript
|
||||
type Ok<T> = { ok: true; value: T };
|
||||
type Err<E> = { ok: false; error: E };
|
||||
type Result<T, E> = Ok<T> | Err<E>;
|
||||
|
||||
async function fetchUser(id: string): Promise<Result<User, 'NotFound' | 'NetworkError'>> {
|
||||
try {
|
||||
const r = await fetch(`/users/${id}`);
|
||||
if (r.status === 404) return { ok: false, error: 'NotFound' };
|
||||
if (!r.ok) return { ok: false, error: 'NetworkError' };
|
||||
return { ok: true, value: await r.json() };
|
||||
} catch {
|
||||
return { ok: false, error: 'NetworkError' };
|
||||
}
|
||||
}
|
||||
|
||||
// Caller forced to handle both branches
|
||||
const r = await fetchUser('42');
|
||||
if (!r.ok) {
|
||||
if (r.error === 'NotFound') return res.status(404).end();
|
||||
return res.status(503).end();
|
||||
}
|
||||
```
|
||||
|
||||
### Error boundaries (React/preact)
|
||||
```tsx
|
||||
class ErrorBoundary extends Component {
|
||||
componentDidCatch(error: Error, info: ErrorInfo) {
|
||||
logger.error({ error: error.message, stack: error.stack, ...info }, 'render error');
|
||||
Sentry.captureException(error, { extra: info });
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) return <Fallback />;
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Go error wrapping
|
||||
```go
|
||||
import "fmt"
|
||||
|
||||
func fetchOrder(id string) (*Order, error) {
|
||||
raw, err := db.Query(id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetchOrder %s: %w", id, err)
|
||||
}
|
||||
return parseOrder(raw)
|
||||
}
|
||||
|
||||
// Caller can unwrap
|
||||
if errors.Is(err, sql.ErrNoRows) { /* ... */ }
|
||||
```
|
||||
|
||||
### Error budgets and alerting
|
||||
```typescript
|
||||
// Log every error, but only alert on rate
|
||||
const errorRate = new Counter({
|
||||
name: 'http_errors_total',
|
||||
labelNames: ['route', 'code'],
|
||||
});
|
||||
|
||||
app.use((err, req, res, next) => {
|
||||
errorRate.inc({ route: req.route?.path, code: err.code });
|
||||
logger.error({ err, req_id: req.id }, 'unhandled');
|
||||
res.status(500).json({ error: 'internal' });
|
||||
});
|
||||
// Prometheus rule: rate(http_errors_total[5m]) > 0.01 → page
|
||||
```
|
||||
|
||||
### Sampling for high-volume logs
|
||||
```typescript
|
||||
const sampledLogger = logger.child({}, {
|
||||
level: 'info',
|
||||
// 1% of info logs, 100% of warn+
|
||||
hooks: {
|
||||
logMethod(args, method, level) {
|
||||
if (level === 30 && Math.random() > 0.01) return;
|
||||
method.apply(this, args);
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Web service errors | Result types or wrapped exceptions |
|
||||
| Critical assertion failure | Panic/process exit |
|
||||
| Expected user input failure | Domain error type, never exception |
|
||||
| Cross-service correlation | OpenTelemetry trace_id |
|
||||
| PII in logs | Redact at serializer + DLP scan |
|
||||
| Log retention | Hot 7d / warm 30d / cold 1y |
|
||||
|
||||
**기본값**: structured JSON + OTel trace IDs + Result types for domain logic + Sentry for unhandled.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Observability]] · [[SRE]]
|
||||
- 변형: [[Distributed Tracing]] · [[Type-safe Error Handling Exhaustiveness Checking]]
|
||||
- 응용: [[Engineering Metrics (DORA)]] · [[Anomaly-Detection]]
|
||||
- Adjacent: [[Flame_Graphs]] · [[경고 피로 (Alert Fatigue)]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: generate structured log statements with consistent fields, refactor exception-throws to Result types.
|
||||
**언제 X**: never ask LLM to invent error taxonomy from scratch — derive from product domain.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **`console.log` in prod**: no levels, no structure.
|
||||
- **Catch and swallow**: `try { } catch { }` — invisible failure.
|
||||
- **Generic exceptions**: `throw new Error("oops")` — caller can't discriminate.
|
||||
- **PII in logs**: passwords, full credit card, JWT bodies.
|
||||
- **Log spam**: per-iteration debug logs in tight loops.
|
||||
- **Stringly-typed errors**: `if (err.message === "not found")` — fragile.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (OpenTelemetry spec, Google SRE book ch.16, Effect-TS docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — structured logging + Result patterns |
|
||||
@@ -0,0 +1,134 @@
|
||||
---
|
||||
id: wiki-2026-0508-major-gc
|
||||
title: Major GC
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [full-gc, old-generation-gc, mark-sweep-compact]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [gc, v8, memory, performance, jvm]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: JavaScript
|
||||
framework: V8
|
||||
---
|
||||
|
||||
# Major GC
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 Old generation 매 전체를 매 sweep 하는 매 비싼 GC cycle — 매 mark-sweep-compact 의 합성"**. 매 minor GC (Scavenge)와 대비되는 V8 의 second-tier collector — 매 long-lived object 의 final destination — 매 stop-the-world pause 의 가장 큰 원인.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 단계
|
||||
1. **Mark**: 매 root → reachable object tree-walk, mark bit set.
|
||||
2. **Sweep**: 매 unmarked region 의 free list 추가.
|
||||
3. **Compact**: 매 fragmentation 의 reduce 매 live object 매 좌측 이동.
|
||||
|
||||
### 매 trigger
|
||||
- 매 old-space 매 limit 도달.
|
||||
- 매 minor GC 매 promotion 매 spike.
|
||||
- 매 manual `--expose-gc` + `gc()` 호출.
|
||||
|
||||
### 매 응용
|
||||
1. 매 long-running Node.js server 매 latency 의 source.
|
||||
2. 매 GC tuning 의 핵심 metric.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 매 GC log enable
|
||||
```bash
|
||||
node --trace-gc app.js
|
||||
# 매 sample
|
||||
# [12345:0x...] [Mark-Compact 250.4MB->180.2MB (300.0MB) 45.3 ms]
|
||||
```
|
||||
|
||||
### 매 PerformanceObserver
|
||||
```javascript
|
||||
const obs = new PerformanceObserver((list) => {
|
||||
for (const entry of list.getEntries()) {
|
||||
if (entry.detail.kind === 4) // 매 major GC
|
||||
console.log('Major GC:', entry.duration, 'ms');
|
||||
}
|
||||
});
|
||||
obs.observe({ entryTypes: ['gc'] });
|
||||
```
|
||||
|
||||
### 매 heap snapshot
|
||||
```javascript
|
||||
const v8 = require('v8');
|
||||
v8.writeHeapSnapshot('/tmp/snap.heapsnapshot');
|
||||
// 매 Chrome DevTools → Memory tab 매 load
|
||||
```
|
||||
|
||||
### 매 incremental marking
|
||||
```bash
|
||||
node --trace-incremental-marking app.js
|
||||
# 매 V8 매 mark phase 의 매 frame budget chunk 로 분할
|
||||
```
|
||||
|
||||
### 매 max-old-space-size
|
||||
```bash
|
||||
node --max-old-space-size=4096 app.js # 매 4GB
|
||||
# 매 default 1.4GB on 64-bit
|
||||
```
|
||||
|
||||
### 매 weak ref pattern
|
||||
```javascript
|
||||
const cache = new Map();
|
||||
const ref = new WeakRef(obj);
|
||||
// 매 GC 매 obj 의 collect 매 cache 의 자동 cleanup
|
||||
const finalizer = new FinalizationRegistry((key) => cache.delete(key));
|
||||
```
|
||||
|
||||
### 매 promotion threshold tune
|
||||
```bash
|
||||
node --min-semi-space-size=64 --max-semi-space-size=128 app.js
|
||||
// 매 young gen 의 크기 의 키워서 promotion 의 줄임
|
||||
```
|
||||
|
||||
### 매 chrome devtools profile
|
||||
```javascript
|
||||
// 매 Performance tab → Record → 매 GC marker 의 yellow bar
|
||||
// 매 매 marker 매 click → reason: "allocation failure" / "external memory"
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 frequent major GC | 매 heap profile + leak hunt |
|
||||
| 매 GC pause >100ms | --max-old-space-size 의 increase |
|
||||
| 매 promotion 폭발 | --max-semi-space-size 의 increase |
|
||||
| 매 long-lived cache | WeakRef + FinalizationRegistry |
|
||||
|
||||
**기본값**: 매 trace-gc 로그로 baseline → 매 profile 후 매 tune.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[V8 가비지 컬렉션(Garbage Collection)]] · [[가비지 컬렉터(Garbage Collector)]]
|
||||
- 변형: [[Mark-Sweep-Compact(메이저 GC)]] · [[오리노코(Orinoco GC)]]
|
||||
- 응용: [[Stop-the-world]] · [[Memory Management]]
|
||||
- Adjacent: [[Scavenge]] · [[New Space(Young Generation)]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 Node.js latency spike 매 trace-gc 결과 의 해석.
|
||||
**언제 X**: 매 minor GC 의 frequent — Scavenge 분석.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **manual gc() 의 spam**: 매 incremental marking 의 방해.
|
||||
- **--expose-gc 의 prod**: 매 attacker 의 DoS vector.
|
||||
- **heap-size 의 무한 증가**: 매 swap 의 trash 매 latency 폭발.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (V8 12.x, Node.js 22+, 2026).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Major GC mark-sweep-compact 단계 + tuning 정리 |
|
||||
@@ -0,0 +1,159 @@
|
||||
---
|
||||
id: wiki-2026-0508-malware-analysis
|
||||
title: Malware Analysis
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [malware-rev, threat-analysis, reverse-engineering-malware]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, malware, reverse-engineering, threat-intel, forensics]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Python/C
|
||||
framework: Ghidra/IDA/YARA
|
||||
---
|
||||
|
||||
# Malware Analysis
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 악성 binary의 매 behavior + capability + IOC 의 추출"**. 매 static (disassembly, string, import) ↔ dynamic (sandbox, instrumentation) ↔ hybrid 의 3-tier — 매 2026 매 LLM-assisted reversing 의 confluence — 매 incident response의 bottleneck.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 3 가지 분석 mode
|
||||
1. **Static**: 매 비실행 — strings, PE header, import table, YARA, signature.
|
||||
2. **Dynamic**: 매 sandbox 실행 — API calls, network, file mod, registry.
|
||||
3. **Hybrid**: 매 static 으로 매 hint 추출 → dynamic 으로 매 path 매 trigger.
|
||||
|
||||
### 매 IOC types
|
||||
- **File**: SHA256, imphash.
|
||||
- **Network**: domain, IP, URL, JA3 fingerprint.
|
||||
- **Host**: registry key, mutex, persistence path.
|
||||
- **Behavior**: MITRE ATT&CK technique.
|
||||
|
||||
### 매 응용
|
||||
1. 매 SOC incident triage.
|
||||
2. 매 threat intel feed 의 enrichment.
|
||||
3. 매 detection rule (YARA, Sigma) 의 author.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 매 file triage
|
||||
```bash
|
||||
file suspicious.bin
|
||||
sha256sum suspicious.bin
|
||||
strings -n 8 suspicious.bin | head -50
|
||||
exiftool suspicious.bin
|
||||
```
|
||||
|
||||
### 매 PE inspect
|
||||
```bash
|
||||
pefile-info suspicious.exe # python pefile
|
||||
# 매 imphash 매 family clustering
|
||||
python -c "import pefile; print(pefile.PE('m.exe').get_imphash())"
|
||||
```
|
||||
|
||||
### 매 YARA rule
|
||||
```yara
|
||||
rule SuspiciousLoader {
|
||||
meta:
|
||||
author = "analyst"
|
||||
date = "2026-05-10"
|
||||
strings:
|
||||
$s1 = "VirtualAlloc" ascii
|
||||
$s2 = "WriteProcessMemory" ascii
|
||||
$s3 = { 48 8B ?? ?? E8 ?? ?? ?? ?? 48 85 C0 74 }
|
||||
condition:
|
||||
uint16(0) == 0x5A4D and 2 of ($s*)
|
||||
}
|
||||
// scan: yara -r rules.yar samples/
|
||||
```
|
||||
|
||||
### 매 Ghidra script (headless)
|
||||
```bash
|
||||
analyzeHeadless /tmp/proj proj1 -import sample.exe \
|
||||
-postScript ExtractStrings.java -deleteProject
|
||||
```
|
||||
|
||||
### 매 sandbox (CAPE / Cuckoo)
|
||||
```bash
|
||||
cape submit suspicious.exe --timeout 120 --options "procmemdump=yes"
|
||||
# 매 result: API trace, network pcap, dropped files
|
||||
```
|
||||
|
||||
### 매 IDA Python
|
||||
```python
|
||||
import idautils, idaapi
|
||||
for func in idautils.Functions():
|
||||
name = idaapi.get_name(func)
|
||||
if 'crypt' in name.lower():
|
||||
print(hex(func), name)
|
||||
```
|
||||
|
||||
### 매 unpacking heuristic
|
||||
```python
|
||||
# 매 entropy >7.0 매 packed 의 강한 signal
|
||||
import math, collections
|
||||
def entropy(data):
|
||||
cnt = collections.Counter(data)
|
||||
total = len(data)
|
||||
return -sum((c/total) * math.log2(c/total) for c in cnt.values())
|
||||
```
|
||||
|
||||
### 매 LLM-assisted (Claude Opus 4.7)
|
||||
```python
|
||||
# 매 disassembly chunk 의 의미 의 explain
|
||||
prompt = f"Analyze this x86_64 function and identify behavior:\n{disasm}"
|
||||
# 매 Ghidra plugin → MCP → Claude API 매 round-trip
|
||||
```
|
||||
|
||||
### 매 MITRE ATT&CK mapping
|
||||
```yaml
|
||||
behaviors:
|
||||
- tactic: Defense Evasion
|
||||
technique: T1055 # Process Injection
|
||||
evidence: VirtualAllocEx + WriteProcessMemory + CreateRemoteThread
|
||||
- tactic: Persistence
|
||||
technique: T1547.001 # Registry Run Keys
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 known-bad triage | hash/imphash lookup |
|
||||
| 매 unknown sample | static + sandbox 병행 |
|
||||
| 매 packed | unpack + dump 후 static |
|
||||
| 매 APT custom | 매 hybrid + LLM-assisted reversing |
|
||||
|
||||
**기본값**: 매 imphash + YARA 의 quick pass → 매 sandbox detonate → 매 manual reverse.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Security]]
|
||||
- 변형: [[Static Analysis]]
|
||||
- 응용: [[Anomaly-Detection]]
|
||||
- Adjacent: [[SAST]] · [[Code Obfuscation]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 disassembly 의 의미 해석, 매 obfuscated string 의 deobfuscation.
|
||||
**언제 X**: 매 IOC extraction 의 numeric — 매 deterministic tooling 사용.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **production 매 sandbox**: 매 lateral movement 의 위험.
|
||||
- **YARA rule 매 too generic**: 매 false positive 폭발.
|
||||
- **strings only**: 매 packed 매 useless.
|
||||
- **LLM 답 의 blind trust**: 매 hallucinated API behavior 위험.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Ghidra 11.x, YARA 4.5, MITRE ATT&CK v15, 2026).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — static/dynamic/hybrid 분석 + LLM-assisted 정리 |
|
||||
@@ -0,0 +1,173 @@
|
||||
---
|
||||
id: wiki-2026-0508-media-literacy
|
||||
title: Media Literacy
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Information Literacy, Source Evaluation, Digital Literacy]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [media-literacy, information, verification, deepfake, security]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: c2pa
|
||||
---
|
||||
|
||||
# Media Literacy
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 source 의 verify, claim 의 cross-check, framing 의 detect — 매 information 의 evaluate skill"**. 매 1990s NAMLE 시작, 매 2026 LLM-generated content + deepfake + C2PA provenance + AI watermark 의 era 에 매 default skill.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Core skills (5)
|
||||
- **Access**: 매 reliable source 의 find.
|
||||
- **Analyze**: bias, framing, omission 의 detect.
|
||||
- **Evaluate**: credibility, evidence quality.
|
||||
- **Create**: ethical content production.
|
||||
- **Act**: misinformation 의 counter.
|
||||
|
||||
### 매 SIFT method (Caulfield)
|
||||
- **Stop**: 매 click 전 pause.
|
||||
- **Investigate**: source 의 background.
|
||||
- **Find**: better/original coverage.
|
||||
- **Trace**: claim 의 original context.
|
||||
|
||||
### 매 응용
|
||||
1. Deepfake detection: C2PA provenance + ML classifier.
|
||||
2. LLM output: hallucination 의 detect.
|
||||
3. News pipeline: source ranking.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### C2PA manifest verification
|
||||
```python
|
||||
# 매 image 의 provenance 의 verify
|
||||
from c2pa import Reader
|
||||
reader = Reader.from_file('photo.jpg')
|
||||
manifest = reader.json()
|
||||
print(f"Producer: {manifest['active_manifest']['claim_generator']}")
|
||||
print(f"AI generated: {manifest.get('ai_generated', False)}")
|
||||
print(f"Signature valid: {reader.validation_status()}")
|
||||
```
|
||||
|
||||
### AI watermark detection (SynthID-like)
|
||||
```python
|
||||
# 매 LLM output 매 watermark 의 detect
|
||||
import torch
|
||||
def detect_watermark(text: str, key: bytes, threshold=0.6) -> bool:
|
||||
tokens = tokenize(text)
|
||||
# green-list ratio (Kirchenbauer 2023)
|
||||
green = sum(1 for t in tokens if hash_token(t, key) % 2 == 0)
|
||||
z = (green - 0.5*len(tokens)) / (0.25*len(tokens))**0.5
|
||||
return z > threshold * 5 # 매 strict threshold
|
||||
```
|
||||
|
||||
### Reverse image search (TinEye API)
|
||||
```python
|
||||
import httpx
|
||||
def reverse_search(image_path: str, api_key: str):
|
||||
with open(image_path, 'rb') as f:
|
||||
r = httpx.post('https://api.tineye.com/rest/search/',
|
||||
files={'image_upload': f},
|
||||
auth=(api_key, ''))
|
||||
matches = r.json()['results']['matches']
|
||||
return [(m['image_url'], m['domain'], m['crawl_date']) for m in matches[:5]]
|
||||
```
|
||||
|
||||
### Source credibility score
|
||||
```python
|
||||
TRUSTED_DOMAINS = {'reuters.com': 0.95, 'apnews.com': 0.93, 'nature.com': 0.97}
|
||||
SUSPICIOUS = {'.tk', '.click'}
|
||||
|
||||
def score_source(url: str) -> float:
|
||||
from urllib.parse import urlparse
|
||||
domain = urlparse(url).netloc.lower().lstrip('www.')
|
||||
if domain in TRUSTED_DOMAINS: return TRUSTED_DOMAINS[domain]
|
||||
if any(domain.endswith(s) for s in SUSPICIOUS): return 0.1
|
||||
return 0.5 # unknown
|
||||
```
|
||||
|
||||
### Deepfake classifier (FaceForensics++)
|
||||
```python
|
||||
import torch
|
||||
from transformers import AutoModelForImageClassification, AutoImageProcessor
|
||||
|
||||
model = AutoModelForImageClassification.from_pretrained(
|
||||
'prithivMLmods/Deep-Fake-Detector-v2-Model')
|
||||
proc = AutoImageProcessor.from_pretrained('prithivMLmods/Deep-Fake-Detector-v2-Model')
|
||||
|
||||
def is_deepfake(img) -> tuple[bool, float]:
|
||||
inputs = proc(images=img, return_tensors='pt')
|
||||
with torch.no_grad():
|
||||
logits = model(**inputs).logits
|
||||
probs = logits.softmax(-1)[0]
|
||||
fake_prob = probs[1].item()
|
||||
return fake_prob > 0.5, fake_prob
|
||||
```
|
||||
|
||||
### Cross-reference fact-check
|
||||
```python
|
||||
import asyncio, httpx
|
||||
|
||||
async def fact_check(claim: str):
|
||||
async with httpx.AsyncClient() as c:
|
||||
r = await c.get('https://factchecktools.googleapis.com/v1alpha1/claims:search',
|
||||
params={'query': claim, 'key': 'KEY'})
|
||||
results = r.json().get('claims', [])
|
||||
return [(x['text'], x['claimReview'][0]['textualRating']) for x in results]
|
||||
```
|
||||
|
||||
### Browser ext: provenance badge
|
||||
```ts
|
||||
// content.ts
|
||||
async function annotateImages() {
|
||||
for (const img of document.querySelectorAll('img')) {
|
||||
const r = await fetch(`/api/c2pa-check?url=${encodeURIComponent(img.src)}`);
|
||||
const { aiGenerated, verified } = await r.json();
|
||||
if (aiGenerated) img.style.outline = '3px solid orange';
|
||||
if (!verified) img.title = '매 provenance unverified';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| News article | SIFT method |
|
||||
| Image authenticity | C2PA + reverse search + deepfake classifier |
|
||||
| LLM output | watermark detect + cross-reference |
|
||||
| Suspicious domain | credibility score < 0.3 → reject |
|
||||
|
||||
**기본값**: SIFT + tooling-augmented (C2PA, fact-check API).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Information Literacy]]
|
||||
- 변형: [[Source Evaluation]]
|
||||
- 응용: [[Deepfake-Detection]]
|
||||
- Adjacent: [[Conversational-Maxims]] · [[Procedural-Rhetoric]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: claim cross-reference, framing analysis, summary 의 bias detect.
|
||||
**언제 X**: 매 LLM 자체 매 hallucinate — 매 외부 source 와 cross-check 필수.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Headline reading**: 매 click 만 하고 article body 매 읽지 X.
|
||||
- **Single source**: corroboration 매 X.
|
||||
- **Bothsidesism**: 매 lopsided evidence 의 false equivalence.
|
||||
- **No provenance check**: image 매 viral spread 후 reverse search X.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (NAMLE Core Principles, C2PA spec 2.0, SIFT method by Mike Caulfield).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — SIFT + C2PA + deepfake tooling |
|
||||
@@ -0,0 +1,158 @@
|
||||
---
|
||||
id: wiki-2026-0508-memory-management
|
||||
title: Memory Management
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [memory-mgmt, heap-management]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [memory, gc, performance, runtime, systems]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: C/JS/Rust
|
||||
framework: V8/JVM/glibc
|
||||
---
|
||||
|
||||
# Memory Management
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 program 매 lifetime 동안 의 allocation/deallocation 의 전략"**. 매 manual (C/C++) ↔ ARC (Swift/ObjC) ↔ tracing GC (V8/JVM) ↔ ownership (Rust) — 매 spectrum 의 각 trade-off — 매 2026 의 mainstream 4 가지 paradigm 의 공존.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 4 가지 paradigm
|
||||
1. **Manual**: malloc/free, new/delete — 매 control 최대, 매 leak 위험.
|
||||
2. **Reference counting**: ARC, shared_ptr — 매 deterministic, 매 cycle 문제.
|
||||
3. **Tracing GC**: V8, JVM, .NET — 매 productivity, 매 pause.
|
||||
4. **Ownership**: Rust borrow checker — 매 zero-runtime overhead, 매 learning curve.
|
||||
|
||||
### 매 핵심 metric
|
||||
- **RSS** (resident set size): 매 OS 시점.
|
||||
- **Heap used**: 매 runtime 시점.
|
||||
- **External**: 매 native buffer (Node `Buffer`).
|
||||
- **Fragmentation**: 매 allocate 가능하지만 매 contiguous block 부재.
|
||||
|
||||
### 매 응용
|
||||
1. 매 long-running server 의 stability.
|
||||
2. 매 game engine 의 frame budget.
|
||||
3. 매 embedded 의 RAM 의 limit.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 매 manual (C)
|
||||
```c
|
||||
char *buf = malloc(1024);
|
||||
if (!buf) { perror("malloc"); exit(1); }
|
||||
// ... use ...
|
||||
free(buf);
|
||||
buf = NULL; // 매 dangling 의 방지
|
||||
```
|
||||
|
||||
### 매 RAII (C++)
|
||||
```cpp
|
||||
{
|
||||
std::unique_ptr<MyObj> p = std::make_unique<MyObj>();
|
||||
// 매 scope exit 매 자동 delete
|
||||
}
|
||||
std::shared_ptr<MyObj> sp = std::make_shared<MyObj>();
|
||||
// 매 ref-count 0 매 free
|
||||
```
|
||||
|
||||
### 매 ownership (Rust)
|
||||
```rust
|
||||
fn take(s: String) { /* 매 drop on end */ }
|
||||
let owned = String::from("hi");
|
||||
take(owned);
|
||||
// println!("{}", owned); // 매 compile error: moved
|
||||
```
|
||||
|
||||
### 매 tracing GC (JS)
|
||||
```javascript
|
||||
let cache = new Map();
|
||||
cache.set('a', { big: new Array(1e6) });
|
||||
cache = null; // 매 GC 의 next cycle 의 reclaim
|
||||
// 매 WeakMap 매 key 의 GC 자동 cleanup
|
||||
const wm = new WeakMap();
|
||||
```
|
||||
|
||||
### 매 Node memory inspect
|
||||
```javascript
|
||||
const v8 = require('v8');
|
||||
console.log(v8.getHeapStatistics());
|
||||
// { total_heap_size: ..., used_heap_size: ..., heap_size_limit: ... }
|
||||
process.memoryUsage();
|
||||
// { rss, heapTotal, heapUsed, external, arrayBuffers }
|
||||
```
|
||||
|
||||
### 매 leak detection (Node)
|
||||
```bash
|
||||
node --inspect app.js
|
||||
# Chrome DevTools → Memory → Take snapshot → 매 sample 3 개 → comparison view
|
||||
node --heapsnapshot-signal=SIGUSR2 app.js
|
||||
kill -USR2 $(pgrep node)
|
||||
```
|
||||
|
||||
### 매 pool allocator
|
||||
```cpp
|
||||
class Pool {
|
||||
std::vector<MyObj*> free_;
|
||||
public:
|
||||
MyObj* acquire() {
|
||||
if (free_.empty()) return new MyObj();
|
||||
auto* p = free_.back(); free_.pop_back(); return p;
|
||||
}
|
||||
void release(MyObj* p) { free_.push_back(p); }
|
||||
};
|
||||
// 매 hot path 매 alloc 의 amortize
|
||||
```
|
||||
|
||||
### 매 arena (Rust bumpalo)
|
||||
```rust
|
||||
use bumpalo::Bump;
|
||||
let arena = Bump::new();
|
||||
let s = arena.alloc(String::from("hi"));
|
||||
let v = arena.alloc(vec![1, 2, 3]);
|
||||
// 매 arena drop 매 모두 free — 매 deallocation O(1)
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 systems / kernel | manual + sanitizer |
|
||||
| 매 high-perf game | RAII + pool |
|
||||
| 매 server productive | tracing GC + tune |
|
||||
| 매 safety + perf | Rust ownership |
|
||||
| 매 short-lived bulk | arena |
|
||||
|
||||
**기본값**: 매 language idiom 따름 — 매 C++ RAII, 매 JS GC, 매 Rust ownership.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Performance]]
|
||||
- 변형: [[Garbage Collection]] · [[ARC]] · [[Ownership]]
|
||||
- 응용: [[V8 Engine Heap Management]] · [[Major GC]]
|
||||
- Adjacent: [[가비지 컬렉터(Garbage Collector)]] · [[힙 메모리(Heap Memory)]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 memory leak / OOM 의 hunt 매 paradigm 의 선택.
|
||||
**언제 X**: 매 high-level business logic 의 memory 의 의식 안 해도 됨.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **manual + GC mix 매 over-confidence**: 매 native buffer leak.
|
||||
- **shared_ptr cycle**: 매 weak_ptr 의 break.
|
||||
- **arena 매 long-lived**: 매 effective leak.
|
||||
- **Rust 매 unsafe 의 무분별**: 매 borrow checker 의 우회.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (V8/JVM/Rust/glibc 2026 documentation).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — 4가지 메모리 관리 paradigm 비교 + pattern 정리 |
|
||||
@@ -0,0 +1,159 @@
|
||||
---
|
||||
id: wiki-2026-0508-network-coordinate-systems
|
||||
title: Network Coordinate Systems
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [NCS, Vivaldi, network coordinates, latency embedding]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [networking, distributed-systems, latency, p2p]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Go/Rust
|
||||
framework: HashiCorp Serf, libp2p
|
||||
---
|
||||
|
||||
# Network Coordinate Systems
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 host 를 매 low-dim Euclidean space 의 점으로 embed 하여 매 RTT 를 매 distance 로 predict"**. 매 2004 MIT Vivaldi paper 가 매 seminal — 매 N×N RTT measurement 의 O(N²) 폭발 의 회피. 매 2026 service mesh / CDN edge selection / P2P overlay 의 매 building block.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 motivation
|
||||
- 매 N node 매 mesh 의 매 N² RTT probe = 매 1000 node = 1M probe.
|
||||
- 매 NCS: 매 O(N) coordinate update 로 매 any pair 의 RTT predict.
|
||||
- 매 update 매 lazy — 매 gossip / piggyback 매 existing message.
|
||||
|
||||
### 매 Vivaldi (대표 algorithm)
|
||||
- 매 spring relaxation: 매 measured RTT 와 매 predicted distance 의 error 가 매 force.
|
||||
- 매 height vector h: 매 access link latency 의 capture (Euclidean 의 X 인 매 last-mile).
|
||||
- 매 dim 5-7 차 + height 1 차: 매 internet topology 의 충분한 fit.
|
||||
|
||||
### 매 응용
|
||||
1. CDN edge selection (Cloudflare Argo).
|
||||
2. Service mesh locality routing (HashiCorp Consul).
|
||||
3. P2P overlay neighbor selection (libp2p).
|
||||
4. Cluster placement (Kubernetes topology-aware).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 1. Vivaldi update step (Go-style)
|
||||
```go
|
||||
type Coord struct {
|
||||
Vec []float64 // 8-dim
|
||||
Height float64
|
||||
Error float64 // local confidence
|
||||
}
|
||||
|
||||
const Cc, Ce = 0.25, 0.25
|
||||
|
||||
func (a *Coord) Update(b *Coord, rttSeconds float64) {
|
||||
predicted := dist(a, b)
|
||||
relErr := math.Abs(predicted-rttSeconds) / rttSeconds
|
||||
w := a.Error / (a.Error + b.Error)
|
||||
a.Error = relErr*Ce*w + a.Error*(1-Ce*w)
|
||||
|
||||
delta := Cc * w
|
||||
direction := unitVec(sub(a.Vec, b.Vec))
|
||||
force := (rttSeconds - predicted) * delta
|
||||
for i := range a.Vec {
|
||||
a.Vec[i] += direction[i] * force
|
||||
}
|
||||
a.Height = math.Max(0.001, a.Height+(rttSeconds-predicted)*delta*0.5)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Distance prediction
|
||||
```go
|
||||
func dist(a, b *Coord) float64 {
|
||||
sumSq := 0.0
|
||||
for i := range a.Vec {
|
||||
d := a.Vec[i] - b.Vec[i]
|
||||
sumSq += d * d
|
||||
}
|
||||
return math.Sqrt(sumSq) + a.Height + b.Height
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Gossip-based update (Serf-style)
|
||||
```go
|
||||
// On every gossip message exchange:
|
||||
func (s *Serf) onPing(peer Node, rtt time.Duration) {
|
||||
s.coord.Update(peer.Coord, rtt.Seconds())
|
||||
s.broadcast(s.coord)
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Edge selection (CDN)
|
||||
```go
|
||||
func nearestEdge(client *Coord, edges []Edge) Edge {
|
||||
best := edges[0]
|
||||
bestDist := dist(client, best.Coord)
|
||||
for _, e := range edges[1:] {
|
||||
if d := dist(client, e.Coord); d < bestDist {
|
||||
best, bestDist = e, d
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Confidence-weighted query
|
||||
```go
|
||||
func predictRTT(a, b *Coord) (float64, float64) {
|
||||
rtt := dist(a, b)
|
||||
confidence := 1.0 - math.Min(a.Error+b.Error, 1.0)
|
||||
return rtt, confidence
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Pharos (hierarchical NCS)
|
||||
```go
|
||||
// Two-tier: global coord + cluster-local coord
|
||||
type PharosCoord struct {
|
||||
Global Coord // inter-cluster
|
||||
Local Coord // intra-cluster
|
||||
Cluster string
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| < 50 nodes | Direct N² probe — NCS overkill |
|
||||
| 50-10k nodes (mesh) | Vivaldi (HashiCorp Serf 매 default) |
|
||||
| > 10k geo-distributed | Pharos (hierarchical) or HTRAE |
|
||||
| Adversarial / Byzantine | Newton (outlier-resistant) |
|
||||
| Edge selection only | Anycast + GeoIP 매 simpler |
|
||||
|
||||
**기본값**: Vivaldi 8-dim + height (Serf-compatible).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Distributed Systems]]
|
||||
- 응용: [[Service Mesh]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 100+ node mesh 매 latency-aware routing/placement 가 필요. 매 RTT measurement 의 O(N²) 폭발 회피.
|
||||
**언제 X**: 매 small cluster (< 50). 매 BGP anycast 매 충분한 단순 edge selection. 매 Byzantine adversary present.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Triangle inequality 의 violation 무시**: 매 internet 의 매 routing asymmetry 매 strict triangle 위반 — 매 height vector 매 partial 해결.
|
||||
- **High-dim 매 사용**: 매 16+ dim 매 overfitting + 매 update cost 증가. 매 8 dim 매 sweet spot.
|
||||
- **Cold start 매 0 vector**: 매 random init 매 collapse 회피.
|
||||
- **Confidence 무시**: 매 fresh node 의 coord 매 unreliable — 매 Error field 매 weight 사용.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Vivaldi: Dabek et al., SIGCOMM 2004; HashiCorp Serf source 2026-05).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Vivaldi spring-relaxation + Serf 의 production usage |
|
||||
@@ -0,0 +1,168 @@
|
||||
---
|
||||
id: wiki-2026-0508-new-space-young-generation
|
||||
title: New Space (Young Generation)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Young Generation, Eden + Survivor, Scavenger, Minor GC, Nursery]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [gc, v8, jvm, generational-gc, memory-management]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: C++
|
||||
framework: V8, HotSpot JVM, .NET
|
||||
---
|
||||
|
||||
# New Space (Young Generation)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 generational GC 의 short-lived object region"**. 매 1984 Lieberman & Hewitt 의 매 generational hypothesis ("most objects die young") 매 base. 매 V8 의 New Space (Scavenger), 매 JVM 의 Young Gen (Eden + 2 Survivor), 매 .NET 의 Gen 0/1 — 매 모두 매 동일한 idea: 매 young object 매 cheap copy + 매 old object 매 promote.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 generational hypothesis
|
||||
- 매 90%+ object 매 매 first GC cycle 의 die.
|
||||
- 매 survivor 매 long-lived 가능 매 high.
|
||||
- 매 separate region + 매 separate algorithm 매 efficient.
|
||||
|
||||
### 매 V8 New Space 구조
|
||||
- 매 to-space + from-space (semispace).
|
||||
- 매 Cheney's Scavenge (Cheney 1970) — 매 BFS copy.
|
||||
- 매 size 매 1-8MB per isolate (V8 12+ adaptive).
|
||||
- 매 minor GC: 매 < 1ms typical.
|
||||
- 매 promotion: 매 2회 survive 시 Old Space 로 이동.
|
||||
|
||||
### 매 JVM Young Gen 구조
|
||||
- 매 Eden (allocation site) + Survivor 0 + Survivor 1.
|
||||
- 매 Eden full → 매 minor GC → 매 live → S0 (or S1).
|
||||
- 매 매 매 Tenuring threshold (default 15) 도달 → Old Gen.
|
||||
|
||||
### 매 응용
|
||||
1. JS engine (V8 / SpiderMonkey / JavaScriptCore).
|
||||
2. JVM (HotSpot G1, ZGC, Parallel).
|
||||
3. .NET CLR.
|
||||
4. Dart VM.
|
||||
5. Lua의 incremental (slightly different).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 1. V8 heap snapshot 측정
|
||||
```ts
|
||||
import v8 from 'node:v8';
|
||||
|
||||
const stats = v8.getHeapSpaceStatistics();
|
||||
const newSpace = stats.find(s => s.space_name === 'new_space');
|
||||
console.log({
|
||||
size: newSpace.space_size,
|
||||
used: newSpace.space_used_size,
|
||||
available: newSpace.space_available_size,
|
||||
});
|
||||
```
|
||||
|
||||
### 2. V8 GC trace flag
|
||||
```bash
|
||||
node --trace-gc app.js
|
||||
# [12345:0x1234] 234 ms: Scavenge 4.5 (5.3) -> 0.8 (5.3) MB, 1.2 ms
|
||||
node --trace-gc-verbose --max-semi-space-size=64 app.js
|
||||
```
|
||||
|
||||
### 3. Allocation site 의 promotion 회피
|
||||
```ts
|
||||
// 매 hot loop 의 ephemeral 의 ㅇ
|
||||
function processStream(items: Item[]) {
|
||||
for (const item of items) {
|
||||
const tmp = { x: item.x * 2, y: item.y * 2 }; // 매 New Space alloc
|
||||
emit(tmp); // 매 die immediately — minor GC 의 reclaim
|
||||
}
|
||||
}
|
||||
|
||||
// 매 X — 매 long-lived array 의 promotion
|
||||
const cache: Record<string, Result> = {};
|
||||
function bad(item: Item) {
|
||||
cache[item.id] = compute(item); // 매 Old Space promotion
|
||||
}
|
||||
```
|
||||
|
||||
### 4. JVM Young Gen tuning
|
||||
```bash
|
||||
java -Xms2g -Xmx8g \
|
||||
-XX:NewRatio=2 \
|
||||
-XX:SurvivorRatio=8 \
|
||||
-XX:MaxTenuringThreshold=10 \
|
||||
-XX:+UseG1GC \
|
||||
-Xlog:gc*:file=gc.log \
|
||||
App
|
||||
```
|
||||
|
||||
### 5. Pretenuring (object 의 사전 Old 배치)
|
||||
```cpp
|
||||
// V8 internal: AllocationSite 가 매 history 추적 → 매 large/long-lived 매 immediate Old.
|
||||
// 매 user-facing API X — 매 V8 의 implicit.
|
||||
// 매 application 의 hint: 매 reuse object pool.
|
||||
```
|
||||
|
||||
### 6. Object pool (allocation pressure 회피)
|
||||
```ts
|
||||
class Vec3Pool {
|
||||
private pool: Vec3[] = [];
|
||||
acquire(): Vec3 {
|
||||
return this.pool.pop() ?? new Vec3();
|
||||
}
|
||||
release(v: Vec3) {
|
||||
v.set(0, 0, 0);
|
||||
if (this.pool.length < 1000) this.pool.push(v);
|
||||
}
|
||||
}
|
||||
// 매 매 frame 의 allocation 의 X → minor GC 매 silent
|
||||
```
|
||||
|
||||
### 7. .NET Gen 0 stats
|
||||
```csharp
|
||||
GC.Collect(0); // 매 Gen 0 (Young) 매 only
|
||||
Console.WriteLine($"Gen0: {GC.CollectionCount(0)}");
|
||||
Console.WriteLine($"Gen1: {GC.CollectionCount(1)}");
|
||||
Console.WriteLine($"Gen2: {GC.CollectionCount(2)}");
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | New Space tuning |
|
||||
|---|---|
|
||||
| Allocation-heavy (web server) | 매 large New Space (V8 64-256MB) — 매 Scavenge frequency 줄임 |
|
||||
| Long-lived state (cache) | 매 small New Space — 매 promote fast |
|
||||
| Latency-critical (game) | 매 object pool + 매 zero-alloc hot path |
|
||||
| Memory-tight (mobile) | 매 default + GC tuning 의 X |
|
||||
| Long debugging session | --trace-gc + heap snapshot |
|
||||
|
||||
**기본값**: 매 V8 default New Space + 매 hot path 의 object pool 사용.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Garbage Collection]]
|
||||
- 변형: [[Old_Space|Old Space]] · [[Mark-Sweep-Compact]]
|
||||
- 응용: [[V8 GC]]
|
||||
- Adjacent: [[Cheney's Algorithm]] · [[Object Pool]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 GC pause 매 SLO 위협. 매 allocation profiling 매 hot path 식별. 매 V8 / JVM heap behavior 의 understanding.
|
||||
**언제 X**: 매 Rust / C++ (no GC). 매 small script (default 면 충분). 매 micro-optimization 의 매 measurement 의 X.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 frame 의 새 closure**: 매 frame 마다 매 object alloc → 매 Scavenge 폭발.
|
||||
- **Long-lived array 의 매 push/splice**: 매 internal buffer 의 New Space alloc → promote.
|
||||
- **TypedArray 의 매 매 new 만들기**: 매 reuse — 매 Float32Array 매 large allocation.
|
||||
- **매 GC 의 force (`global.gc()`)**: 매 production 의 X — 매 V8 heuristic 의 disrupt.
|
||||
- **매 NewRatio 매 production 의 변경 의 측정 없이**: 매 application-specific tuning — default 매 first.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (V8 design docs 2026-05, OpenJDK HotSpot source, Cheney 1970 paper).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Cheney scavenge + V8/JVM/.NET cross-platform comparison |
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
---
|
||||
id: wiki-2026-0508-notebooklm-automated-authenticat
|
||||
title: NotebookLM Automated Authentication CLI
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [notebooklm-cli, notebooklm-auto-auth]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.85
|
||||
verification_status: applied
|
||||
tags: [automation, oauth, cli, notebooklm, google]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Python/Node
|
||||
framework: Playwright/OAuth2
|
||||
---
|
||||
|
||||
# NotebookLM Automated Authentication CLI
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 NotebookLM 의 official API 부재 시 의 매 browser-automation 기반 인증 우회"**. 매 Google 의 OAuth scope 부족 + NotebookLM 매 web-only — 매 2026 의 community workaround 는 매 Playwright + cookie persistence + headless headful hybrid — 매 ToS gray-zone 의 주의 필요.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 official 한계 (2026)
|
||||
- 매 NotebookLM API 매 not GA — 매 Workspace partner 매 limited preview 만.
|
||||
- 매 OAuth scope 매 notebooklm 부재.
|
||||
- 매 Apps Script 매 access 매 X.
|
||||
|
||||
### 매 community workaround
|
||||
1. 매 Playwright headful 매 첫 login → 매 cookie/storage_state save.
|
||||
2. 매 subsequent run 매 headless + saved state.
|
||||
3. 매 challenge / 2FA 매 hybrid (headful trigger when needed).
|
||||
|
||||
### 매 응용
|
||||
1. 매 daily research digest 자동 ingest.
|
||||
2. 매 source library 의 batch upload.
|
||||
3. 매 podcast generation 의 schedule.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 매 first login + save state
|
||||
```python
|
||||
# auth_init.py — 매 1회 실행, 사용자 매 직접 login
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=False)
|
||||
ctx = browser.new_context()
|
||||
page = ctx.new_page()
|
||||
page.goto("https://notebooklm.google.com/")
|
||||
print("Sign in manually, then press Enter…")
|
||||
input()
|
||||
ctx.storage_state(path="state.json")
|
||||
browser.close()
|
||||
```
|
||||
|
||||
### 매 reuse session
|
||||
```python
|
||||
# run.py
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
ctx = browser.new_context(storage_state="state.json")
|
||||
page = ctx.new_page()
|
||||
page.goto("https://notebooklm.google.com/")
|
||||
page.wait_for_selector("text=Notebooks", timeout=15_000)
|
||||
# … perform actions …
|
||||
ctx.storage_state(path="state.json") # 매 refresh saved state
|
||||
browser.close()
|
||||
```
|
||||
|
||||
### 매 challenge fallback
|
||||
```python
|
||||
def goto_with_fallback(url, state_path="state.json"):
|
||||
try:
|
||||
ctx = browser.new_context(storage_state=state_path)
|
||||
page = ctx.new_page(); page.goto(url)
|
||||
page.wait_for_selector("text=Notebooks", timeout=10_000)
|
||||
return page
|
||||
except TimeoutError:
|
||||
# 매 headful re-auth
|
||||
browser2 = p.chromium.launch(headless=False)
|
||||
ctx2 = browser2.new_context(storage_state=state_path)
|
||||
page2 = ctx2.new_page(); page2.goto(url)
|
||||
input("Resolve challenge, Enter…")
|
||||
ctx2.storage_state(path=state_path)
|
||||
return None
|
||||
```
|
||||
|
||||
### 매 cookie expiry monitor
|
||||
```python
|
||||
import json, time
|
||||
state = json.load(open("state.json"))
|
||||
for c in state["cookies"]:
|
||||
if c.get("expires", 0) and c["expires"] < time.time() + 86400:
|
||||
print(f"WARN: {c['name']} expires soon")
|
||||
```
|
||||
|
||||
### 매 cron job
|
||||
```cron
|
||||
# 매 every 6h refresh
|
||||
0 */6 * * * cd /opt/nlm && /usr/bin/python3 run.py >> log 2>&1
|
||||
```
|
||||
|
||||
### 매 docker secrets
|
||||
```dockerfile
|
||||
FROM mcr.microsoft.com/playwright/python:v1.45-jammy
|
||||
WORKDIR /app
|
||||
COPY *.py ./
|
||||
# state.json 매 mount 의 secret
|
||||
CMD ["python", "run.py"]
|
||||
```
|
||||
|
||||
```bash
|
||||
docker run --rm -v $(pwd)/state.json:/app/state.json:rw nlm-bot
|
||||
```
|
||||
|
||||
### 매 multi-account
|
||||
```python
|
||||
ACCOUNTS = ["work", "personal"]
|
||||
for acc in ACCOUNTS:
|
||||
ctx = browser.new_context(storage_state=f"state-{acc}.json")
|
||||
# ...
|
||||
```
|
||||
|
||||
### 매 audit log
|
||||
```python
|
||||
import logging
|
||||
logging.basicConfig(filename="audit.log", level=logging.INFO,
|
||||
format="%(asctime)s %(message)s")
|
||||
logging.info(f"login session reused, action={action}")
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 daily small batch | Playwright + state.json |
|
||||
| 매 enterprise scale | Workspace API preview 의 신청 |
|
||||
| 매 ToS-strict org | 매 official API 만 — automation 회피 |
|
||||
| 매 2FA 매 strict | hybrid headful fallback |
|
||||
|
||||
**기본값**: 매 personal use — Playwright state-file pattern. 매 enterprise — official API 신청 + 대기.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[OAuth]]
|
||||
- Adjacent: [[Secret_Management]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 NotebookLM-driven research pipeline 의 자동화.
|
||||
**언제 X**: 매 ToS 위반 우려 시 — 매 Workspace partner channel 사용.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **state.json 매 git commit**: 매 session 의 leak.
|
||||
- **2FA 매 bypass attempt**: 매 ToS violation + account ban.
|
||||
- **headless 매 only**: 매 challenge 매 silent fail.
|
||||
- **expiry 무시**: 매 cron 매 silent broken.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Playwright 1.45+, NotebookLM 2026 web behavior).
|
||||
- 신뢰도 A-.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Playwright 기반 NotebookLM 인증 자동화 패턴 |
|
||||
@@ -0,0 +1,153 @@
|
||||
---
|
||||
id: wiki-2026-0508-oilpan
|
||||
title: Oilpan
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Blink GC, cppgc, Oilpan GC]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [gc, c++, blink, chromium, memory-management]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: C++
|
||||
framework: Blink/Chromium, cppgc (V8)
|
||||
---
|
||||
|
||||
# Oilpan
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 C++ object 매 trace-based GC"**. 매 2014 Blink (Chromium renderer) 의 DOM tree memory bug 해결 위해 도입 된 매 C++ GC. 매 2021 V8 의 매 cppgc 로 generalize 되어 매 Node.js native module / Dart VM 의 사용. 매 raw pointer 의 cycle leak 매 fundamental 해결.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 motivation
|
||||
- 매 DOM tree 매 cyclic reference (parent ↔ child) 매 매우 흔함.
|
||||
- 매 RefCounted (smart pointer) 의 cycle 매 leak.
|
||||
- 매 manual `delete` 매 use-after-free / double-free 폭발.
|
||||
- 매 Blink 매 2010-2014 매 매 brutal memory bug 매 routine.
|
||||
|
||||
### 매 Oilpan 동작
|
||||
- 매 `GarbageCollected<T>` base class 매 inherit → 매 GC 의 manage.
|
||||
- 매 `Member<T>` smart pointer 매 GC-tracked field 매 declare.
|
||||
- 매 `Trace(Visitor*)` virtual method 매 reachability 의 manual report.
|
||||
- 매 incremental marking + concurrent sweeping → 매 main thread pause < 1ms.
|
||||
|
||||
### 매 응용
|
||||
1. Blink DOM (Element, Node, Document) 매 모든 lifecycle.
|
||||
2. V8 cppgc 매 사용 한 매 Node.js native addon.
|
||||
3. Dart VM heap.
|
||||
4. Skia paint object graph (experimental).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 1. Garbage-collected class
|
||||
```cpp
|
||||
#include "v8/cppgc/garbage-collected.h"
|
||||
#include "v8/cppgc/member.h"
|
||||
|
||||
class Node : public cppgc::GarbageCollected<Node> {
|
||||
public:
|
||||
void Trace(cppgc::Visitor* visitor) const {
|
||||
visitor->Trace(parent_);
|
||||
visitor->Trace(children_);
|
||||
}
|
||||
|
||||
private:
|
||||
cppgc::Member<Node> parent_;
|
||||
cppgc::HeapVector<cppgc::Member<Node>> children_;
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Allocation
|
||||
```cpp
|
||||
auto* node = cppgc::MakeGarbageCollected<Node>(heap.GetAllocationHandle());
|
||||
// 매 delete 의 X — GC 가 reclaim
|
||||
```
|
||||
|
||||
### 3. Persistent (off-heap reference)
|
||||
```cpp
|
||||
class NonGcOwner {
|
||||
cppgc::Persistent<Node> root_; // 매 strong root
|
||||
cppgc::WeakPersistent<Node> observer_; // 매 weak (clear 시 nullptr)
|
||||
};
|
||||
```
|
||||
|
||||
### 4. Pre-finalizer (cleanup hook)
|
||||
```cpp
|
||||
class Resource : public cppgc::GarbageCollected<Resource> {
|
||||
USING_PRE_FINALIZER(Resource, Dispose);
|
||||
void Dispose() {
|
||||
// 매 GC 직전 호출 — 매 file handle close 등
|
||||
if (fd_ >= 0) close(fd_);
|
||||
}
|
||||
void Trace(cppgc::Visitor*) const {}
|
||||
private:
|
||||
int fd_ = -1;
|
||||
};
|
||||
```
|
||||
|
||||
### 5. Cross-thread safety
|
||||
```cpp
|
||||
// 매 GC heap 매 single thread (renderer main).
|
||||
// 매 worker → main thread post 매 cppgc::CrossThreadPersistent.
|
||||
cppgc::CrossThreadPersistent<Node> handle(node);
|
||||
PostTaskToMain([handle]() {
|
||||
handle->DoSomething();
|
||||
});
|
||||
```
|
||||
|
||||
### 6. Heap stats (debugging)
|
||||
```cpp
|
||||
auto stats = heap.CollectStatistics(cppgc::HeapStatistics::DetailLevel::kDetailed);
|
||||
LOG(INFO) << "Resident: " << stats.resident_size_bytes
|
||||
<< " Used: " << stats.used_size_bytes;
|
||||
```
|
||||
|
||||
### 7. Force GC (test only)
|
||||
```cpp
|
||||
heap.ForceGarbageCollectionSlow(
|
||||
"test", "explicit",
|
||||
cppgc::Heap::StackState::kNoHeapPointers);
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Acyclic ownership | `unique_ptr` / `shared_ptr` (no GC needed) |
|
||||
| Cyclic graph (DOM-like) | Oilpan / cppgc |
|
||||
| Latency-critical realtime | Avoid — GC pause unpredictable |
|
||||
| Cross-language boundary (V8) | cppgc 매 V8 와 매 unified heap |
|
||||
| Embedded / no V8 | Standalone cppgc library |
|
||||
|
||||
**기본값**: 매 cycle 가능 한 graph 에서만 Oilpan. 매 simple ownership 매 RAII.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Garbage Collection]] · [[Tracing GC]]
|
||||
- 변형: [[V8 GC]] · [[Mark-Sweep-Compact]]
|
||||
- Adjacent: [[Tri-color Marking]] · [[Reference Counting]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 C++ project 에서 매 cyclic object graph 매 unavoidable. 매 V8 embedder 매 native object 와 JS object 의 unified GC.
|
||||
**언제 X**: 매 simple resource ownership (RAII 매 충분). 매 hard real-time. 매 embedded (memory budget tight).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Raw pointer 매 GC heap object 매 hold**: 매 GC 가 collect → use-after-free. 매 항상 Member/Persistent.
|
||||
- **Trace 매 incomplete**: 매 missed field 매 premature collection. 매 Clang plugin 매 lint check 활용.
|
||||
- **Pre-finalizer 매 heavy work**: 매 GC 의 pause 증가. 매 light cleanup 만.
|
||||
- **Cross-thread 매 raw Member**: 매 data race + 매 GC 의 oblivious. 매 CrossThreadPersistent 사용.
|
||||
- **Stack 의 conservative scan 의 abuse**: 매 false retention. 매 kNoHeapPointers state 매 가능 한 사용.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (V8 cppgc docs, Blink rendering core 2026-05, Dart VM source).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Oilpan/cppgc unified heap + Member/Persistent pattern |
|
||||
@@ -0,0 +1,179 @@
|
||||
---
|
||||
id: wiki-2026-0508-pdf-format
|
||||
title: PDF Format
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Portable Document Format, ISO 32000, PDF/A]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [pdf, document, format, parsing, generation]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: pypdf
|
||||
---
|
||||
|
||||
# PDF Format
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 cross-reference table 의 random-access 의 binary container"**. 매 Adobe (1993) 의 PostScript-derived 의 ISO 32000 의 standardize 의 page-fixed-layout 의 dominant interchange format. 매 2026 년 의 PDF/A-4 (archival) + PDF 2.0 의 modern variant 의 LLM-extraction 의 challenge 의 source (no semantic structure 의 guarantee).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 file 구조
|
||||
1. **Header** — `%PDF-2.0` (또는 1.x).
|
||||
2. **Body** — sequence of indirect objects (`N G obj ... endobj`).
|
||||
3. **Cross-reference table** (`xref`) — byte offset of each object.
|
||||
4. **Trailer** — root + info + size + xref offset.
|
||||
|
||||
### 매 object types
|
||||
- Boolean, Number, String (literal `()` or hex `<>`), Name (`/Name`), Array, Dictionary, Stream (filtered binary).
|
||||
- Page tree (Catalog → Pages → Page) + Resources (Font, XObject, etc.).
|
||||
|
||||
### 매 응용
|
||||
1. Text/table extraction (LLM 의 RAG ingest).
|
||||
2. Form fill (AcroForm / XFA).
|
||||
3. Digital signature (PAdES).
|
||||
4. Print fidelity (PDF/X for press).
|
||||
5. Archive (PDF/A — embed fonts, no encryption).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Text extraction (pypdf, 2026)
|
||||
```python
|
||||
from pypdf import PdfReader
|
||||
|
||||
reader = PdfReader("doc.pdf")
|
||||
text = ""
|
||||
for page in reader.pages:
|
||||
text += page.extract_text() + "\n"
|
||||
# pypdf 5.x: layout-mode option for column-aware
|
||||
text = "\n".join(p.extract_text(extraction_mode="layout") for p in reader.pages)
|
||||
```
|
||||
|
||||
### Better extraction with pdfplumber (preserves layout)
|
||||
```python
|
||||
import pdfplumber
|
||||
|
||||
with pdfplumber.open("doc.pdf") as pdf:
|
||||
for page in pdf.pages:
|
||||
# Tables
|
||||
for table in page.extract_tables():
|
||||
print(table)
|
||||
# Words with bbox
|
||||
for word in page.extract_words():
|
||||
print(word['text'], word['x0'], word['top'])
|
||||
```
|
||||
|
||||
### LLM-grade extraction with Unstructured (2026)
|
||||
```python
|
||||
from unstructured.partition.pdf import partition_pdf
|
||||
|
||||
elements = partition_pdf(
|
||||
filename="doc.pdf",
|
||||
strategy="hi_res", # uses layout model
|
||||
infer_table_structure=True,
|
||||
extract_images_in_pdf=True,
|
||||
)
|
||||
# Each element: Title, NarrativeText, Table, Image
|
||||
```
|
||||
|
||||
### Generate PDF (reportlab)
|
||||
```python
|
||||
from reportlab.lib.pagesizes import A4
|
||||
from reportlab.pdfgen import canvas
|
||||
|
||||
c = canvas.Canvas("out.pdf", pagesize=A4)
|
||||
c.setFont("Helvetica-Bold", 16)
|
||||
c.drawString(72, 800, "Invoice #1234")
|
||||
c.setFont("Helvetica", 10)
|
||||
for i, line in enumerate(items):
|
||||
c.drawString(72, 760 - i*14, line)
|
||||
c.showPage()
|
||||
c.save()
|
||||
```
|
||||
|
||||
### Modern HTML→PDF (Playwright, replaces wkhtmltopdf)
|
||||
```python
|
||||
from playwright.async_api import async_playwright
|
||||
|
||||
async def html_to_pdf(html, out):
|
||||
async with async_playwright() as p:
|
||||
browser = await p.chromium.launch()
|
||||
page = await browser.new_page()
|
||||
await page.set_content(html)
|
||||
await page.pdf(path=out, format="A4", print_background=True)
|
||||
await browser.close()
|
||||
```
|
||||
|
||||
### Sign PDF (PAdES, pyhanko)
|
||||
```python
|
||||
from pyhanko.sign import signers, fields
|
||||
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
|
||||
|
||||
with open("input.pdf", "rb") as inf:
|
||||
w = IncrementalPdfFileWriter(inf)
|
||||
fields.append_signature_field(w, sig_field_spec=fields.SigFieldSpec("Sig1", box=(50, 50, 200, 100)))
|
||||
signer = signers.SimpleSigner.load("cert.pem", "key.pem")
|
||||
with open("signed.pdf", "wb") as out:
|
||||
signers.sign_pdf(w, signers.PdfSignatureMetadata(field_name="Sig1"), signer=signer, output=out)
|
||||
```
|
||||
|
||||
### Repair / linearize (qpdf CLI)
|
||||
```bash
|
||||
qpdf --linearize input.pdf output.pdf
|
||||
qpdf --object-streams=generate --compress-streams=y input.pdf small.pdf
|
||||
qpdf --check input.pdf # validate xref + structure
|
||||
```
|
||||
|
||||
### Encrypted PDF
|
||||
```python
|
||||
from pypdf import PdfWriter
|
||||
|
||||
writer = PdfWriter(clone_from="doc.pdf")
|
||||
writer.encrypt(user_password="user", owner_password="owner", algorithm="AES-256")
|
||||
with open("encrypted.pdf", "wb") as f:
|
||||
writer.write(f)
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| Text extraction (simple) | pypdf 5.x |
|
||||
| Layout / tables | pdfplumber |
|
||||
| LLM RAG ingest | Unstructured + hi_res / Marker / Docling |
|
||||
| Generation (reports) | reportlab / WeasyPrint |
|
||||
| HTML → PDF (modern) | Playwright (Chrome headless) |
|
||||
| Forms / signing | pyhanko + qpdf |
|
||||
| Repair / optimize | qpdf, mutool |
|
||||
|
||||
**기본값**: 매 ingest → Unstructured (layout-aware), 매 generate → Playwright (HTML).
|
||||
|
||||
## 🔗 Graph
|
||||
- 응용: [[Document AI]]
|
||||
- Adjacent: [[OCR]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 form-filled PDF 의 question. 매 extraction tool 의 selection. 매 schema mapping.
|
||||
**언제 X**: 매 binary blob 의 direct edit 의 LLM 의 X. 매 spec-conformant tool 의 use.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Regex-based PDF parsing**: 매 binary + xref 의 fragile. 매 lib 의 사용.
|
||||
- **Single extraction strategy**: 매 scanned PDF 의 OCR fallback. 매 hi_res strategy.
|
||||
- **No PDF/A for archive**: 매 font 의 missing 의 future render fail.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (ISO 32000-2:2020, pypdf docs, Unstructured docs, qpdf manual).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — PDF structure + 2026 extraction/generation toolchain |
|
||||
@@ -0,0 +1,169 @@
|
||||
---
|
||||
id: wiki-2026-0508-page-experience-algorithm
|
||||
title: Page Experience Algorithm
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Google Page Experience, Core Web Vitals ranking, INP]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [seo, web-performance, core-web-vitals, google]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: N/A
|
||||
framework: Google Search Ranking
|
||||
---
|
||||
|
||||
# Page Experience Algorithm
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 Google 의 ranking signal 으로서 의 매 user perceived UX metric"**. 매 2021 Page Experience update 매 mobile 적용, 매 2022 desktop 확장, 매 2024-03 매 FID → INP 교체. 매 2026 의 매 core signal: LCP / INP / CLS + HTTPS / mobile-friendly / no-intrusive-interstitial.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Core Web Vitals (2026)
|
||||
- **LCP (Largest Contentful Paint)**: 매 viewport 의 매 largest element render 시간. **Good < 2.5s**.
|
||||
- **INP (Interaction to Next Paint)**: 매 모든 interaction 의 매 max latency (75th percentile). **Good < 200ms**.
|
||||
- **CLS (Cumulative Layout Shift)**: 매 unexpected layout shift 누적 score. **Good < 0.1**.
|
||||
|
||||
### 매 추가 signal
|
||||
- HTTPS 적용.
|
||||
- Mobile-friendly (responsive).
|
||||
- No intrusive interstitial (popup ad coverage).
|
||||
- (deprecated 2024-03) Safe Browsing — 매 separate signal.
|
||||
|
||||
### 매 측정 source
|
||||
- **CrUX (Chrome UX Report)**: 매 28-day rolling RUM data, 매 actual ranking signal.
|
||||
- **PageSpeed Insights**: 매 lab + field 결합 view.
|
||||
- **Search Console > Core Web Vitals report**.
|
||||
- **web-vitals.js**: 매 self-RUM library.
|
||||
|
||||
### 매 응용
|
||||
1. SEO ranking 향상.
|
||||
2. Conversion rate 개선 (slow → bounce).
|
||||
3. AdSense ad serving quality.
|
||||
4. Discover feed 노출 자격.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 1. web-vitals.js 측정
|
||||
```ts
|
||||
import { onLCP, onINP, onCLS } from 'web-vitals';
|
||||
|
||||
onLCP((metric) => sendToAnalytics('LCP', metric));
|
||||
onINP((metric) => sendToAnalytics('INP', metric));
|
||||
onCLS((metric) => sendToAnalytics('CLS', metric));
|
||||
|
||||
function sendToAnalytics(name: string, metric: any) {
|
||||
navigator.sendBeacon('/rum', JSON.stringify({
|
||||
name, value: metric.value, id: metric.id, rating: metric.rating
|
||||
}));
|
||||
}
|
||||
```
|
||||
|
||||
### 2. LCP 최적화 — preload hero image
|
||||
```html
|
||||
<link rel="preload" as="image"
|
||||
href="/hero.webp"
|
||||
fetchpriority="high"
|
||||
imagesrcset="/hero-800.webp 800w, /hero-1600.webp 1600w"
|
||||
imagesizes="100vw">
|
||||
```
|
||||
|
||||
### 3. INP 최적화 — long task break
|
||||
```ts
|
||||
async function processLargeList(items: Item[]) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
process(items[i]);
|
||||
if (i % 50 === 0) {
|
||||
await scheduler.yield(); // 매 2026 Scheduler API
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. CLS 방지 — explicit dimensions
|
||||
```html
|
||||
<img src="/photo.webp" width="800" height="600" alt="...">
|
||||
<iframe src="..." width="560" height="315"></iframe>
|
||||
|
||||
<!-- font swap reserve space -->
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
src: url(/inter.woff2) format("woff2");
|
||||
size-adjust: 100%;
|
||||
ascent-override: 90%;
|
||||
font-display: swap;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 5. Defer non-critical JS
|
||||
```html
|
||||
<script src="/analytics.js" defer></script>
|
||||
<script type="module" src="/app.js"></script>
|
||||
<script src="/legacy.js" nomodule defer></script>
|
||||
```
|
||||
|
||||
### 6. Resource hints
|
||||
```html
|
||||
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
|
||||
<link rel="dns-prefetch" href="https://api.example.com">
|
||||
<link rel="modulepreload" href="/critical-module.js">
|
||||
```
|
||||
|
||||
### 7. CrUX API query (BigQuery)
|
||||
```sql
|
||||
SELECT
|
||||
origin,
|
||||
largest_contentful_paint.histogram.density AS lcp_density,
|
||||
interaction_to_next_paint.histogram.density AS inp_density
|
||||
FROM `chrome-ux-report.materialized.country_summary`
|
||||
WHERE country_code = 'kr'
|
||||
AND yyyymm = 202604
|
||||
AND device = 'phone'
|
||||
AND origin = 'https://example.com';
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Priority |
|
||||
|---|---|
|
||||
| LCP > 4s | Hero image preload + fetchpriority=high (매 first) |
|
||||
| INP > 500ms | React 18+ concurrent + scheduler.yield() (매 2번째) |
|
||||
| CLS > 0.25 | Image dimensions + font swap stabilization (매 quick win) |
|
||||
| All green but slow ranking | Beyond CWV — content quality matters |
|
||||
| Mobile-only fail | Test 매 mobile network throttle (Slow 4G) |
|
||||
|
||||
**기본값**: web-vitals.js + Lighthouse CI + CrUX field monitoring 의 매 weekly review.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[SEO]] · [[Web Performance]]
|
||||
- 변형: [[Lighthouse]]
|
||||
- 응용: [[Core Web Vitals Optimization (INP, LCP, CLS)|Core Web Vitals]]
|
||||
- Adjacent: [[Lighthouse CI]] · [[PageSpeed Insights]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 SEO-driven traffic 매 critical (e-commerce, news, blog). 매 ranking 매 stagnant + 매 lab metric 양호 한 경우.
|
||||
**언제 X**: 매 internal tool / B2B SaaS (organic search 매 minor). 매 ranking 의 매 dominant signal 의 X — 매 content 매 first.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Lab metric 만 monitor**: 매 PageSpeed score 100 + 매 field CrUX poor — 매 real users 의 perspective 누락.
|
||||
- **75th percentile 무시**: 매 mean / median 매 deceiving — 매 long tail 매 ranking 결정.
|
||||
- **INP 의 무시**: 매 2024-03 부터 매 FID 대체 — 매 legacy site 매 INP regression 매 routine.
|
||||
- **CLS shift container 매 transform 으로 회피**: 매 actual layout 매 jarring — 매 reserved space 가 매 정답.
|
||||
- **Preload 의 abuse**: 매 모든 image preload → 매 critical asset 매 starve.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (web.dev/vitals 2026-05, Google Search Central 공식 docs, CrUX dataset).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — INP-replaces-FID + 2026 Scheduler API yield pattern |
|
||||
@@ -0,0 +1,200 @@
|
||||
---
|
||||
id: wiki-2026-0508-parse-dont-validate
|
||||
title: Parse, Don't Validate
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [parse don't validate, type-driven design, smart constructor, refinement type]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [type-system, design, haskell, typescript, validation]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript/Haskell
|
||||
framework: Zod, Effect, Brand types
|
||||
---
|
||||
|
||||
# Parse, Don't Validate
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 unsafe input 매 한번 parse → 매 typed value 매 produce, 매 downstream 매 다시 검증 의 X"**. 매 2019 Alexis King (lexi-lambda) 의 Haskell post 의 origin. 매 핵심 idea: 매 validation 매 boolean 의 throw — 매 information 의 lose. 매 parsing 매 validated 형식 의 새 type 의 produce — 매 type system 의 매 invariant 의 carry.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 validate 의 problem
|
||||
```ts
|
||||
// 매 anti-pattern
|
||||
function isNonEmpty<T>(arr: T[]): boolean { return arr.length > 0; }
|
||||
|
||||
function head<T>(arr: T[]): T {
|
||||
if (!isNonEmpty(arr)) throw new Error("empty!");
|
||||
return arr[0]; // 매 type system 매 still T | undefined
|
||||
}
|
||||
```
|
||||
- 매 `isNonEmpty` check 후 매 type 매 `T[]` (그대로) — 매 information lost.
|
||||
- 매 head 매 매번 다시 check or throw.
|
||||
- 매 caller 매 invariant 의 untracked.
|
||||
|
||||
### 매 parse 의 solution
|
||||
```ts
|
||||
type NonEmpty<T> = readonly [T, ...T[]];
|
||||
|
||||
function parseNonEmpty<T>(arr: T[]): NonEmpty<T> | null {
|
||||
return arr.length > 0 ? (arr as NonEmpty<T>) : null;
|
||||
}
|
||||
|
||||
function head<T>(arr: NonEmpty<T>): T {
|
||||
return arr[0]; // 매 항상 safe — type system 의 guarantee
|
||||
}
|
||||
```
|
||||
- 매 parse 결과 매 새 type — 매 invariant 가 매 type 에 baked in.
|
||||
- 매 downstream 매 trust — 매 re-check 의 X.
|
||||
|
||||
### 매 응용
|
||||
1. API request body validation (Zod / Effect Schema).
|
||||
2. ID type discrimination (UserId vs OrderId).
|
||||
3. URL / Email parsing.
|
||||
4. Smart constructor (private constructor + parse function).
|
||||
5. Domain modeling (PositiveNumber, NonEmptyString).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 1. Branded type (TypeScript)
|
||||
```ts
|
||||
type Brand<T, B> = T & { readonly __brand: B };
|
||||
type Email = Brand<string, 'Email'>;
|
||||
|
||||
function parseEmail(s: string): Email | null {
|
||||
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s) ? (s as Email) : null;
|
||||
}
|
||||
|
||||
function sendMail(to: Email, body: string) { /* 매 trust to */ }
|
||||
|
||||
const raw = "user@example.com";
|
||||
const email = parseEmail(raw);
|
||||
if (!email) throw new Error("bad email");
|
||||
sendMail(email, "hi"); // 매 OK
|
||||
sendMail(raw, "hi"); // 매 type error
|
||||
```
|
||||
|
||||
### 2. Zod schema (parse-style)
|
||||
```ts
|
||||
import { z } from 'zod';
|
||||
|
||||
const UserSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
email: z.string().email(),
|
||||
age: z.number().int().min(0).max(150),
|
||||
});
|
||||
|
||||
type User = z.infer<typeof UserSchema>; // 매 fully-typed
|
||||
|
||||
app.post('/users', (req, res) => {
|
||||
const result = UserSchema.safeParse(req.body);
|
||||
if (!result.success) return res.status(400).json(result.error);
|
||||
createUser(result.data); // 매 trust — User type 매 guaranteed
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Effect Schema (2026 의 매 modern)
|
||||
```ts
|
||||
import { Schema as S } from "effect";
|
||||
|
||||
const PositiveInt = S.Int.pipe(S.positive(), S.brand("PositiveInt"));
|
||||
type PositiveInt = S.Schema.Type<typeof PositiveInt>;
|
||||
|
||||
const decode = S.decodeUnknownSync(PositiveInt);
|
||||
const x = decode(42); // 매 PositiveInt
|
||||
const y = decode(-1); // 매 throws ParseError
|
||||
```
|
||||
|
||||
### 4. Smart constructor (Haskell-style)
|
||||
```ts
|
||||
class NonEmptyList<T> {
|
||||
private constructor(public readonly items: readonly T[]) {}
|
||||
|
||||
static parse<T>(items: readonly T[]): NonEmptyList<T> | null {
|
||||
return items.length > 0 ? new NonEmptyList(items) : null;
|
||||
}
|
||||
|
||||
get head(): T { return this.items[0]; } // 매 always safe
|
||||
get tail(): readonly T[] { return this.items.slice(1); }
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Discriminated ID type
|
||||
```ts
|
||||
type UserId = Brand<string, 'UserId'>;
|
||||
type OrderId = Brand<string, 'OrderId'>;
|
||||
|
||||
function getUser(id: UserId): User { /*...*/ }
|
||||
function getOrder(id: OrderId): Order { /*...*/ }
|
||||
|
||||
const uid = parseUserId(req.params.id);
|
||||
if (!uid) throw new Error();
|
||||
getUser(uid); // 매 OK
|
||||
getOrder(uid); // 매 type error 매 prevent mix-up
|
||||
```
|
||||
|
||||
### 6. Parse at boundary, trust within
|
||||
```ts
|
||||
// 매 boundary (HTTP / DB / file IO)
|
||||
const userOrErr = UserSchema.safeParse(rawJson);
|
||||
|
||||
// 매 internal — User type 매 항상 valid
|
||||
function processUser(u: User) {
|
||||
// 매 u.email 매 valid email — 매 re-check 의 X
|
||||
// 매 u.age 매 0-150 매 — 매 re-check 의 X
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Refinement chain
|
||||
```ts
|
||||
const NonEmptyString = z.string().min(1).brand<'NonEmptyString'>();
|
||||
const EmailString = NonEmptyString.refine(
|
||||
s => /^[^@]+@[^@]+$/.test(s)
|
||||
).brand<'Email'>();
|
||||
type Email = z.infer<typeof EmailString>;
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Apply parse-don't-validate? |
|
||||
|---|---|
|
||||
| Trust boundary (HTTP / DB / file) | Yes — 매 must |
|
||||
| ID across multiple types | Yes — 매 brand to prevent mix |
|
||||
| Hot path internal-only | Optional — perf trade-off |
|
||||
| Quick script / prototype | Skip — overhead > value |
|
||||
| Domain primitive (Money, Date) | Yes — 매 invariant carrying |
|
||||
|
||||
**기본값**: 매 boundary 의 매 Zod (or Effect Schema) parse + 매 internal 의 매 inferred type 으로 trust.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Type-Driven Design]]
|
||||
- 변형: [[Refinement Type]] · [[Smart Constructor]]
|
||||
- 응용: [[Zod]] · [[Effect Schema]] · [[Branded Type]]
|
||||
- Adjacent: [[Validation]] · [[Type Narrowing]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 API server / public library 의 매 input validation. 매 ID mix-up bug 매 routine 한 codebase. 매 domain rule 매 type-encode 가능 한 경우.
|
||||
**언제 X**: 매 internal-only quick script. 매 highly dynamic JSON 의 schema 가 unknown. 매 perf-critical hot loop (parse overhead).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Validate 후 raw type 의 pass**: 매 invariant 매 lose. 매 항상 새 type 의 return.
|
||||
- **Parse 매 boundary X 의 매 매 layer 의 repeat**: 매 perf 손실 + 매 동일 logic 의 duplicate.
|
||||
- **Brand 의 매 runtime check 의 X**: 매 cast 매 type-only — 매 parse function 매 항상 runtime check 포함.
|
||||
- **Optional 의 abuse**: 매 `email?: string` — 매 invariant 매 unclear. 매 명확한 `Email | null`.
|
||||
- **Throw on parse fail (preference)**: 매 Result type / safeParse 의 매 prefer — 매 caller flow 매 explicit.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Alexis King "Parse, Don't Validate" 2019, Zod 4 / Effect 3.x docs 2026-05).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Branded types + Zod/Effect Schema 의 modern parse pattern |
|
||||
@@ -0,0 +1,206 @@
|
||||
---
|
||||
id: wiki-2026-0508-practical-cryptography
|
||||
title: Practical Cryptography
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Applied Cryptography, Crypto Engineering]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [cryptography, security, encryption]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Python/Go
|
||||
framework: libsodium/cryptography
|
||||
---
|
||||
|
||||
# Practical Cryptography
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 don't roll your own crypto"**. 매 application engineer 의 task 는 매 well-vetted primitives (AES-GCM, ChaCha20-Poly1305, Ed25519, X25519) 의 correct composition — 매 algorithm 의 invention 아님. 2026 의 modern stack 은 libsodium, AWS KMS, age, Noise Protocol Framework 위 의 build.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Primitives (2026 baseline)
|
||||
- **Symmetric AEAD**: ChaCha20-Poly1305 (mobile/no-AES-NI), AES-256-GCM (server with AES-NI), AES-256-GCM-SIV (nonce-misuse resistant).
|
||||
- **Asymmetric**: X25519 (ECDH key agreement), Ed25519 (signing), Kyber-1024 (post-quantum KEM, NIST FIPS 203).
|
||||
- **Hashing**: BLAKE3 (fast), SHA-256 (interop), Argon2id (password hashing, 2026 default).
|
||||
- **Key derivation**: HKDF-SHA256 (key expansion), Argon2id (password → key).
|
||||
|
||||
### 매 Threat models
|
||||
- **Confidentiality**: encrypt-then-MAC, AEAD prevents IND-CCA2 attacks.
|
||||
- **Integrity**: HMAC, Poly1305, signatures.
|
||||
- **Authenticity**: signatures (Ed25519), authenticated key exchange (Noise).
|
||||
- **Forward secrecy**: ephemeral keys (X25519 per session).
|
||||
- **Post-quantum**: hybrid Kyber + X25519 (2026 TLS 1.3 default).
|
||||
|
||||
### 매 응용
|
||||
1. TLS 1.3 (transport security).
|
||||
2. Signal Protocol (E2EE messaging — Double Ratchet).
|
||||
3. age/rage (file encryption — replaces GPG).
|
||||
4. JWT/PASETO (stateless tokens — PASETO preferred).
|
||||
5. Password storage (Argon2id with per-user salt).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### AEAD encryption (ChaCha20-Poly1305 with libsodium)
|
||||
```python
|
||||
from nacl.secret import SecretBox
|
||||
from nacl.utils import random
|
||||
|
||||
key = random(SecretBox.KEY_SIZE) # 32 bytes
|
||||
box = SecretBox(key)
|
||||
|
||||
# Encrypt — nonce auto-generated, prepended to ciphertext
|
||||
ciphertext = box.encrypt(b"sensitive data")
|
||||
|
||||
# Decrypt — fails with CryptoError on tampering
|
||||
plaintext = box.decrypt(ciphertext)
|
||||
```
|
||||
|
||||
### Authenticated key exchange (X25519 + HKDF)
|
||||
```python
|
||||
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
|
||||
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
|
||||
# Each party generates ephemeral keypair
|
||||
alice_priv = X25519PrivateKey.generate()
|
||||
bob_priv = X25519PrivateKey.generate()
|
||||
|
||||
# Compute shared secret
|
||||
shared = alice_priv.exchange(bob_priv.public_key())
|
||||
|
||||
# Derive symmetric key — never use raw DH output as key
|
||||
session_key = HKDF(
|
||||
algorithm=hashes.SHA256(),
|
||||
length=32,
|
||||
salt=None,
|
||||
info=b"session-v1",
|
||||
).derive(shared)
|
||||
```
|
||||
|
||||
### Password hashing (Argon2id)
|
||||
```python
|
||||
from argon2 import PasswordHasher
|
||||
|
||||
ph = PasswordHasher(
|
||||
time_cost=3, # iterations
|
||||
memory_cost=65536, # 64 MiB
|
||||
parallelism=4,
|
||||
)
|
||||
|
||||
hash = ph.hash("user-password") # store this
|
||||
|
||||
# Verify (constant-time)
|
||||
try:
|
||||
ph.verify(hash, "user-password")
|
||||
if ph.check_needs_rehash(hash):
|
||||
new_hash = ph.hash("user-password") # parameter upgrade
|
||||
except VerifyMismatchError:
|
||||
raise AuthError()
|
||||
```
|
||||
|
||||
### Digital signature (Ed25519)
|
||||
```python
|
||||
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
|
||||
|
||||
priv = Ed25519PrivateKey.generate()
|
||||
pub = priv.public_key()
|
||||
|
||||
signature = priv.sign(b"message")
|
||||
pub.verify(signature, b"message") # raises InvalidSignature on failure
|
||||
```
|
||||
|
||||
### Envelope encryption (KMS pattern)
|
||||
```python
|
||||
import boto3
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
kms = boto3.client("kms")
|
||||
|
||||
def encrypt_blob(plaintext: bytes, kms_key_id: str) -> dict:
|
||||
# Generate per-message data key
|
||||
resp = kms.generate_data_key(KeyId=kms_key_id, KeySpec="AES_256")
|
||||
data_key = resp["Plaintext"]
|
||||
encrypted_dk = resp["CiphertextBlob"]
|
||||
|
||||
# Encrypt data with data key, discard plaintext data key
|
||||
f = Fernet(base64.urlsafe_b64encode(data_key))
|
||||
ct = f.encrypt(plaintext)
|
||||
|
||||
return {"ciphertext": ct, "encrypted_key": encrypted_dk}
|
||||
```
|
||||
|
||||
### Constant-time comparison
|
||||
```python
|
||||
import hmac
|
||||
|
||||
# WRONG — leaks length info via timing
|
||||
if user_token == stored_token:
|
||||
pass
|
||||
|
||||
# RIGHT — constant time
|
||||
if hmac.compare_digest(user_token, stored_token):
|
||||
pass
|
||||
```
|
||||
|
||||
### Post-quantum hybrid KEM (2026)
|
||||
```python
|
||||
# liboqs-python — hybrid X25519 + Kyber768
|
||||
from oqs import KeyEncapsulation
|
||||
import nacl.public
|
||||
|
||||
# Classical X25519
|
||||
x_priv = nacl.public.PrivateKey.generate()
|
||||
|
||||
# Post-quantum Kyber
|
||||
with KeyEncapsulation("Kyber768") as kem:
|
||||
pq_pub = kem.generate_keypair()
|
||||
|
||||
# Combine both shared secrets via HKDF for hybrid security
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| File encryption | age (modern), libsodium SecretBox |
|
||||
| Password hash | Argon2id (never bcrypt for new systems) |
|
||||
| Token format | PASETO v4 (Ed25519) over JWT |
|
||||
| Mobile/IoT AEAD | ChaCha20-Poly1305 |
|
||||
| TLS 1.3 backend | rustls or BoringSSL, hybrid PQ enabled |
|
||||
| Signing | Ed25519 (never RSA for new systems) |
|
||||
|
||||
**기본값**: libsodium + Argon2id + Ed25519 + ChaCha20-Poly1305.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Practical-Cryptography|Cryptography]] · [[Security]]
|
||||
- 변형: [[보안 및 시스템 신뢰성 표준|Symmetric-Encryption]]
|
||||
- 응용: [[Secret_Management]] · [[보안 및 시스템 신뢰성 표준|Zero-Trust Architecture]]
|
||||
- Adjacent: [[보안 및 시스템 신뢰성 표준|OWASP Top 10]] · [[Practical-Cryptography]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: explain primitive choice, audit crypto code for misuse, suggest migration paths.
|
||||
**언제 X**: never ask LLM to design new protocol — always defer to peer-reviewed designs (Noise, Signal).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Roll-your-own**: custom XOR-based "encryption" — 매 broken in seconds.
|
||||
- **ECB mode**: leaks pattern (penguin image meme). Always GCM/CTR/CBC-with-MAC.
|
||||
- **Static IV/nonce**: catastrophic for GCM (key recovery). Always random or counter.
|
||||
- **MD5/SHA-1**: collision-broken. Never for security purposes.
|
||||
- **bcrypt for new systems**: Argon2id 2026 default.
|
||||
- **String comparison for tokens**: use `hmac.compare_digest`.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (NIST FIPS 203/204/205, RFC 9180 HPKE, libsodium docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — full primitives + 2026 PQ baseline |
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
id: wiki-2026-0508-prettier
|
||||
title: Prettier
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Prettier Formatter, Code Formatter]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [tooling, formatter, javascript, typescript]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: JavaScript/TypeScript
|
||||
framework: Prettier
|
||||
---
|
||||
|
||||
# Prettier
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 opinionated formatter — 매 bikeshed 종결자"**. Prettier 매 AST re-print 방식 사용 — 매 source 의 whitespace 무시 의 deterministic output 생성. 2026 매 v3.x 의 ESM-first + plugin ecosystem 안정화.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Re-print 방식
|
||||
- 매 parser 의 source → AST 변환.
|
||||
- 매 printer 의 AST → IR (Doc) 생성.
|
||||
- 매 IR 의 line-width constraint 기반 layout 결정.
|
||||
- 매 original whitespace 의 X 보존.
|
||||
|
||||
### 매 ESLint 와의 분리
|
||||
- ESLint: 매 code quality (logic, anti-patterns).
|
||||
- Prettier: 매 formatting (whitespace, quote, line-break).
|
||||
- 매 `eslint-config-prettier` 의 conflict rule disable.
|
||||
|
||||
### 매 응용
|
||||
1. 매 monorepo 의 unified formatting.
|
||||
2. CI 의 `--check` mode — 매 format violation 의 fail.
|
||||
3. Pre-commit hook (`lint-staged` + `husky`) 의 auto-format.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Config 의 minimal `.prettierrc`
|
||||
```json
|
||||
{
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"arrowParens": "always",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
```
|
||||
|
||||
### CLI 의 batch format
|
||||
```bash
|
||||
# Format in place
|
||||
npx prettier --write "src/**/*.{ts,tsx,js,jsx,json,md}"
|
||||
|
||||
# CI check
|
||||
npx prettier --check "src/**/*.{ts,tsx}"
|
||||
```
|
||||
|
||||
### lint-staged 의 staged-only format
|
||||
```json
|
||||
// package.json
|
||||
{
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx,js,jsx}": [
|
||||
"prettier --write",
|
||||
"eslint --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Plugin 의 ordering — `prettier-plugin-tailwindcss`
|
||||
```json
|
||||
{
|
||||
"plugins": ["prettier-plugin-tailwindcss"]
|
||||
}
|
||||
// Tailwind class 의 자동 ordering — flex p-4 m-2 → m-2 p-4 flex
|
||||
```
|
||||
|
||||
### Programmatic API (v3 ESM)
|
||||
```typescript
|
||||
import prettier from "prettier";
|
||||
|
||||
const formatted = await prettier.format(sourceCode, {
|
||||
parser: "typescript",
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Editor integration — VSCode
|
||||
```json
|
||||
// .vscode/settings.json
|
||||
{
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }
|
||||
}
|
||||
```
|
||||
|
||||
### Override 의 file-type 별 config
|
||||
```json
|
||||
{
|
||||
"semi": true,
|
||||
"overrides": [
|
||||
{ "files": "*.md", "options": { "proseWrap": "always", "printWidth": 80 } },
|
||||
{ "files": "*.yml", "options": { "tabWidth": 2 } }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Solo project | Prettier defaults — 매 zero config. |
|
||||
| Team — strict | `.prettierrc` commit + CI check. |
|
||||
| Tailwind 사용 | `prettier-plugin-tailwindcss` 필수. |
|
||||
| Legacy codebase | 매 한 번 `--write` + 매 `.git-blame-ignore-revs` 추가. |
|
||||
| Monorepo | Root `.prettierrc` + workspace override. |
|
||||
|
||||
**기본값**: `singleQuote: true`, `trailingComma: "all"`, `printWidth: 100`, format-on-save + pre-commit hook.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Code Formatting]]
|
||||
- 변형: [[ESLint]] · [[Biome]]
|
||||
- 응용: [[153_pre-commit과_품질_게이트|Pre-commit Hooks]] · [[lint-staged]]
|
||||
- Adjacent: [[AST]] · [[TypeScript]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: JS/TS/JSON/MD/YAML/CSS — 매 multi-language project 의 unified formatting.
|
||||
**언제 X**: 매 Rust/Go (rustfmt/gofmt 의 사용), 매 single-language Rust-only 의 Biome 고려.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **ESLint 의 stylistic rules + Prettier 동시 사용**: 매 conflict 발생 → `eslint-config-prettier` 적용.
|
||||
- **`.prettierrc` 의 commit X**: 매 team 의 inconsistent format.
|
||||
- **Format-on-save 의 X + manual format**: 매 review noise 증가.
|
||||
- **매 large initial format 의 main branch 직접 commit**: blame 의 손상 — 매 `.git-blame-ignore-revs` 사용.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Prettier docs v3.x).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Prettier 매 re-print formatter + config patterns 정리 |
|
||||
@@ -0,0 +1,158 @@
|
||||
---
|
||||
id: wiki-2026-0508-procedural-rhetoric
|
||||
title: Procedural Rhetoric
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Persuasive Games, Computational Rhetoric]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [rhetoric, game-design, persuasion]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: design
|
||||
framework: Bogost framework
|
||||
---
|
||||
|
||||
# Procedural Rhetoric
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 argument 의 made not by words, but by rules"**. Ian Bogost 의 *Persuasive Games* (2007) 의 coined — 매 systems/processes/simulations 의 medium 의 argumentation. 2026 의 LLM-driven dynamic narrative + simulation games (Civ VII, FrostPunk 2) 의 procedural rhetoric 의 mainstream.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Bogost's framework
|
||||
- **Verbal rhetoric**: words, written/spoken.
|
||||
- **Visual rhetoric**: images, layout, color.
|
||||
- **Procedural rhetoric**: rules, systems, feedback loops.
|
||||
- 매 game 의 unique medium — 매 "what you do" expresses argument.
|
||||
|
||||
### 매 Mechanisms
|
||||
- **Constraint**: what you can't do says as much as what you can.
|
||||
- **Feedback loops**: reward shapes belief about what matters.
|
||||
- **Simulation gap**: simplifications reveal designer assumptions.
|
||||
- **Failure states**: what counts as losing encodes values.
|
||||
- **Resource economy**: scarcity → priorities.
|
||||
- **Agency vs. determinism**: how much player matters.
|
||||
|
||||
### 매 Examples
|
||||
- **September 12th** (Frasca): bombing terrorists creates more terrorists.
|
||||
- **PeaceMaker**: Israeli-Palestinian dual-perspective.
|
||||
- **Papers, Please**: bureaucratic complicity, moral fatigue.
|
||||
- **This War of Mine**: civilian war experience.
|
||||
- **FrostPunk**: authoritarianism as survival logic.
|
||||
- **Civilization**: progress narrative encoded in tech tree.
|
||||
- **Cookie Clicker**: critique of incremental design.
|
||||
|
||||
### 매 응용
|
||||
1. Serious games (training, education).
|
||||
2. News games (Bloomberg's Build the wall vs Don't, NYT graphics).
|
||||
3. Activist games (climate, refugees).
|
||||
4. Marketing simulations.
|
||||
5. AI-driven dynamic narrative (2026 Inworld, Convai).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Encoding argument as mechanic
|
||||
```
|
||||
Argument: "Bureaucracy dehumanizes"
|
||||
Mechanic: Time pressure + paperwork + small reward for thoroughness, big penalty for missing detail
|
||||
Result: Player feels the dehumanization rather than reads about it
|
||||
→ Papers, Please
|
||||
```
|
||||
|
||||
### Resource scarcity as ideology
|
||||
```
|
||||
Argument: "Survival justifies authoritarianism"
|
||||
Mechanic: Heat ↓ over time, citizens demand law book, only authoritarian laws prevent extinction
|
||||
Result: Player chooses oppression "rationally"
|
||||
→ FrostPunk
|
||||
```
|
||||
|
||||
### Simplification as critique
|
||||
```typescript
|
||||
// Climate simulator: emissions only knob
|
||||
// By omitting "carbon offsets", "green tech", argues these are insufficient distractions
|
||||
const tempAtYear = (year: number, emissions: number) =>
|
||||
baseline + emissions * year * sensitivity;
|
||||
// What's missing IS the rhetoric
|
||||
```
|
||||
|
||||
### LLM-driven NPC dialogue (2026)
|
||||
```typescript
|
||||
// Inworld-style: NPC values encoded as system prompt + memory
|
||||
// The game's argument now adapts to player — emergent procedural rhetoric
|
||||
const npcPrompt = `
|
||||
You are a refugee in an unnamed conflict.
|
||||
Your values: family safety > nation > ideology.
|
||||
You distrust both sides equally.
|
||||
Respond based on the player's prior actions: ${recentActions.join(', ')}.
|
||||
`;
|
||||
// The NPC's reactive logic IS the rhetorical move
|
||||
```
|
||||
|
||||
### Failure state as moral
|
||||
```
|
||||
Lose condition: Empire collapses if happiness < 50%
|
||||
Encoded argument: "Subject welfare is instrumentally necessary, not intrinsically valued"
|
||||
vs.
|
||||
Lose condition: Game ends when one citizen dies
|
||||
Encoded argument: "Each person has infinite worth"
|
||||
```
|
||||
|
||||
### Reward loop as ethics
|
||||
```
|
||||
Reward: +XP per enemy killed
|
||||
Argument (unintended): violence is the path to progress
|
||||
Reward: +XP per peaceful resolution
|
||||
Argument: dialogue valued
|
||||
→ Designers encode ethics whether they intend to or not
|
||||
```
|
||||
|
||||
### Counter-rhetoric (anti-game)
|
||||
```
|
||||
Players expect: shooter rewards aggression
|
||||
Anti-game: every kill ages your character +1 year, game ends at 100
|
||||
→ Mechanic refutes the genre's implicit argument
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Educational claim | Simulate causal model, let player explore |
|
||||
| Empathy goal | Constrain player to NPC perspective |
|
||||
| Critique of system | Make player IS the system, feel its pressures |
|
||||
| Information delivery | Verbal/visual still better for facts |
|
||||
| Complex policy | Procedural model + verbal scaffolding |
|
||||
|
||||
**기본값**: identify the felt experience the player should have, design mechanics that produce it, then verify via playtest.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Game-Design]]
|
||||
- 변형: [[Persuasive-Games]]
|
||||
- 응용: [[Beat Saber 엑서게임 연구(Beat Saber Exergaming Study)]] · [[Edtech-Industry-Trends]]
|
||||
- Adjacent: [[Media-Literacy]] · [[Information-Society]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: analyze a game's procedural argument, brainstorm mechanics that embody a thesis, generate playtest probes.
|
||||
**언제 X**: never collapse procedural rhetoric to "narrative" — the rules ARE the argument.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Skin over substance**: stick a "climate change" theme on standard mechanics — argument absent.
|
||||
- **Sermon mechanic**: the only "right" choice — no agency, weak rhetoric.
|
||||
- **Unintended argument**: reward loop says A while writing says B — players believe the loop.
|
||||
- **Realism worship**: simulation accuracy ≠ rhetorical clarity.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Bogost *Persuasive Games* 2007, *How to Do Things with Videogames* 2011, Frasca *Videogames of the Oppressed*).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Bogost framework + 2026 LLM-NPC angle |
|
||||
@@ -0,0 +1,199 @@
|
||||
---
|
||||
id: wiki-2026-0508-quality-control
|
||||
title: Quality Control
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [QC, Software Quality]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [quality, testing, process]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript/Python
|
||||
framework: Playwright/pytest
|
||||
---
|
||||
|
||||
# Quality Control
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 quality 의 inspect 보다 build-in"**. 매 modern QC 의 shift-left — 매 unit test, type checking, static analysis, contract test, e2e — 매 layer 의 different bug class catch. 2026 의 LLM-augmented test generation + property-based testing 의 mainstream.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Test pyramid (2026 update)
|
||||
- **Unit (60-70%)**: pure function, fast, isolated.
|
||||
- **Integration (15-25%)**: module + DB/queue, real dependencies via testcontainers.
|
||||
- **E2E (5-10%)**: full user journey, Playwright/Cypress.
|
||||
- **Contract (5%)**: Pact, consumer-driven, prevent break-on-deploy.
|
||||
- **Property-based (cross-cutting)**: Hypothesis/fast-check, find edge cases.
|
||||
|
||||
### 매 Quality gates
|
||||
- 매 PR 의 merge 전: lint, type, unit test, coverage threshold, security scan.
|
||||
- 매 deploy 전: integration test, smoke test, canary metrics.
|
||||
- 매 prod: synthetic monitoring, real-user monitoring (RUM).
|
||||
|
||||
### 매 Defect classes
|
||||
- **Functional**: wrong output for given input.
|
||||
- **Performance**: slow, regression on benchmark.
|
||||
- **Security**: OWASP categories.
|
||||
- **Accessibility**: WCAG violations.
|
||||
- **Compatibility**: browser/OS specific.
|
||||
|
||||
### 매 응용
|
||||
1. CI/CD pipeline gates.
|
||||
2. Pre-merge bots (Danger, Reviewdog).
|
||||
3. Mutation testing (Stryker) — quality of tests themselves.
|
||||
4. Visual regression (Chromatic, Percy).
|
||||
5. Chaos engineering (production resilience).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Property-based testing (TypeScript with fast-check)
|
||||
```typescript
|
||||
import fc from 'fast-check';
|
||||
import { reverse } from './lib';
|
||||
|
||||
test('reverse twice = identity', () => {
|
||||
fc.assert(
|
||||
fc.property(fc.array(fc.integer()), (arr) => {
|
||||
expect(reverse(reverse(arr))).toEqual(arr);
|
||||
}),
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
### Contract test (Pact)
|
||||
```typescript
|
||||
// Consumer side
|
||||
const provider = new Pact({ consumer: 'Web', provider: 'OrdersAPI' });
|
||||
|
||||
await provider.addInteraction({
|
||||
state: 'order 123 exists',
|
||||
uponReceiving: 'a request for order 123',
|
||||
withRequest: { method: 'GET', path: '/orders/123' },
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
body: { id: '123', total: 99.0 },
|
||||
},
|
||||
});
|
||||
|
||||
// Generates pact.json — provider verifies against it in CI
|
||||
```
|
||||
|
||||
### Mutation testing (Stryker)
|
||||
```javascript
|
||||
// stryker.conf.js
|
||||
export default {
|
||||
testRunner: 'vitest',
|
||||
mutate: ['src/**/*.ts'],
|
||||
thresholds: { high: 80, low: 60, break: 50 },
|
||||
};
|
||||
// Mutates code (a + b → a - b) and checks if tests catch it
|
||||
// Surviving mutants = weak tests
|
||||
```
|
||||
|
||||
### LLM-assisted test generation (2026 pattern)
|
||||
```typescript
|
||||
// CI step: claude-code generates edge cases
|
||||
// $ claude test-gen src/parser.ts --output tests/parser.gen.test.ts
|
||||
// Then human review before merge — never blind-trust
|
||||
```
|
||||
|
||||
### Visual regression (Playwright)
|
||||
```typescript
|
||||
test('homepage matches snapshot', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(await page.screenshot()).toMatchSnapshot('home.png', {
|
||||
maxDiffPixelRatio: 0.01,
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Coverage gates (vitest)
|
||||
```typescript
|
||||
// vitest.config.ts
|
||||
export default {
|
||||
test: {
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
thresholds: {
|
||||
lines: 80,
|
||||
functions: 80,
|
||||
branches: 75,
|
||||
statements: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Pre-commit hook (lint-staged + husky)
|
||||
```json
|
||||
{
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx}": [
|
||||
"eslint --fix",
|
||||
"prettier --write",
|
||||
"vitest related --run"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Chaos test (Toxiproxy / Litmus)
|
||||
```yaml
|
||||
# Inject 500ms latency into Redis dependency
|
||||
apiVersion: chaos-mesh.org/v1alpha1
|
||||
kind: NetworkChaos
|
||||
spec:
|
||||
action: delay
|
||||
selector:
|
||||
labelSelectors: { app: redis }
|
||||
delay: { latency: 500ms }
|
||||
duration: 60s
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Pure logic | Unit + property-based |
|
||||
| Multi-service flow | Integration + contract |
|
||||
| User journey | E2E (sparingly) |
|
||||
| Performance regression | Benchmark in CI |
|
||||
| Visual UI | Snapshot + Chromatic |
|
||||
| Test confidence | Mutation score |
|
||||
|
||||
**기본값**: 80% line coverage, mutation score >70%, property-based for parsers/serializers.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Test_Automation]]
|
||||
- 변형: [[CI_CD_Pipeline]] · [[Test_Automation|Test_Automation_Mastery]]
|
||||
- 응용: [[Engineering Metrics (DORA)]] · [[Automated Quality & Review]]
|
||||
- Adjacent: [[Continuous Integration (CI)|Continuous_Integration]] · [[Husky]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: generate edge cases, suggest mutation-resistant assertions, identify untested branches.
|
||||
**언제 X**: never let LLM write the assertion AND implementation — confirmation bias.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Coverage worship**: 100% coverage, 0% assertions ("test executes but checks nothing").
|
||||
- **Flaky tests ignored**: erodes trust in suite. Quarantine and fix immediately.
|
||||
- **E2E-heavy pyramid**: slow, flaky, expensive. Push down to integration/unit.
|
||||
- **Manual QA only**: doesn't scale, regression-prone.
|
||||
- **No mutation testing**: blind to assertion quality.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Google Testing Blog, Mike Cohn pyramid, Stryker docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — pyramid + 2026 LLM-assisted patterns |
|
||||
@@ -0,0 +1,196 @@
|
||||
---
|
||||
id: wiki-2026-0508-raycasting
|
||||
title: Raycasting
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [ray casting, ray-object intersection, picking, ray-sphere, ray-triangle]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [graphics, geometry, ray-tracing, picking, collision]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript/GLSL
|
||||
framework: Three.js, WebGPU, three-mesh-bvh
|
||||
---
|
||||
|
||||
# Raycasting
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 ray 와 매 geometry 의 intersection test"**. 매 1968 Arthur Appel 의 매 first hidden surface paper 매 origin, 매 1992 Wolfenstein 3D 의 매 game engine signature. 매 2026 의 매 universal primitive: mouse picking, hit-test, AR placement, lighting, AI vision-cone, BIM section. 매 Raycasting ≠ Ray Tracing — 매 single ray (no recursion) vs 매 recursive light path.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 raycasting vs raytracing
|
||||
| | Raycasting | Ray Tracing |
|
||||
|---|---|---|
|
||||
| Recursion | 매 single hit | 매 reflection / refraction recursive |
|
||||
| Cost | 매 O(log N) per ray (BVH) | 매 50-1000x heavier |
|
||||
| Use | Picking, collision | Photorealistic render |
|
||||
|
||||
### 매 Ray = origin + t·direction
|
||||
- t > 0: 매 forward.
|
||||
- nearest hit: 매 minimum t > 0.
|
||||
- ray vs primitive: 매 sphere / plane / triangle / AABB / OBB.
|
||||
|
||||
### 매 acceleration structure
|
||||
- BVH (Bounding Volume Hierarchy): 매 dominant 매 2026.
|
||||
- KD-tree: 매 static scene 매 slightly faster build.
|
||||
- Octree: 매 voxel world.
|
||||
- Spatial hash: 매 dynamic scene.
|
||||
|
||||
### 매 응용
|
||||
1. Mouse picking (Three.js Raycaster).
|
||||
2. AR object placement (hit-test with depth).
|
||||
3. AI line-of-sight / vision cone.
|
||||
4. Bullet physics (sweep test).
|
||||
5. Audio occlusion (raycast for muffle).
|
||||
6. BIM 의 section plane / clipper.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### 1. Three.js mouse picking
|
||||
```ts
|
||||
import * as THREE from 'three';
|
||||
|
||||
const raycaster = new THREE.Raycaster();
|
||||
const mouse = new THREE.Vector2();
|
||||
|
||||
window.addEventListener('pointerdown', (e) => {
|
||||
mouse.x = (e.clientX / innerWidth) * 2 - 1;
|
||||
mouse.y = -(e.clientY / innerHeight) * 2 + 1;
|
||||
raycaster.setFromCamera(mouse, camera);
|
||||
const hits = raycaster.intersectObjects(scene.children, true);
|
||||
if (hits.length) console.log('Hit:', hits[0].object.name, hits[0].point);
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Ray-sphere intersection (analytic)
|
||||
```ts
|
||||
function raySphere(ro: V3, rd: V3, center: V3, r: number): number {
|
||||
const oc = sub(ro, center);
|
||||
const b = dot(oc, rd);
|
||||
const c = dot(oc, oc) - r * r;
|
||||
const h = b * b - c;
|
||||
if (h < 0) return -1;
|
||||
const t = -b - Math.sqrt(h);
|
||||
return t >= 0 ? t : -1;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Ray-triangle (Möller-Trumbore)
|
||||
```ts
|
||||
function rayTriangle(ro: V3, rd: V3, a: V3, b: V3, c: V3): number {
|
||||
const e1 = sub(b, a), e2 = sub(c, a);
|
||||
const p = cross(rd, e2);
|
||||
const det = dot(e1, p);
|
||||
if (Math.abs(det) < 1e-8) return -1;
|
||||
const inv = 1 / det;
|
||||
const tv = sub(ro, a);
|
||||
const u = dot(tv, p) * inv;
|
||||
if (u < 0 || u > 1) return -1;
|
||||
const q = cross(tv, e1);
|
||||
const v = dot(rd, q) * inv;
|
||||
if (v < 0 || u + v > 1) return -1;
|
||||
return dot(e2, q) * inv;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. BVH-accelerated picking (three-mesh-bvh)
|
||||
```ts
|
||||
import { computeBoundsTree, acceleratedRaycast } from 'three-mesh-bvh';
|
||||
|
||||
THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree;
|
||||
THREE.Mesh.prototype.raycast = acceleratedRaycast;
|
||||
|
||||
mesh.geometry.computeBoundsTree(); // 매 once
|
||||
// 매 매 raycast 100x+ faster
|
||||
```
|
||||
|
||||
### 5. AR hit-test (WebXR)
|
||||
```ts
|
||||
const session = await navigator.xr.requestSession('immersive-ar', {
|
||||
requiredFeatures: ['hit-test']
|
||||
});
|
||||
const refSpace = await session.requestReferenceSpace('viewer');
|
||||
const hitSource = await session.requestHitTestSource({ space: refSpace });
|
||||
|
||||
session.requestAnimationFrame(function frame(t, frame) {
|
||||
const results = frame.getHitTestResults(hitSource);
|
||||
if (results.length) {
|
||||
const pose = results[0].getPose(refSpace);
|
||||
placeReticleAt(pose.transform.matrix);
|
||||
}
|
||||
session.requestAnimationFrame(frame);
|
||||
});
|
||||
```
|
||||
|
||||
### 6. Vision cone (AI agent)
|
||||
```ts
|
||||
function canSee(agent: Agent, target: V3, world: BVH): boolean {
|
||||
const dir = normalize(sub(target, agent.pos));
|
||||
const angle = Math.acos(dot(dir, agent.forward));
|
||||
if (angle > agent.fov / 2) return false;
|
||||
const dist = length(sub(target, agent.pos));
|
||||
if (dist > agent.sightRange) return false;
|
||||
const hit = world.raycastFirst(agent.pos, dir);
|
||||
return !hit || hit.t >= dist - 0.01;
|
||||
}
|
||||
```
|
||||
|
||||
### 7. WebGPU compute-shader raycast
|
||||
```wgsl
|
||||
@compute @workgroup_size(64)
|
||||
fn cs_raycast(@builtin(global_invocation_id) id: vec3u) {
|
||||
let ray = rays[id.x];
|
||||
var t_min = 1e30;
|
||||
var hit_idx = -1;
|
||||
for (var i = 0u; i < tri_count; i++) {
|
||||
let t = ray_triangle(ray, tris[i]);
|
||||
if (t > 0.0 && t < t_min) { t_min = t; hit_idx = i32(i); }
|
||||
}
|
||||
results[id.x] = Hit(t_min, hit_idx);
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| < 1k triangles | Naive Three.js raycaster 충분 |
|
||||
| 1k-100k triangles | three-mesh-bvh (BVH on CPU) |
|
||||
| 100k-10M, dynamic | refit BVH per frame + worker |
|
||||
| 10M+ static | WebGPU compute + GPU BVH |
|
||||
| Voxel world (Minecraft-ish) | DDA / Amanatides-Woo (매 grid traversal) |
|
||||
| AR placement | WebXR hit-test API (매 system-provided) |
|
||||
|
||||
**기본값**: Three.js + three-mesh-bvh 매 web 의 standard. 매 dynamic 매 BVH refit. 매 GPU compute 매 last resort.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Computational Geometry]] · [[Computer Graphics]]
|
||||
- 응용: [[Collision Detection]]
|
||||
- Adjacent: [[KD-Tree]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 3D scene 매 user input mapping (click/touch/AR). 매 line-of-sight / occlusion query. 매 sweep collision 1-shot.
|
||||
**언제 X**: 매 2D UI hit-test (DOM event 매 충분). 매 dense per-pixel intersection — 매 GPU rasterization 매 더 fast.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 frame 의 brute-force intersect 모든 triangle**: 매 100k tri scene 매 60fps 의 X — 매 BVH 필수.
|
||||
- **BVH refit 의 X 매 dynamic mesh**: 매 stale tree → 매 missed hits.
|
||||
- **Far plane 무시**: 매 무한 ray 매 매 distant unimportant geom hit.
|
||||
- **Ray direction 매 unnormalized**: 매 t value 매 distance 의 X — 매 모든 distance compare 매 broken.
|
||||
- **Single-precision float 의 self-intersection**: 매 origin offset (`+ 0.001 * normal`) 매 epsilon 처리.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Möller-Trumbore 1997 paper, Three.js 2026 source, three-mesh-bvh 0.7+).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Möller-Trumbore + BVH + WebXR hit-test + WebGPU compute |
|
||||
@@ -0,0 +1,167 @@
|
||||
---
|
||||
id: wiki-2026-0508-remote-rehabilitation
|
||||
title: Remote Rehabilitation
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [telerehabilitation, telerehab, digital rehabilitation]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [rehabilitation, telehealth, devops, monitoring, healthtech]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: nextjs-supabase-webrtc
|
||||
---
|
||||
|
||||
# Remote Rehabilitation
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 clinic 의 walls 의 dissolving — 매 patient 의 home 의 becoming 의 PT studio"**. Remote rehabilitation (telerehab) 의 PT/OT/cognitive therapy 의 delivering 의 video, sensors, gamified exercises 의 via. 2026 의 standard care 의 stroke recovery, post-op orthopedics, chronic pain — 매 reimbursement (CPT 98975-98981) 의 mainstream 의 making.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 modalities
|
||||
- **Synchronous**: 매 live video PT session — 매 therapist 의 form correction 의 real-time.
|
||||
- **Asynchronous**: 매 patient 의 records exercise 의 video 의, 매 therapist 의 reviews 의 later.
|
||||
- **RPM (Remote Patient Monitoring)**: 매 wearables 의 ROM, gait, HR 의 streaming 의 dashboard 의.
|
||||
- **DTx (Digital Therapeutics)**: 매 prescription apps — 매 Akili EndeavorRx, 매 Pear reSET (deprecated).
|
||||
|
||||
### 매 tech stack 의 typical
|
||||
- **Video**: WebRTC (Daily, Twilio Video, Zoom SDK) — 매 HIPAA BAA 의 require.
|
||||
- **Pose estimation**: MediaPipe Pose, 매 Apple Vision Pro Body Tracking, 매 Google ML Kit.
|
||||
- **Wearables**: Apple Watch, Whoop, IMU patches (BioStamp).
|
||||
- **Backend**: FHIR R5 의 EHR integration 의, 매 HL7 Bulk Data API.
|
||||
|
||||
### 매 응용
|
||||
1. 매 stroke recovery — 매 mirror therapy 의 VR 의.
|
||||
2. 매 post-ACL 의 ROM tracking 의 IMU 의.
|
||||
3. 매 chronic low back pain 의 Hinge Health-style 의 daily exercises.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Pose-based form scoring (MediaPipe + TS)
|
||||
```typescript
|
||||
import { PoseLandmarker, FilesetResolver } from '@mediapipe/tasks-vision';
|
||||
|
||||
const vision = await FilesetResolver.forVisionTasks(
|
||||
'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10/wasm'
|
||||
);
|
||||
const pose = await PoseLandmarker.createFromOptions(vision, {
|
||||
baseOptions: { modelAssetPath: '/pose_landmarker_full.task' },
|
||||
runningMode: 'VIDEO',
|
||||
numPoses: 1,
|
||||
});
|
||||
|
||||
function squatDepthScore(landmarks: any[]): number {
|
||||
const hip = landmarks[24], knee = landmarks[26], ankle = landmarks[28];
|
||||
const angle = Math.atan2(hip.y - knee.y, hip.x - knee.x) -
|
||||
Math.atan2(ankle.y - knee.y, ankle.x - knee.x);
|
||||
const deg = Math.abs((angle * 180) / Math.PI);
|
||||
return deg < 90 ? 1.0 : Math.max(0, 1 - (deg - 90) / 30);
|
||||
}
|
||||
```
|
||||
|
||||
### WebRTC 의 HIPAA-compliant session 의
|
||||
```typescript
|
||||
import Daily from '@daily-co/daily-js';
|
||||
|
||||
const call = Daily.createCallObject({
|
||||
audioSource: true,
|
||||
videoSource: true,
|
||||
dailyConfig: { useDevicePreferenceCookies: true },
|
||||
});
|
||||
await call.join({
|
||||
url: signedRoomUrl, // server-issued, BAA-covered
|
||||
token: patientJWT,
|
||||
});
|
||||
call.on('recording-started', (e) => logToFHIR(e.recordingId, encounterId));
|
||||
```
|
||||
|
||||
### IMU streaming 의 ROM tracking
|
||||
```typescript
|
||||
const device = await navigator.bluetooth.requestDevice({
|
||||
filters: [{ services: ['battery_service', 'heart_rate'] }],
|
||||
optionalServices: ['0000fff0-0000-1000-8000-00805f9b34fb'],
|
||||
});
|
||||
const server = await device.gatt!.connect();
|
||||
const svc = await server.getPrimaryService('0000fff0-0000-1000-8000-00805f9b34fb');
|
||||
const ch = await svc.getCharacteristic('0000fff1-0000-1000-8000-00805f9b34fb');
|
||||
await ch.startNotifications();
|
||||
ch.addEventListener('characteristicvaluechanged', (e: any) => {
|
||||
const dv = e.target.value as DataView;
|
||||
const quat = [dv.getFloat32(0), dv.getFloat32(4), dv.getFloat32(8), dv.getFloat32(12)];
|
||||
pushROM(quaternionToEulerDeg(quat));
|
||||
});
|
||||
```
|
||||
|
||||
### FHIR Observation 의 exercise log
|
||||
```typescript
|
||||
const obs = {
|
||||
resourceType: 'Observation',
|
||||
status: 'final',
|
||||
category: [{ coding: [{ system: 'http://terminology.hl7.org/CodeSystem/observation-category', code: 'activity' }] }],
|
||||
code: { coding: [{ system: 'http://loinc.org', code: '82290-8', display: 'ROM knee flexion' }] },
|
||||
subject: { reference: `Patient/${patientId}` },
|
||||
effectiveDateTime: new Date().toISOString(),
|
||||
valueQuantity: { value: maxFlexionDeg, unit: 'deg', system: 'http://unitsofmeasure.org' },
|
||||
};
|
||||
await fetch(`${FHIR_BASE}/Observation`, { method: 'POST', headers, body: JSON.stringify(obs) });
|
||||
```
|
||||
|
||||
### Adherence nudging (server cron)
|
||||
```typescript
|
||||
export default async (req: Request) => {
|
||||
const { data: due } = await sb
|
||||
.from('patients')
|
||||
.select('id, phone, plan_id')
|
||||
.lt('last_session_at', new Date(Date.now() - 86400_000).toISOString());
|
||||
await Promise.all(
|
||||
due!.map((p) => twilio.messages.create({
|
||||
to: p.phone,
|
||||
from: TWILIO_FROM,
|
||||
body: '오늘 의 5분 의 PT routine 의 done?',
|
||||
}))
|
||||
);
|
||||
return new Response('ok');
|
||||
};
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| post-acute stroke | hybrid (sync video 2x/wk + async daily) |
|
||||
| chronic pain (>3mo) | async-first DTx (Hinge, Sword) |
|
||||
| post-op week 1-2 | sync-heavy + RPM continuous |
|
||||
| medicare reimbursement 의 target | RTM/RPM (CPT 98975-77 + 98980-81) |
|
||||
|
||||
**기본값**: hybrid sync+async + IMU/wearable RPM, FHIR-backed.
|
||||
|
||||
## 🔗 Graph
|
||||
- 변형: [[Pose Estimation]]
|
||||
- 응용: [[Stroke Recovery]]
|
||||
- Adjacent: [[WebRTC]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: exercise plan generation, session note summarization, patient-facing Q&A (with guardrails).
|
||||
**언제 X**: clinical diagnosis, dosage decisions, medical advice 의 unsupervised 의.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Consumer Zoom 사용**: BAA 없음 — HIPAA violation.
|
||||
- **PHI 의 client-side log**: console.log 의 patient name — 매 audit fail.
|
||||
- **Pose model 의 cloud-only**: latency >200ms — 매 form correction 의 useless.
|
||||
- **Adherence ignore**: 매 70%+ patients drop off by week 3 — nudging 없으면 ROI zero.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (CMS RTM/RPM 2025 final rule, Hinge Health 의 BMJ 2024 RCT, MediaPipe Pose docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — telerehab tech stack + FHIR/WebRTC/pose patterns |
|
||||
@@ -0,0 +1,146 @@
|
||||
---
|
||||
id: wiki-2026-0508-sast
|
||||
title: SAST
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Static Application Security Testing, static analysis, source code analysis]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [security, sast, devsecops, static-analysis, ci-cd]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: multi
|
||||
framework: semgrep-codeql-snyk
|
||||
---
|
||||
|
||||
# SAST
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 source 의 reading 없이 의 running"**. SAST (Static Application Security Testing) 의 source code, bytecode, binary 의 의 inspecting 의 vulnerabilities 의 detecting 의 — 매 runtime 의 없이. 2026 의 dominant tools: Semgrep (rule-based, fast), CodeQL (semantic, deep), Snyk Code (DeepCode AI).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 SAST 의 기본 mechanics
|
||||
- **AST/CFG/DFG**: source 의 parse → AST → control-flow graph → data-flow graph.
|
||||
- **Taint analysis**: 매 source (user input) → sink (sql query) 의 path 의 trace.
|
||||
- **Pattern matching**: 매 known anti-pattern (e.g., `eval(req.body)`) 의 detect.
|
||||
- **Symbolic execution** (heavy): 매 path constraints 의 SMT solver 의 — 매 CodeQL.
|
||||
|
||||
### 매 modern tools 의 비교
|
||||
- **Semgrep** (2026): YAML rules, 매 fast (CI-friendly), 매 OSS + Pro (Semgrep Code).
|
||||
- **CodeQL** (GitHub): semantic queries, 매 deep — 매 GitHub Advanced Security 에 free for OSS.
|
||||
- **Snyk Code**: AI-augmented (DeepCode), 매 fast, 매 commercial.
|
||||
- **SonarQube**: code quality + security 의 hybrid.
|
||||
|
||||
### 매 응용
|
||||
1. PR-blocking gate (block-on-high).
|
||||
2. Pre-commit (fast subset).
|
||||
3. Nightly full scan + Jira issue 의 auto-create.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Semgrep custom rule (taint TS)
|
||||
```yaml
|
||||
rules:
|
||||
- id: dangerous-eval-from-request
|
||||
languages: [typescript, javascript]
|
||||
severity: ERROR
|
||||
message: 매 user input 의 eval 의 — RCE 위험
|
||||
mode: taint
|
||||
pattern-sources:
|
||||
- pattern-either:
|
||||
- pattern: req.body
|
||||
- pattern: req.query
|
||||
- pattern: req.params
|
||||
pattern-sinks:
|
||||
- pattern-either:
|
||||
- pattern: eval(...)
|
||||
- pattern: new Function(...)
|
||||
```
|
||||
|
||||
### GitHub Actions — Semgrep CI
|
||||
```yaml
|
||||
name: SAST
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
semgrep:
|
||||
runs-on: ubuntu-latest
|
||||
container: returntocorp/semgrep
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: semgrep ci --config=p/owasp-top-ten --config=.semgrep/
|
||||
env:
|
||||
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
```
|
||||
|
||||
### CodeQL query 의 hardcoded secret
|
||||
```ql
|
||||
import javascript
|
||||
|
||||
from StringLiteral s
|
||||
where s.getValue().regexpMatch("AKIA[0-9A-Z]{16}")
|
||||
select s, "매 hardcoded AWS key 의 detected"
|
||||
```
|
||||
|
||||
### Pre-commit hook — fast subset
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
changed=$(git diff --cached --name-only --diff-filter=ACMR | grep -E '\.(ts|tsx|js|py)$')
|
||||
[ -z "$changed" ] && exit 0
|
||||
echo "$changed" | xargs semgrep --config=p/security-audit --error
|
||||
```
|
||||
|
||||
### SARIF upload 의 GitHub code scanning 의
|
||||
```yaml
|
||||
- run: semgrep ci --sarif --output=semgrep.sarif || true
|
||||
- uses: github/codeql-action/upload-sarif@v3
|
||||
with: { sarif_file: semgrep.sarif }
|
||||
```
|
||||
|
||||
### Triage — false positive 의 suppress 의
|
||||
```typescript
|
||||
// nosemgrep: dangerous-eval-from-request
|
||||
// 매 reason: input 의 zod-validated 의 already
|
||||
const result = eval(safeMath); // ok
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| OSS project, 매 fast feedback | Semgrep (free OSS rules) |
|
||||
| GitHub repo, 매 deep semantic | CodeQL (GHAS) |
|
||||
| polyglot enterprise | Snyk Code or SonarQube |
|
||||
| custom org rules 의 heavy | Semgrep Pro |
|
||||
|
||||
**기본값**: Semgrep (PR gate, p/owasp-top-ten) + CodeQL (nightly, scheduled).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[CI/CD Pipeline & IDE Security Integration|DevSecOps]] · [[Application Security]]
|
||||
- 변형: [[보안 및 시스템 신뢰성 표준|DAST]] · [[IAST]] · [[SCA_Fundamentals|SCA]]
|
||||
- 응용: [[보안 및 시스템 신뢰성 표준|OWASP Top 10]] · [[Secure SDLC]]
|
||||
- Adjacent: [[CodeQL]] · [[Semgrep]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: triaging findings, generating fix PRs (Copilot Autofix style), writing custom rules from natural language.
|
||||
**언제 X**: trusting AI-only triage 없이 의 human review — 매 false positives 여전히 30-50%.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Block-on-everything**: medium severity 의 PR block — devs 의 SAST 의 disable 의.
|
||||
- **No suppression hygiene**: `nosemgrep` 의 reason 없이 spammed.
|
||||
- **Tool-only**: SAST 만 — DAST/SCA 없으면 runtime + dependency 의 blind.
|
||||
- **Scan once a quarter**: 매 finding backlog 의 explode.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Semgrep Registry 2026, GitHub CodeQL docs, OWASP SAST guide).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Semgrep/CodeQL 의 modern SAST patterns |
|
||||
@@ -0,0 +1,155 @@
|
||||
---
|
||||
id: wiki-2026-0508-sre
|
||||
title: SRE
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Site Reliability Engineering, production engineering]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [sre, reliability, slo, observability, devops]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: multi
|
||||
framework: prometheus-grafana-opentelemetry
|
||||
---
|
||||
|
||||
# SRE
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 reliability 의 feature 의 — 매 first feature 의"**. SRE (Site Reliability Engineering) 의 Google-originated discipline 의 software engineering 의 ops 의 applying. 핵심: SLOs 의 define, error budgets 의 enforce, toil 의 eliminate, blameless postmortems.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 SRE 의 핵심 의 concepts
|
||||
- **SLI**: 매 measurement (e.g., 200-OK rate over 5min).
|
||||
- **SLO**: 매 target (e.g., 99.9% over 28d rolling).
|
||||
- **SLA**: 매 customer contract (with $ penalty).
|
||||
- **Error budget**: 매 100% - SLO. 매 budget 의 burn 시 release freeze.
|
||||
|
||||
### 매 four golden signals (Google)
|
||||
- Latency, Traffic, Errors, Saturation.
|
||||
|
||||
### 매 응용
|
||||
1. SLO-driven alerting (multi-window burn rate).
|
||||
2. Toil budget (≤50% of SRE time).
|
||||
3. Blameless postmortem culture.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Prometheus SLO recording rules
|
||||
```yaml
|
||||
groups:
|
||||
- name: slo.rules
|
||||
interval: 30s
|
||||
rules:
|
||||
- record: api:availability:ratio_rate5m
|
||||
expr: |
|
||||
sum(rate(http_requests_total{job="api",code!~"5.."}[5m]))
|
||||
/ sum(rate(http_requests_total{job="api"}[5m]))
|
||||
- record: api:availability:ratio_rate1h
|
||||
expr: |
|
||||
sum(rate(http_requests_total{job="api",code!~"5.."}[1h]))
|
||||
/ sum(rate(http_requests_total{job="api"}[1h]))
|
||||
```
|
||||
|
||||
### Multi-window multi-burn-rate alert
|
||||
```yaml
|
||||
- alert: ApiErrorBudgetFastBurn
|
||||
expr: |
|
||||
(1 - api:availability:ratio_rate5m) > (14.4 * 0.001)
|
||||
and
|
||||
(1 - api:availability:ratio_rate1h) > (14.4 * 0.001)
|
||||
for: 2m
|
||||
labels: { severity: page }
|
||||
annotations:
|
||||
summary: "Fast burn — 매 2% budget 의 1h 의 consume 의"
|
||||
```
|
||||
|
||||
### OpenTelemetry instrumentation (Node)
|
||||
```typescript
|
||||
import { NodeSDK } from '@opentelemetry/sdk-node';
|
||||
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
||||
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
||||
|
||||
new NodeSDK({
|
||||
traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_ENDPOINT }),
|
||||
instrumentations: [getNodeAutoInstrumentations()],
|
||||
}).start();
|
||||
```
|
||||
|
||||
### Runbook automation (Python)
|
||||
```python
|
||||
import kubernetes.client as k8s
|
||||
def remediate(pod_name: str, ns: str):
|
||||
api = k8s.CoreV1Api()
|
||||
api.delete_namespaced_pod(pod_name, ns)
|
||||
notify_slack(f"매 auto-restart {ns}/{pod_name} (high mem)")
|
||||
```
|
||||
|
||||
### Postmortem template
|
||||
```markdown
|
||||
# Incident YYYY-MM-DD: <title>
|
||||
**Status**: resolved
|
||||
**Impact**: <users affected, $ lost, duration>
|
||||
**Severity**: SEV-2
|
||||
|
||||
## Timeline (UTC)
|
||||
- 14:02 alert fired
|
||||
- 14:05 oncall paged
|
||||
- 14:18 root cause identified
|
||||
- 14:31 mitigated
|
||||
|
||||
## Root Cause
|
||||
<technical>
|
||||
|
||||
## Action Items
|
||||
- [ ] (P0) Fix race in checkout-svc — owner: @x
|
||||
- [ ] (P1) Add SLO alert for queue depth — owner: @y
|
||||
```
|
||||
|
||||
### Toil tracking
|
||||
```typescript
|
||||
type Toil = { repetitive: boolean; manual: boolean; automatable: boolean; ts: Date };
|
||||
// dashboard: toil hours / total hours per quarter, target ≤50%
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | SLO |
|
||||
|---|---|
|
||||
| user-facing read API | 99.9% availability, p99 <300ms |
|
||||
| user-facing write API | 99.95% availability, p99 <500ms |
|
||||
| internal batch | 99.5% job completion within window |
|
||||
| free-tier feature | 99% (lower budget = ship faster) |
|
||||
|
||||
**기본값**: 99.9% availability, multi-burn-rate alerts, weekly error-budget review.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[DevOps]] · [[Production Engineering]]
|
||||
- 변형: [[Platform Engineering]] · [[CI/CD Pipeline & IDE Security Integration|DevSecOps]]
|
||||
- 응용: [[Observability]] · [[Chaos Engineering]]
|
||||
- Adjacent: [[Prometheus]] · [[OpenTelemetry]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: postmortem drafting from timeline, log anomaly summarization, runbook generation, oncall question answering.
|
||||
**언제 X**: auto-remediation 의 LLM-only — 매 hallucinated kubectl 의 prod 의 destroy.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **No SLO**: 매 alert noise — 매 every blip 의 page.
|
||||
- **100% uptime goal**: 매 unattainable, 매 budget 0 = no innovation.
|
||||
- **Blame culture**: postmortem 의 finger-pointing — engineers 의 hide incidents.
|
||||
- **Toil unbounded**: SREs 의 burned out — quit within 12mo.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Google SRE Book, SRE Workbook, Prometheus docs, Sloth SLO generator).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — SLO + burn-rate + OTel patterns |
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
id: wiki-2026-0508-scavenge
|
||||
title: Scavenge
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Minor GC, Scavenger, Young Generation GC, Cheney Scavenger]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [v8, garbage-collection, memory, runtime]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: cpp
|
||||
framework: v8-orinoco
|
||||
---
|
||||
|
||||
# Scavenge
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 young object 의 매 빠른 die — 매 cheap 하게 collect"**. Scavenge 는 매 generational hypothesis (most objects die young) 의 매 exploit — 매 V8 young generation 을 매 from-space / to-space 로 나누고 매 live object 만 매 to-space 로 매 copy. 매 dead object 는 매 단순 abandon. 2026 V8 (Orinoco) 에서 매 parallel + concurrent 로 매 main-thread pause < 1ms.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Cheney's algorithm
|
||||
1. Allocate in to-space (linear bump pointer).
|
||||
2. When full → 매 swap roles. From-space = 매 old to-space.
|
||||
3. From roots, copy 매 reachable object to (new) to-space.
|
||||
4. Update 매 forwarding pointer in from-space slot.
|
||||
5. BFS through copied objects, copying 매 referenced objects.
|
||||
6. Done → from-space 매 entirely abandoned.
|
||||
|
||||
### 매 V8-specific
|
||||
- Young gen = New Space ≈ 1–8 MB per worker.
|
||||
- Promotion: 매 survives 2 scavenges → 매 Old Space.
|
||||
- Parallel Scavenge (2018+): 매 multiple threads.
|
||||
- Concurrent (2021+): root marking on background.
|
||||
|
||||
### 매 응용
|
||||
1. JS heap young gen.
|
||||
2. Java HotSpot Young Generation (Parallel Scavenge collector).
|
||||
3. .NET Gen 0/1.
|
||||
4. Erlang per-process heap.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Cheney scavenge (pseudo-C)
|
||||
```c
|
||||
typedef struct { intptr_t header; void* slots[]; } Object;
|
||||
char *from, *to, *alloc;
|
||||
|
||||
void* scavenge_copy(Object *obj) {
|
||||
if (is_forwarded(obj)) return forwarded_addr(obj);
|
||||
size_t size = obj_size(obj);
|
||||
Object *copy = (Object*)alloc;
|
||||
memcpy(copy, obj, size);
|
||||
alloc += size;
|
||||
set_forwarded(obj, copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void scavenge() {
|
||||
swap(&from, &to);
|
||||
alloc = to;
|
||||
char *scan = to;
|
||||
for (Root *r = roots; r; r = r->next) *r = scavenge_copy(*r);
|
||||
while (scan < alloc) {
|
||||
Object *o = (Object*)scan;
|
||||
for (int i = 0; i < slot_count(o); i++)
|
||||
o->slots[i] = scavenge_copy(o->slots[i]);
|
||||
scan += obj_size(o);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Allocation (bump pointer)
|
||||
```c
|
||||
void* alloc_young(size_t bytes) {
|
||||
if (alloc + bytes > to_end) trigger_scavenge();
|
||||
void *p = alloc;
|
||||
alloc += bytes;
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
### Promotion check
|
||||
```c
|
||||
if (obj_age(o) >= 2) {
|
||||
void *promoted = alloc_old(obj_size(o));
|
||||
memcpy(promoted, o, obj_size(o));
|
||||
// also update remembered set if old → young pointers exist
|
||||
} else {
|
||||
scavenge_copy(o);
|
||||
inc_age(o);
|
||||
}
|
||||
```
|
||||
|
||||
### Remembered set (write barrier)
|
||||
```c
|
||||
void store_field(Object *obj, int slot, Object *val) {
|
||||
obj->slots[slot] = val;
|
||||
if (in_old_space(obj) && in_young_space(val))
|
||||
remembered_set_add(&obj->slots[slot]);
|
||||
}
|
||||
```
|
||||
|
||||
### V8 trace (observe scavenge)
|
||||
```bash
|
||||
node --trace-gc app.js
|
||||
# [12345:0x...] 100 ms: Scavenge 5.5 (6.7) -> 4.8 (7.7) MB, 0.4 / 0.0 ms
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Strategy |
|
||||
|---|---|
|
||||
| 매 short-lived alloc heavy | Larger young gen (--max-semi-space-size) |
|
||||
| 매 long-lived heavy | Smaller young, faster promotion |
|
||||
| 매 latency-critical | Concurrent scavenge enabled |
|
||||
| 매 throughput | Parallel scavenge |
|
||||
|
||||
**기본값**: V8 default — auto-tuned per workload.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Garbage Collection]] · [[V8 Engine]]
|
||||
- 변형: [[Mark-Sweep-Compact]] · [[Major GC]]
|
||||
- 응용: [[New Space(Young Generation)]] · [[Cheneys Algorithm]]
|
||||
- Adjacent: [[Orinoco GC]] · [[Stop-the-world]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: GC log analysis, allocation hotspot identification from heap snapshots, write-barrier overhead estimation.
|
||||
**언제 X**: 매 actual GC algorithm change — runtime team only.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Massive young alloc + immediate retain**: 매 promotion storm → 매 old space pressure.
|
||||
- **Linked list of small objects**: 매 scan cost 의 매 linear in slots → 매 use TypedArray.
|
||||
- **Disabling GC**: 매 --no-gc — 매 memory grows unbounded.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (V8 Orinoco docs, Cheney 1970 paper, "The Garbage Collection Handbook" 2nd Ed.).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Cheney + V8 Orinoco parallel-concurrent state |
|
||||
@@ -0,0 +1,168 @@
|
||||
---
|
||||
id: wiki-2026-0508-secret-management
|
||||
title: Secret Management
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Secrets Management, Credential Management, Vault]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [security, devsecops, credentials, kms]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: multi
|
||||
framework: vault-aws-kms
|
||||
---
|
||||
|
||||
# Secret Management
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 secret 은 매 git 에 절대 — 매 vault 에"**. Secret management 는 매 API key, DB password, certificate, signing key 의 매 lifecycle (issue, store, rotate, revoke, audit) 의 매 centralized control. 2026 현재 매 HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager, Doppler, Infisical 가 매 dominant; 매 SPIFFE/SPIRE workload identity, 매 short-lived (15min) tokens 가 매 long-lived API key 를 매 replace.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Anti-secrets
|
||||
- Hardcoded in source.
|
||||
- Plain in `.env` committed.
|
||||
- Shared via Slack DM.
|
||||
- Long-lived (years) static API keys.
|
||||
|
||||
### 매 Pillars
|
||||
- **Encryption at rest**: KMS-backed.
|
||||
- **Encryption in transit**: TLS-only.
|
||||
- **Access control**: RBAC + audit log.
|
||||
- **Rotation**: automated (DB pwd, KMS key).
|
||||
- **Workload identity**: 매 service ≠ user — 매 ephemeral token 의 매 cloud IAM.
|
||||
- **Detection**: 매 git pre-commit (gitleaks, trufflehog) + 매 GitHub secret scanning.
|
||||
|
||||
### 매 응용
|
||||
1. App → DB: dynamic creds.
|
||||
2. CI → cloud: OIDC federation, no static keys.
|
||||
3. K8s pod → AWS: IRSA / Workload Identity.
|
||||
4. Cross-service: SPIFFE SVID.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Vault dynamic DB cred
|
||||
```bash
|
||||
vault write database/roles/app-readonly \
|
||||
db_name=postgres-prod \
|
||||
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
|
||||
default_ttl=1h max_ttl=24h
|
||||
|
||||
# App requests cred
|
||||
vault read database/creds/app-readonly
|
||||
# username: v-token-app-readonly-x9a..., password: A1b2C3..., lease_id: ..., lease_duration: 3600
|
||||
```
|
||||
|
||||
### GitHub Actions OIDC → AWS (no static keys)
|
||||
```yaml
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::123:role/github-deploy
|
||||
aws-region: us-east-1
|
||||
- run: aws s3 sync ./build s3://prod-bucket/
|
||||
```
|
||||
|
||||
### Pre-commit secret scan
|
||||
```yaml
|
||||
# .pre-commit-config.yaml
|
||||
repos:
|
||||
- repo: https://github.com/gitleaks/gitleaks
|
||||
rev: v8.18.0
|
||||
hooks:
|
||||
- id: gitleaks
|
||||
```
|
||||
|
||||
### App-side fetch with caching
|
||||
```typescript
|
||||
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
|
||||
const sm = new SecretsManagerClient({});
|
||||
const cache = new Map<string, { value: any; expires: number }>();
|
||||
|
||||
async function getSecret(name: string): Promise<any> {
|
||||
const cached = cache.get(name);
|
||||
if (cached && cached.expires > Date.now()) return cached.value;
|
||||
const res = await sm.send(new GetSecretValueCommand({ SecretId: name }));
|
||||
const value = JSON.parse(res.SecretString!);
|
||||
cache.set(name, { value, expires: Date.now() + 5 * 60_000 });
|
||||
return value;
|
||||
}
|
||||
```
|
||||
|
||||
### K8s External Secrets Operator
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata: { name: db-creds }
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef: { name: vault-backend, kind: ClusterSecretStore }
|
||||
target: { name: db-creds }
|
||||
data:
|
||||
- secretKey: password
|
||||
remoteRef: { key: database/creds/app, property: password }
|
||||
```
|
||||
|
||||
### Rotation Lambda
|
||||
```typescript
|
||||
export async function rotateApiKey(event) {
|
||||
const step = event.Step;
|
||||
if (step === "createSecret") {
|
||||
const newKey = await crypto.randomUUID();
|
||||
await sm.putSecretValue({ SecretId: event.SecretId, ClientRequestToken: event.ClientRequestToken, SecretString: newKey, VersionStages: ["AWSPENDING"] });
|
||||
} else if (step === "setSecret") { /* configure target */ }
|
||||
else if (step === "testSecret") { /* test */ }
|
||||
else if (step === "finishSecret") {
|
||||
await sm.updateSecretVersionStage({ SecretId: event.SecretId, VersionStage: "AWSCURRENT", MoveToVersionId: event.ClientRequestToken });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Tool |
|
||||
|---|---|
|
||||
| 매 multi-cloud, 매 self-host | HashiCorp Vault |
|
||||
| 매 AWS-only | Secrets Manager + Parameter Store |
|
||||
| 매 dev-friendly UX | Doppler / Infisical |
|
||||
| 매 K8s | External Secrets Operator + cloud KMS |
|
||||
| 매 workload-to-workload | SPIFFE/SPIRE |
|
||||
|
||||
**기본값**: Cloud-native (Secrets Manager) + OIDC for CI + ESO for K8s.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[DevSecOps_Framework]] · [[Application Security]]
|
||||
- 변형: [[KMS]] · [[PKI]]
|
||||
- 응용: [[CI_CD_Pipeline]] · [[보안 및 시스템 신뢰성 표준|Zero-Trust Architecture]]
|
||||
- Adjacent: [[보안 및 시스템 신뢰성 표준|OWASP Top 10]] · [[OAuth 2.0]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Secret-scanner triage (매 actual secret vs 매 test fixture?), rotation runbook generation, IAM policy synthesis from natural-language requirement.
|
||||
**언제 X**: 매 secret 자체를 매 LLM context 에 매 넣지 마. 매 leak risk.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **`.env` in git**: 매 even private repo — 매 contributor leak.
|
||||
- **Long-lived keys**: 매 5-year IAM access key — 매 incident blast-radius huge.
|
||||
- **Shared service account**: 매 audit trail 의 매 useless.
|
||||
- **Plain ENV var visible to all containers**: 매 sidecar / multi-tenant — 매 leak.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (NIST SP 800-57, OWASP ASVS V6, CIS Benchmarks).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — OIDC federation + workload identity 2026 |
|
||||
@@ -0,0 +1,160 @@
|
||||
---
|
||||
id: wiki-2026-0508-session-lifecycle
|
||||
title: Session Lifecycle
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Session Management, Session State, Login Session]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [security, web, authentication, session]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: nextjs-redis
|
||||
---
|
||||
|
||||
# Session Lifecycle
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 user 의 매 authenticated state 의 매 birth → death"**. Session lifecycle 는 매 login 으로 매 시작, 매 idle/absolute timeout 또는 매 explicit logout 으로 매 끝. 2026 현재 매 stateless JWT 의 매 short-lived access token (15 min) + 매 stateful refresh token (rotating, server-revocable) 의 매 hybrid 가 매 dominant; 매 OWASP ASVS V3 가 매 baseline.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 Phases
|
||||
1. **Auth**: credential verify (password, MFA, passkey).
|
||||
2. **Issue**: session token (cookie / JWT) + binding (UA, IP optional).
|
||||
3. **Validate**: per-request check + refresh.
|
||||
4. **Refresh**: rotation on each use.
|
||||
5. **Terminate**: logout, idle (15-30min), absolute (12-24h), forced (admin, breach).
|
||||
|
||||
### 매 Token strategies
|
||||
- **Stateful (DB session)**: server stores; revocable instantly; scale via Redis.
|
||||
- **Stateless JWT**: signed token; revocation via short TTL or blocklist.
|
||||
- **Hybrid**: short JWT access + opaque refresh in DB.
|
||||
|
||||
### 매 Cookie attributes
|
||||
- `HttpOnly` — XSS protection.
|
||||
- `Secure` — TLS only.
|
||||
- `SameSite=Lax` (or Strict) — CSRF.
|
||||
- `__Host-` prefix — domain lock.
|
||||
- `Path=/` and reasonable `Max-Age`.
|
||||
|
||||
### 매 응용
|
||||
1. Web SPA + cookie session.
|
||||
2. Mobile app + refresh-token rotation.
|
||||
3. SSO (SAML/OIDC) federated.
|
||||
4. Service mesh (mTLS-based).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Cookie session (Express + Redis)
|
||||
```typescript
|
||||
import session from "express-session";
|
||||
import RedisStore from "connect-redis";
|
||||
app.use(session({
|
||||
store: new RedisStore({ client: redis, prefix: "sess:" }),
|
||||
secret: process.env.SESSION_SECRET!,
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: {
|
||||
httpOnly: true, secure: true, sameSite: "lax",
|
||||
maxAge: 30 * 60_000, // idle timeout via touch
|
||||
},
|
||||
rolling: true,
|
||||
}));
|
||||
```
|
||||
|
||||
### JWT access + rotating refresh
|
||||
```typescript
|
||||
function issueTokens(userId: string) {
|
||||
const access = jwt.sign({ sub: userId }, ACCESS_SECRET, { expiresIn: "15m" });
|
||||
const refresh = crypto.randomUUID();
|
||||
redis.set(`refresh:${refresh}`, userId, "EX", 60 * 60 * 24 * 14);
|
||||
return { access, refresh };
|
||||
}
|
||||
async function rotate(oldRefresh: string) {
|
||||
const userId = await redis.get(`refresh:${oldRefresh}`);
|
||||
if (!userId) throw new Error("invalid");
|
||||
await redis.del(`refresh:${oldRefresh}`); // single-use
|
||||
return issueTokens(userId);
|
||||
}
|
||||
```
|
||||
|
||||
### Idle + absolute timeout
|
||||
```typescript
|
||||
type Session = { userId: string; createdAt: number; lastSeenAt: number };
|
||||
const ABSOLUTE = 24 * 3600_000;
|
||||
const IDLE = 30 * 60_000;
|
||||
|
||||
function valid(s: Session): boolean {
|
||||
const now = Date.now();
|
||||
return now - s.createdAt < ABSOLUTE && now - s.lastSeenAt < IDLE;
|
||||
}
|
||||
```
|
||||
|
||||
### Global logout (token version)
|
||||
```typescript
|
||||
// User table column: tokenVersion (incremented on logout-everywhere)
|
||||
const access = jwt.sign({ sub: user.id, ver: user.tokenVersion }, SECRET);
|
||||
// On verify
|
||||
if (decoded.ver !== currentUser.tokenVersion) throw new Error("revoked");
|
||||
```
|
||||
|
||||
### Session hijack defense (binding)
|
||||
```typescript
|
||||
function bindClaims(req: Request) {
|
||||
return crypto.createHash("sha256")
|
||||
.update(req.headers["user-agent"] + req.ip).digest("hex");
|
||||
}
|
||||
// On issue: store. On validate: compare. Mismatch → require re-auth.
|
||||
```
|
||||
|
||||
### Concurrent session limit
|
||||
```typescript
|
||||
const sessions = await redis.smembers(`user_sessions:${userId}`);
|
||||
if (sessions.length >= 5) {
|
||||
const oldest = sessions[0];
|
||||
await redis.del(`sess:${oldest}`);
|
||||
await redis.srem(`user_sessions:${userId}`, oldest);
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 Web SPA, 매 same domain | Cookie + CSRF token |
|
||||
| 매 mobile / cross-origin | JWT access + refresh in secure storage |
|
||||
| 매 high-security (banking) | Short access (5m) + step-up auth |
|
||||
| 매 SSO required | OIDC + IdP-managed session |
|
||||
|
||||
**기본값**: HttpOnly Secure SameSite=Lax cookie + Redis-backed session, 30m idle / 24h absolute.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Application Security]]
|
||||
- 변형: [[JWT]] · [[OAuth 2.0]]
|
||||
- 응용: [[보안 및 시스템 신뢰성 표준|OWASP Top 10]] · [[보안 및 시스템 신뢰성 표준|Zero-Trust Architecture]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: Session anomaly detection (매 sudden geo / device shift), suspicious-activity summary for support.
|
||||
**언제 X**: 매 token issuance / signing — 매 deterministic crypto only.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **localStorage JWT**: 매 XSS → 매 token theft. 매 HttpOnly cookie.
|
||||
- **No refresh rotation**: 매 leaked refresh = 매 forever access.
|
||||
- **No absolute timeout**: 매 1년 session — 매 dormant account hijack.
|
||||
- **Client-side only check**: 매 every request server-side.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (OWASP Session Management Cheat Sheet, ASVS V3, NIST SP 800-63B).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — JWT+refresh hybrid + passkey-era state |
|
||||
@@ -0,0 +1,190 @@
|
||||
---
|
||||
id: wiki-2026-0508-single-page-applications-spa
|
||||
title: Single Page Applications (SPA)
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [SPA, Single-Page App, Client-Side App]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [web, frontend, architecture, routing]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript
|
||||
framework: React/Vue/SvelteKit
|
||||
---
|
||||
|
||||
# Single Page Applications (SPA)
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 한 HTML 의 모든 view 의 client-side 의 render"**. SPA 매 initial load 후 server-fetch 의 X 의 navigation — 매 data-only API call. 2026 매 SPA-only 의 declining trend — 매 SSR/RSC hybrid (Next.js 15, Remix, Astro Islands) 의 mainstream.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 핵심 Architecture
|
||||
- 매 single `index.html` shell.
|
||||
- 매 JS bundle 의 view rendering (React / Vue / Svelte).
|
||||
- Client-side routing (History API).
|
||||
- 매 API 의 JSON fetch — REST / GraphQL / tRPC.
|
||||
|
||||
### 매 Pros
|
||||
- 매 fluid navigation — 매 page reload X.
|
||||
- 매 rich interactivity.
|
||||
- 매 backend / frontend 분리 — 매 separate deploy.
|
||||
|
||||
### 매 Cons
|
||||
- Initial bundle size — 매 large.
|
||||
- SEO 의 challenge — 매 crawler 의 JS execution 의존.
|
||||
- TTI (Time to Interactive) 의 slow.
|
||||
- 매 JS-disabled / network-fail 의 blank screen.
|
||||
|
||||
### 매 vs MPA / SSR / SSG
|
||||
- MPA: server 의 매 page-by-page render.
|
||||
- SSR: 매 first render 의 server, 매 hydrate 후 SPA-like.
|
||||
- SSG: 매 build-time 의 pre-render — 매 static deploy.
|
||||
- RSC (React Server Components): 매 server/client 의 component-level mix.
|
||||
|
||||
### 매 2026 trend
|
||||
- 매 pure SPA 의 niche (admin panel, internal tool).
|
||||
- Next.js / Remix / SvelteKit 의 hybrid 의 default.
|
||||
- Astro Islands — 매 partial hydration.
|
||||
- 매 streaming SSR + Suspense — 매 perceived perf 개선.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### React Router v7 — 매 client-side routing
|
||||
```tsx
|
||||
import { createBrowserRouter, RouterProvider } from "react-router";
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{ path: "/", element: <Home /> },
|
||||
{ path: "/posts/:id", element: <Post />, loader: postLoader },
|
||||
{ path: "*", element: <NotFound /> },
|
||||
]);
|
||||
|
||||
export default function App() {
|
||||
return <RouterProvider router={router} />;
|
||||
}
|
||||
```
|
||||
|
||||
### History API — manual SPA navigation
|
||||
```typescript
|
||||
function navigate(url: string) {
|
||||
history.pushState({}, "", url);
|
||||
render(); // re-render based on location.pathname
|
||||
}
|
||||
|
||||
window.addEventListener("popstate", render);
|
||||
```
|
||||
|
||||
### Code splitting — 매 route-level lazy
|
||||
```tsx
|
||||
import { lazy, Suspense } from "react";
|
||||
|
||||
const Dashboard = lazy(() => import("./Dashboard"));
|
||||
|
||||
<Suspense fallback={<Spinner />}>
|
||||
<Dashboard />
|
||||
</Suspense>
|
||||
```
|
||||
|
||||
### Data fetching — TanStack Query
|
||||
```typescript
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
function Post({ id }: { id: string }) {
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["post", id],
|
||||
queryFn: () => fetch(`/api/posts/${id}`).then(r => r.json()),
|
||||
staleTime: 60_000,
|
||||
});
|
||||
|
||||
if (isLoading) return <Skeleton />;
|
||||
return <Article {...data} />;
|
||||
}
|
||||
```
|
||||
|
||||
### Vite — SPA build
|
||||
```typescript
|
||||
// vite.config.ts
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
vendor: ["react", "react-dom"],
|
||||
ui: ["@radix-ui/react-dialog"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### SPA fallback — server config (nginx)
|
||||
```nginx
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
```
|
||||
|
||||
### Skeleton + optimistic UI
|
||||
```tsx
|
||||
const mutation = useMutation({
|
||||
mutationFn: postComment,
|
||||
onMutate: async (newComment) => {
|
||||
await queryClient.cancelQueries({ queryKey: ["comments"] });
|
||||
const prev = queryClient.getQueryData(["comments"]);
|
||||
queryClient.setQueryData(["comments"], (old: any) => [...old, newComment]);
|
||||
return { prev };
|
||||
},
|
||||
onError: (_, __, ctx) => queryClient.setQueryData(["comments"], ctx.prev),
|
||||
});
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Public marketing site | SSG (Astro / Next static) — 매 SPA X. |
|
||||
| Content blog | SSG / ISR. |
|
||||
| SaaS dashboard (auth-walled) | SPA OK — 매 SEO 의 X 필요. |
|
||||
| E-commerce | SSR/RSC — 매 SEO + perceived perf. |
|
||||
| Internal admin tool | SPA — Vite + React Router. |
|
||||
| Rich realtime app | SPA + WebSocket. |
|
||||
|
||||
**기본값**: 매 새 project 의 Next.js / Remix / SvelteKit (hybrid). 매 pure SPA 의 internal tool 만.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Web Architecture]]
|
||||
- 변형: [[MPA]] · [[SSR]] · [[SSG]] · [[Islands Architecture]]
|
||||
- 응용: [[SvelteKit]]
|
||||
- Adjacent: [[Code Splitting]] · [[Hydration]] · [[Service Worker]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 auth-walled rich app — admin, dashboard, realtime collaborative tool.
|
||||
**언제 X**: 매 SEO-critical / content-heavy site — 매 SSR/SSG 의 사용.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 SEO-critical site 의 pure SPA**: 매 crawler 문제 → SSR/SSG.
|
||||
- **매 huge initial bundle (no code-split)**: TTI 악화.
|
||||
- **매 in-memory routing 의 history API X**: 매 back-button 의 X.
|
||||
- **매 server fallback (try_files) 의 X**: 매 deep-link refresh 의 404.
|
||||
- **매 every state 의 Redux**: 매 over-engineering — TanStack Query + local useState.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (MDN Web Docs, React Router v7 docs).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — SPA arch + 2026 hybrid trend 정리 |
|
||||
@@ -0,0 +1,151 @@
|
||||
---
|
||||
id: wiki-2026-0508-skinnedmesh
|
||||
title: SkinnedMesh
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-1189F7, Skinned Mesh, GPU Skinning]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.93
|
||||
verification_status: applied
|
||||
tags: [3d, graphics, animation, threejs, webgl]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript
|
||||
framework: Three.js / WebGL2
|
||||
---
|
||||
|
||||
# SkinnedMesh
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 mesh 의 vertex 가 매 bone weight 에 의해 deformed — single draw call 의 articulated character"**. 1990s SGI/PowerAnimator 의 skinning 매 origin → 2026 GPU compute shader 매 thousands-of-bones 매 real-time. Three.js `SkinnedMesh` 매 WebGPU compute path 매 standard.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 구성 요소
|
||||
- **Mesh geometry**: vertex position + skin index (4 bones/vertex 매 typical) + skin weight.
|
||||
- **Skeleton**: bone hierarchy + bind matrix (rest pose inverse).
|
||||
- **Bone matrices**: world-space transform 매 per-bone, GPU 의 uniform buffer / data texture 의 upload.
|
||||
|
||||
### 매 GPU pipeline
|
||||
- Vertex shader 의 매 vertex 의 bone matrices 의 weighted blend 의 적용 → world-space pos.
|
||||
- Linear Blend Skinning (LBS) 매 default — 매 fast, 매 candy-wrapper artifact 의 risk.
|
||||
- Dual Quaternion Skinning (DQS) 매 alternative — 매 volume-preserving, 매 ~1.3x cost.
|
||||
|
||||
### 매 응용
|
||||
1. Character animation (게임, AR/VR avatar).
|
||||
2. Cloth/soft-body 의 partial rigging.
|
||||
3. Procedural creature 의 spline-driven bones.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Three.js 매 SkinnedMesh 생성
|
||||
```ts
|
||||
import * as THREE from 'three';
|
||||
|
||||
const geometry = new THREE.CylinderGeometry(0.3, 0.3, 4, 8, 8);
|
||||
// skinIndex / skinWeight buffer 의 attach
|
||||
const skinIndices: number[] = [];
|
||||
const skinWeights: number[] = [];
|
||||
for (let i = 0; i < geometry.attributes.position.count; i++) {
|
||||
const y = geometry.attributes.position.getY(i) + 2; // 0..4
|
||||
const skinIndex = Math.floor(y);
|
||||
const skinWeight = y - skinIndex;
|
||||
skinIndices.push(skinIndex, skinIndex + 1, 0, 0);
|
||||
skinWeights.push(1 - skinWeight, skinWeight, 0, 0);
|
||||
}
|
||||
geometry.setAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4));
|
||||
geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4));
|
||||
|
||||
// Bone hierarchy
|
||||
const bones: THREE.Bone[] = [];
|
||||
for (let i = 0; i <= 4; i++) {
|
||||
const b = new THREE.Bone();
|
||||
b.position.y = i === 0 ? -2 : 1;
|
||||
if (i > 0) bones[i - 1].add(b);
|
||||
bones.push(b);
|
||||
}
|
||||
const skeleton = new THREE.Skeleton(bones);
|
||||
|
||||
const mesh = new THREE.SkinnedMesh(geometry, new THREE.MeshStandardMaterial({ skinning: true } as any));
|
||||
mesh.add(bones[0]);
|
||||
mesh.bind(skeleton);
|
||||
```
|
||||
|
||||
### 매 GLTF asset 매 load
|
||||
```ts
|
||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
||||
const loader = new GLTFLoader();
|
||||
const gltf = await loader.loadAsync('/models/character.glb');
|
||||
const skinned = gltf.scene.getObjectByProperty('isSkinnedMesh', true) as THREE.SkinnedMesh;
|
||||
const mixer = new THREE.AnimationMixer(skinned);
|
||||
const action = mixer.clipAction(gltf.animations[0]);
|
||||
action.play();
|
||||
```
|
||||
|
||||
### 매 GPU instancing 매 SkinnedMesh — `BatchedMesh` + skeleton texture
|
||||
```ts
|
||||
// 2026 Three.js r170+ 의 InstancedSkinnedMesh
|
||||
const inst = new THREE.InstancedSkinnedMesh(geometry, material, 1000);
|
||||
inst.boundingSphere = new THREE.Sphere(new THREE.Vector3(), 5);
|
||||
// 매 per-instance 의 별도 skeleton bone matrix texture 의 upload
|
||||
```
|
||||
|
||||
### 매 LBS 매 vertex shader (GLSL)
|
||||
```glsl
|
||||
mat4 skinMatrix =
|
||||
skinWeight.x * boneMatrix(skinIndex.x) +
|
||||
skinWeight.y * boneMatrix(skinIndex.y) +
|
||||
skinWeight.z * boneMatrix(skinIndex.z) +
|
||||
skinWeight.w * boneMatrix(skinIndex.w);
|
||||
vec4 skinned = skinMatrix * vec4(position, 1.0);
|
||||
gl_Position = projectionMatrix * modelViewMatrix * skinned;
|
||||
```
|
||||
|
||||
### 매 bone matrix 의 DataTexture 매 upload (large skeleton)
|
||||
```ts
|
||||
const boneTexture = new THREE.DataTexture(
|
||||
new Float32Array(bones.length * 16),
|
||||
bones.length * 4, 1, THREE.RGBAFormat, THREE.FloatType,
|
||||
);
|
||||
skeleton.boneTexture = boneTexture; // automatically updated
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Character < 256 bones, 단일 instance | uniform array bone matrices |
|
||||
| Character ≥ 256 bones, 매 mobile 의 uniform limit 의 hit | `boneTexture` (DataTexture) |
|
||||
| 매 large crowd (100+ chars) | `InstancedSkinnedMesh` + 매 per-instance skeleton texture |
|
||||
| 매 volume-preserving 의 deformation 의 필요 | DQS or 매 corrective shape keys |
|
||||
| 매 simple twist 매 only | Bend modifier or 매 spline-IK 의 fallback |
|
||||
|
||||
**기본값**: GLTF + Three.js `SkinnedMesh` + LBS + `boneTexture` 의 mobile path.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Three.js]] · [[WebGL 20|WebGL2]]
|
||||
- Adjacent: [[BufferGeometry]] · [[BatchedMesh 및 InstancedMesh 성능 벤치마크]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: GLTF rigged character 의 import, 매 bone weight 의 painting 의 review, 매 skinning artifact 의 debug.
|
||||
**언제 X**: 매 static prop 의 transform — `Mesh` + matrix update 의 더 cheap.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 vertex 별 매 8+ bone weight**: GPU 매 4-weight 의 standard. Excess bones 의 normalize + drop low-weight 의 필요.
|
||||
- **매 frame 별 `skeleton.update()` 의 manual call**: Three.js 매 already 매 auto. Redundant 의 cost.
|
||||
- **매 bone matrix 의 CPU-side recompute** 매 frame: bone hierarchy 의 dirty flag 의 활용.
|
||||
- **`SkinnedMesh.clone()` 의 후 매 same skeleton 의 share**: 매 separate `Skeleton.clone()` 의 필요 — else 매 모든 instances 매 같은 pose.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Three.js docs r170, Khronos glTF 2.0 spec, Real-Time Rendering 4e Ch.4).
|
||||
- 신뢰도 A.
|
||||
- 중복 risk: [[GPU Skinning]] (alias).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — SkinnedMesh의 components, GPU pipeline, instancing 정리 |
|
||||
@@ -0,0 +1,150 @@
|
||||
---
|
||||
id: wiki-2026-0508-solitude-optimization
|
||||
title: Solitude Optimization
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [single-tenant optimization, dedicated-instance tuning, isolation tuning]
|
||||
duplicate_of: none
|
||||
source_trust_level: B
|
||||
confidence_score: 0.75
|
||||
verification_status: applied
|
||||
tags: [performance, isolation, multi-tenant, devops, optimization]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: multi
|
||||
framework: kubernetes-firecracker-cgroups
|
||||
---
|
||||
|
||||
# Solitude Optimization
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 noisy neighbor 의 quiet 의 making"**. Solitude optimization 의 single-tenant / dedicated-isolation workloads 의 의 performance / cost 의 tuning 의 — 매 multi-tenant 의 sharing economy 의 step away. 2026 의 use-cases: HIPAA/SOC2 silo tenants, ML training pods, latency-critical RTC.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 isolation 의 levels
|
||||
- **Process** (cgroups, Linux namespaces): 매 weak.
|
||||
- **VM** (KVM, Firecracker microVM): 매 strong, 매 ms-boot.
|
||||
- **Bare metal**: 매 strongest, 매 slowest provisioning.
|
||||
- **Confidential computing** (SEV-SNP, TDX): 매 memory encryption, 매 even cloud admin 못 read.
|
||||
|
||||
### 매 cost 의 vs noise tradeoff
|
||||
- pool: 매 cheapest, 매 noisy.
|
||||
- silo VM: 매 2-5x cost, 매 quiet + auditable.
|
||||
- bare metal: 매 5-10x, 매 silent + compliance-friendly.
|
||||
|
||||
### 매 응용
|
||||
1. Top-N enterprise tenants 의 dedicated DB instance.
|
||||
2. ML training 의 dedicated GPU node (no neighbor jitter).
|
||||
3. Real-time audio/video 의 dedicated compute pool.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Kubernetes node 의 dedicated taint
|
||||
```yaml
|
||||
kubectl label node gpu-node-1 tenant=acme dedicated=true
|
||||
kubectl taint nodes gpu-node-1 dedicated=acme:NoSchedule
|
||||
|
||||
# pod spec
|
||||
spec:
|
||||
nodeSelector: { tenant: acme }
|
||||
tolerations:
|
||||
- key: dedicated
|
||||
operator: Equal
|
||||
value: acme
|
||||
effect: NoSchedule
|
||||
```
|
||||
|
||||
### CPU pinning + isolated cores
|
||||
```yaml
|
||||
# kubelet --reserved-cpus=0-1, --cpu-manager-policy=static
|
||||
spec:
|
||||
containers:
|
||||
- name: rtc
|
||||
resources:
|
||||
requests: { cpu: "4", memory: "8Gi" }
|
||||
limits: { cpu: "4", memory: "8Gi" }
|
||||
```
|
||||
|
||||
### Firecracker microVM (per-tenant)
|
||||
```bash
|
||||
firectl --kernel ./vmlinux --root-drive ./tenant-rootfs.ext4 \
|
||||
--cpu-template T2 --vcpu-count 2 --memory 1024 \
|
||||
--tap-device tap-acme/AA:FC:00:00:00:01
|
||||
```
|
||||
|
||||
### Postgres 의 logical replica 의 silo upgrade
|
||||
```sql
|
||||
CREATE PUBLICATION acme_pub FOR TABLE invoices, users WHERE (tenant_id='acme-uuid');
|
||||
-- on dedicated instance:
|
||||
CREATE SUBSCRIPTION acme_sub CONNECTION '...' PUBLICATION acme_pub;
|
||||
```
|
||||
|
||||
### Redis — dedicated DB index per VIP tenant
|
||||
```typescript
|
||||
const dbIdx = tenant.tier === 'enterprise' ? tenantToDb[tenant.id] : 0;
|
||||
const r = new Redis({ host, port, db: dbIdx });
|
||||
```
|
||||
|
||||
### Network egress 의 per-tenant bandwidth shape (tc)
|
||||
```bash
|
||||
tc qdisc add dev eth0 root handle 1: htb default 30
|
||||
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit
|
||||
tc filter add dev eth0 protocol ip parent 1:0 prio 1 \
|
||||
u32 match ip src 10.244.5.7/32 flowid 1:1
|
||||
```
|
||||
|
||||
### NUMA-aware 의 ML pod
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
spec:
|
||||
containers:
|
||||
- name: trainer
|
||||
resources:
|
||||
requests:
|
||||
cpu: "16"
|
||||
memory: "64Gi"
|
||||
nvidia.com/gpu: "1"
|
||||
limits:
|
||||
cpu: "16"
|
||||
memory: "64Gi"
|
||||
nvidia.com/gpu: "1"
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Isolation |
|
||||
|---|---|
|
||||
| HIPAA enterprise customer | silo (dedicated DB + node taint) |
|
||||
| ML training, p99 jitter < 5ms | dedicated GPU node + CPU pin |
|
||||
| RTC audio/video VIPs | dedicated pool, NUMA-pinned |
|
||||
| free-tier | pool (cgroups only) |
|
||||
|
||||
**기본값**: pool with QoS-Guaranteed for paid tiers, silo upgrade option for enterprise SLA.
|
||||
|
||||
## 🔗 Graph
|
||||
- 응용: [[Firecracker]]
|
||||
- Adjacent: [[SaaS]] · [[SLO]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: tier-tradeoff explanation to sales, capacity planning, generating taint/toleration manifests.
|
||||
**언제 X**: auto-migrating tenants pool→silo 의 unchecked — 매 cutover 의 careful orchestration 필요.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Silo by default**: 매 cost balloon — pool 의 enough for 95% tenants.
|
||||
- **No QoS class**: BestEffort pods 의 prod 의 — 매 OOMKill victims.
|
||||
- **Dedicated 의 sold w/o SLO uplift**: 매 customer 의 perceived value 0.
|
||||
- **Forget the data plane**: CPU silo 의 했지만 shared NIC/Disk — 매 noise 여전.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Kubernetes CPU Manager, Firecracker docs, AWS Nitro/SEV-SNP, Postgres logical rep).
|
||||
- 신뢰도 B (term "solitude optimization" 의 niche; 매 industry 표준 용어 의 multi-tenancy isolation tuning).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — isolation/silo patterns + microVM + NUMA |
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
id: wiki-2026-0508-source-control
|
||||
title: Source Control
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [version control, VCS, git workflow]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [git, version-control, devops, workflow, collaboration]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: shell
|
||||
framework: git-github-jujutsu
|
||||
---
|
||||
|
||||
# Source Control
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 commit 의 atomic unit of intent"**. Source control (VCS) 의 code changes 의 의 history 의 record 의, 매 collaboration / rollback / branching 의 의 enable 의. 2026 의 dominant 의 git, 매 emerging: Jujutsu (jj) 의 ergonomic next-gen, 매 Sapling (Meta).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 git 의 mental model
|
||||
- **Snapshot**, not diffs. 매 commit 의 tree (file content hashes) 의 reference.
|
||||
- **Three trees**: working dir, index (stage), HEAD.
|
||||
- **Refs**: branches, tags, HEAD 의 commit pointers.
|
||||
- **Object store**: blobs, trees, commits, tags — content-addressed (SHA-1/SHA-256).
|
||||
|
||||
### 매 modern workflows
|
||||
- **Trunk-based**: short-lived branches (<24h), main 의 always deployable.
|
||||
- **GitHub Flow**: feature branch → PR → merge to main.
|
||||
- **GitFlow** (legacy): heavy 의 develop/release/hotfix branches — 매 2026 의 거의 not 추천.
|
||||
|
||||
### 매 응용
|
||||
1. Trunk-based + feature flags (modern PLG SaaS).
|
||||
2. Stacked PRs (Graphite, Sapling) for big changes.
|
||||
3. Monorepo (Nx, Turborepo, Bazel).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Conventional commits + commitlint
|
||||
```js
|
||||
module.exports = {
|
||||
extends: ['@commitlint/config-conventional'],
|
||||
rules: {
|
||||
'type-enum': [2, 'always', ['feat','fix','chore','docs','refactor','test','perf','build','ci']],
|
||||
'scope-empty': [2, 'never'],
|
||||
'subject-max-length': [2, 'always', 72],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Pre-push hook (husky)
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
pnpm test --run && pnpm lint
|
||||
```
|
||||
|
||||
### Squash-merge default + linear history
|
||||
```bash
|
||||
gh repo edit OWNER/REPO \
|
||||
--enable-squash-merge --enable-rebase-merge=false --enable-merge-commit=false \
|
||||
--delete-branch-on-merge
|
||||
```
|
||||
|
||||
### Stacked PRs (Graphite)
|
||||
```bash
|
||||
gt branch create feat-foundation
|
||||
gt branch create feat-api
|
||||
gt submit --stack
|
||||
```
|
||||
|
||||
### Bisect 매 regression
|
||||
```bash
|
||||
git bisect start
|
||||
git bisect bad HEAD
|
||||
git bisect good v2.3.0
|
||||
git bisect run pnpm test:e2e:smoke
|
||||
git bisect reset
|
||||
```
|
||||
|
||||
### Rerere 의 conflict 의 reuse
|
||||
```bash
|
||||
git config --global rerere.enabled true
|
||||
```
|
||||
|
||||
### Worktrees 의 parallel branches
|
||||
```bash
|
||||
git worktree add ../proj-hotfix hotfix/v2.3.1
|
||||
git worktree remove ../proj-hotfix
|
||||
```
|
||||
|
||||
### Sparse-checkout (monorepo)
|
||||
```bash
|
||||
git sparse-checkout init --cone
|
||||
git sparse-checkout set apps/web packages/ui
|
||||
```
|
||||
|
||||
### Signed commits (sigstore gitsign)
|
||||
```bash
|
||||
gitsign init
|
||||
git -c commit.gpgsign=true commit -m "feat: thing"
|
||||
gitsign verify HEAD --certificate-identity=me@org.com \
|
||||
--certificate-oidc-issuer=https://accounts.google.com
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Workflow |
|
||||
|---|---|
|
||||
| SaaS startup, daily deploy | trunk-based + feature flags |
|
||||
| OSS library | GitHub Flow + protected main |
|
||||
| regulated (releases) | release branches + CHANGELOG |
|
||||
| monorepo of apps | trunk-based + Nx affected + sparse |
|
||||
|
||||
**기본값**: trunk-based, squash-merge, conventional commits, signed commits (gitsign), CODEOWNERS-protected main.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[DevOps]]
|
||||
- 응용: [[Trunk-Based Development]] · [[Code Review]] · [[Monorepo]]
|
||||
- Adjacent: [[CODEOWNERS]] · [[Conventional Commits]] · [[GitOps]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: commit message generation, PR description drafts, conflict resolution suggestions, blame summarization.
|
||||
**언제 X**: rebasing 의 LLM-driven 의 unchecked — 매 history 의 corrupt 위험.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Long-lived feature branches** (>1wk): 매 merge hell.
|
||||
- **Force-push to shared branches**: 매 teammates' work 의 destroy.
|
||||
- **Big-bang commits**: 매 review impossible, bisect useless.
|
||||
- **No CODEOWNERS**: 매 누구나 의 critical path 의 merge.
|
||||
- **Secrets in history**: 매 even after rotation, 매 forever exposed.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Pro Git book, GitHub flow docs, Trunk-Based Development site, Conventional Commits 1.0).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — git workflow + stacked PR + sigstore patterns |
|
||||
@@ -0,0 +1,137 @@
|
||||
---
|
||||
id: wiki-2026-0508-speculative-execution
|
||||
title: Speculative Execution
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-CCED4D, Branch Speculation, Out-of-order Execution]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [cpu, microarchitecture, security, performance, spectre]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: C / asm
|
||||
framework: x86-64 / ARMv9
|
||||
---
|
||||
|
||||
# Speculative Execution
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 CPU 의 매 branch 의 outcome 의 wait 의 X — 매 predicted path 의 의 ahead 의 execute, 매 wrong → rollback"**. 1990s Pentium Pro 매 first commercial impl → 2018 Spectre/Meltdown 매 the dark side 의 reveal → 2026 매 hardware mitigation (Intel CET, ARM BTI/MTE) + compiler hardening 매 standard.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 mechanism
|
||||
- **Branch predictor** 매 매 branch 의 taken/not-taken 의 history 의 학습 (TAGE, Perceptron).
|
||||
- **Reorder buffer (ROB)** 매 매 speculative instruction 의 in-flight 의 hold.
|
||||
- **Retire stage** 매 매 branch 의 resolved 의 후 의 commit (correct) or flush (mispredict).
|
||||
- **Misprediction penalty**: 매 modern CPU 매 ~15-25 cycles.
|
||||
|
||||
### 매 dark side
|
||||
- **Spectre v1 (Bounds Check Bypass)**: 매 attacker 의 branch predictor 의 train → 매 sensitive memory 의 cache 의 leak.
|
||||
- **Spectre v2 (Branch Target Injection)**: 매 indirect branch 의 mispredict 의 force.
|
||||
- **Meltdown**: 매 user 의 kernel memory 의 speculative read.
|
||||
- **L1TF, MDS, Retbleed, GhostRace** (2018-2024): 매 variant 의 endless.
|
||||
|
||||
### 매 응용
|
||||
1. CPU performance (1.5-3x IPC vs in-order).
|
||||
2. Branch prediction research.
|
||||
3. Compiler 매 PGO + autovectorization 의 enabler.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Pattern 1: 매 Spectre v1 매 PoC (educational)
|
||||
```c
|
||||
// 매 educational only
|
||||
uint8_t array1[16] = {0};
|
||||
uint8_t array2[256 * 512];
|
||||
char* secret = "key";
|
||||
unsigned int array1_size = 16;
|
||||
|
||||
void victim(size_t x) {
|
||||
if (x < array1_size) { // <-- 매 trained branch
|
||||
uint8_t v = array2[array1[x] * 512];
|
||||
// 매 cache 의 leak via timing
|
||||
}
|
||||
}
|
||||
// Attacker 매 array1_size 의 cache 의 evict → speculative path 매 OOB read
|
||||
```
|
||||
|
||||
### Pattern 2: 매 LFENCE / 매 retpoline 의 mitigation
|
||||
```c
|
||||
// gcc -mindirect-branch=thunk-extern -mfunction-return=thunk-extern
|
||||
static inline void speculation_barrier(void) {
|
||||
__asm__ volatile ("lfence" ::: "memory");
|
||||
}
|
||||
|
||||
bool safe_lookup(size_t i, size_t n, uint8_t* arr) {
|
||||
if (i < n) {
|
||||
speculation_barrier(); // 매 stops speculative path
|
||||
return arr[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 3: 매 bench 의 branch misprediction
|
||||
```c
|
||||
// perf stat -e branches,branch-misses ./a.out
|
||||
#include <stdio.h>
|
||||
int main(int argc, char** argv) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
if (i % 2 == 0) sum += i; // 매 100% predictable
|
||||
// if ((rand() & 1)) sum += i; // 매 50% miss → much slower
|
||||
}
|
||||
printf("%d\n", sum);
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 4: 매 V8 / JIT 의 speculative optimization
|
||||
```js
|
||||
// V8 매 hidden class 의 speculatively assume → 매 type 의 change → 매 deopt
|
||||
function add(o) { return o.x + o.y; }
|
||||
add({ x: 1, y: 2 }); // 매 monomorphic, JIT 의 specialize
|
||||
add({ x: 1, y: 2, z: 3 }); // 매 hidden class 의 change → 매 deopt
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 user code 매 typical app | 매 default — speculation 매 win, 매 mitigation OS-level |
|
||||
| 매 cryptography (constant-time req) | `LFENCE`, branchless code, 매 secret-dep 의 branch X |
|
||||
| 매 multi-tenant cloud | site-isolation, hardware mitigation enable, microcode update |
|
||||
| 매 perf-critical hot loop | Profile-guided opt + branchless when miss > 5% |
|
||||
| 매 indirect call hot path | retpoline (Spectre v2) + IBRS off if isolated |
|
||||
|
||||
**기본값**: 매 OS + microcode 의 latest, 매 crypto code 매 constant-time, 매 hot-loop 매 PGO.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[CPU Bottleneck]] · [[Branch Prediction]]
|
||||
- 변형: [[Out-of-order Execution]]
|
||||
- 응용: [[V8 Engine]] · [[Spectre]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 perf 분석 (branch-miss rate), 매 microbenchmark 의 design, 매 mitigation flag 의 trade-off 분석.
|
||||
**언제 X**: 매 actual exploit 의 development — out of scope.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 secret-dependent branch** 매 crypto code — 매 timing leak.
|
||||
- **매 mitigation 의 disable** ("for performance") 매 multi-tenant host.
|
||||
- **매 indirect call 의 hot loop** without retpoline 매 Spectre v2-vulnerable CPU.
|
||||
- **매 unpredictable branch** 매 inner loop — 매 branchless (cmov, mask) 의 prefer.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Hennessy & Patterson 6e Ch.3, Spectre paper Kocher 2018, Intel SDM Vol.3 Ch.2).
|
||||
- 신뢰도 A.
|
||||
- 중복 risk: [[Branch Prediction]] (related), [[Out-of-order Execution]] (parent mechanism).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — mechanism, Spectre family, mitigations 정리 |
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
id: wiki-2026-0508-statistics-data-analysis
|
||||
title: "Statistics & Data Analysis"
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [stats, data analysis, applied statistics]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [statistics, data-analysis, ab-testing, ml, observability]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: python
|
||||
framework: numpy-scipy-statsmodels-pymc
|
||||
---
|
||||
|
||||
# Statistics & Data Analysis
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 data 의 lying 의 — 매 stats 의 catching"**. Statistics 의 uncertainty 의 quantify 의, 매 patterns 의 noise 의 separate 의 의 discipline. 2026 의 production 의 standard 의: Bayesian methods (PyMC, Stan), causal inference (DoWhy, EconML), CUPED 의 A/B test variance reduction.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 핵심 dichotomy
|
||||
- **Frequentist**: p-values, confidence intervals — 매 long-run frequency 의.
|
||||
- **Bayesian**: posteriors, credible intervals — 매 belief update 의.
|
||||
- **2026 trend**: Bayesian 의 production analytics 의 dominant (interpretable, sequential-safe).
|
||||
|
||||
### 매 must-know toolkit
|
||||
- **Hypothesis tests**: t-test, Mann-Whitney, χ², Fisher exact.
|
||||
- **Regression**: OLS, GLM (logistic, Poisson), mixed-effects.
|
||||
- **Causal**: difference-in-differences, IV, RDD, synthetic control.
|
||||
- **A/B**: CUPED, sequential testing (mSPRT), multi-armed bandits.
|
||||
|
||||
### 매 응용
|
||||
1. Product A/B testing (CUPED + sequential).
|
||||
2. SRE — anomaly detection on metrics.
|
||||
3. SAST/SCA findings 의 risk scoring (Bayesian prior).
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Welch t-test (A/B)
|
||||
```python
|
||||
import numpy as np
|
||||
from scipy import stats
|
||||
control = np.array([...])
|
||||
treatment = np.array([...])
|
||||
t, p = stats.ttest_ind(control, treatment, equal_var=False)
|
||||
ci = stats.t.interval(0.95, len(control)+len(treatment)-2,
|
||||
loc=treatment.mean()-control.mean(),
|
||||
scale=stats.sem(np.concatenate([control, treatment])))
|
||||
print(f"Δ={treatment.mean()-control.mean():.4f}, p={p:.4f}, 95%CI={ci}")
|
||||
```
|
||||
|
||||
### CUPED variance reduction
|
||||
```python
|
||||
import numpy as np
|
||||
def cuped_adjust(y_pre, y_post):
|
||||
theta = np.cov(y_pre, y_post)[0,1] / np.var(y_pre)
|
||||
return y_post - theta * (y_pre - y_pre.mean())
|
||||
y_adj_c = cuped_adjust(pre_c, post_c)
|
||||
y_adj_t = cuped_adjust(pre_t, post_t)
|
||||
```
|
||||
|
||||
### Bayesian A/B (PyMC)
|
||||
```python
|
||||
import pymc as pm
|
||||
with pm.Model() as m:
|
||||
p_a = pm.Beta('p_a', 1, 1)
|
||||
p_b = pm.Beta('p_b', 1, 1)
|
||||
pm.Binomial('obs_a', n=n_a, p=p_a, observed=k_a)
|
||||
pm.Binomial('obs_b', n=n_b, p=p_b, observed=k_b)
|
||||
pm.Deterministic('lift', (p_b - p_a) / p_a)
|
||||
idata = pm.sample(2000, tune=1000)
|
||||
print(f"P(B>A) = {(idata.posterior['lift']>0).mean().item():.3f}")
|
||||
```
|
||||
|
||||
### Sequential testing (mSPRT)
|
||||
```python
|
||||
import numpy as np
|
||||
def msprt(x, y, sigma2_tau=0.01, alpha=0.05):
|
||||
n = min(len(x), len(y))
|
||||
delta = y[:n] - x[:n]
|
||||
s2 = delta.var(ddof=1)
|
||||
t = delta.mean() * np.sqrt(n)
|
||||
lr = np.sqrt(s2/(s2+n*sigma2_tau)) * np.exp(
|
||||
n*sigma2_tau*t**2 / (2*s2*(s2+n*sigma2_tau)))
|
||||
return lr > 1/alpha
|
||||
```
|
||||
|
||||
### Causal — difference-in-differences (statsmodels)
|
||||
```python
|
||||
import statsmodels.formula.api as smf
|
||||
m = smf.ols('y ~ treated * post + C(unit) + C(time)', data=df).fit(
|
||||
cov_type='cluster', cov_kwds={'groups': df['unit']})
|
||||
print(m.params['treated:post'])
|
||||
```
|
||||
|
||||
### Anomaly — robust z (MAD)
|
||||
```python
|
||||
import numpy as np
|
||||
def mad_z(x):
|
||||
med = np.median(x)
|
||||
mad = np.median(np.abs(x - med))
|
||||
return 0.6745 * (x - med) / (mad + 1e-9)
|
||||
anomalies = np.abs(mad_z(latency_p99)) > 3.5
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Method |
|
||||
|---|---|
|
||||
| 2-arm online experiment, fixed N | Welch t-test + CUPED |
|
||||
| sequential / peeking 위험 | mSPRT or Bayesian |
|
||||
| many arms, exploration value | Thompson sampling bandit |
|
||||
| observational, treatment effect | DiD / IV / synthetic control |
|
||||
| heavy-tailed (revenue) | Mann-Whitney + bootstrap CI |
|
||||
|
||||
**기본값**: Welch + CUPED for online A/B; Bayesian for small-N or peeking; bootstrap for non-Gaussian.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Probability Theory]]
|
||||
- 변형: [[Bayesian Statistics]] · [[Causal Inference]]
|
||||
- 응용: [[Anomaly Detection]] · [[ML Evaluation]]
|
||||
- Adjacent: [[PyMC]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: experiment design review, p-value 해석, choosing test for distribution shape, generating PyMC models from descriptions.
|
||||
**언제 X**: trusting LLM-computed p-values 없이 의 verification — 매 arithmetic mistakes.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Peeking**: 매 fixed-N test 의 daily check 의 stop — 매 false positive rate 의 5% → 30%+.
|
||||
- **HARKing**: 매 hypothesis after results known.
|
||||
- **p<0.05 worship**: 매 effect size 무시.
|
||||
- **Ignoring multiple testing**: 매 20 metrics 의 →약 1 의 false positive 의 expected.
|
||||
- **CUPED 의 covariate 의 post-treatment 의**: 매 invalidates.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Microsoft CUPED paper 2013, Optimizely Stats Engine, Gelman BDA3, Wasserman All of Stats).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — A/B + Bayesian + causal patterns |
|
||||
@@ -0,0 +1,135 @@
|
||||
---
|
||||
id: wiki-2026-0508-stop-the-world
|
||||
title: Stop the world
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-D2D9B2, STW, GC pause, Stop-the-world]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [gc, runtime, performance, latency, jvm, v8]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: Java / JS / Go
|
||||
framework: HotSpot / V8 / Go runtime
|
||||
---
|
||||
|
||||
# Stop the world
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 GC + 매 mutator 의 동시 실행 매 X — 매 모든 application thread 의 freeze, 매 GC 의 reclaim 의 후 의 resume"**. 1960s LISP MTS GC 매 origin → 1990s incremental → 2010s concurrent → 2026 매 ZGC / Shenandoah / Go 1.5+ 의 sub-millisecond STW. 매 STW 매 매 latency 의 archenemy.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 왜 STW 의 필요
|
||||
- **Heap traversal consistency**: 매 mark phase 매 reference graph 의 stable 의 require — 매 mutator 매 concurrent write 의 invariant break.
|
||||
- **Root scanning**: 매 thread stack + 매 register 의 snapshot 의 atomic 매 collect.
|
||||
- **Pointer update**: 매 compacting GC 매 매 reference 의 rewrite 의 atomic 매 require.
|
||||
|
||||
### 매 STW phase
|
||||
- **Initial mark** (root scan) — 매 short.
|
||||
- **Final mark / remark** — 매 mutator 의 missed reference 의 catch-up.
|
||||
- **Reference processing** (weak/soft refs).
|
||||
- **Cleanup / class unloading**.
|
||||
|
||||
### 매 modern GC 의 STW
|
||||
- **HotSpot G1**: ~10-200ms (heap size 의 dependent).
|
||||
- **HotSpot ZGC** (JDK 21+): < 1ms 매 always (concurrent compaction).
|
||||
- **HotSpot Shenandoah**: < 10ms (Brooks pointers).
|
||||
- **Go runtime**: < 0.5ms (concurrent + tri-color + write barrier).
|
||||
- **V8 Orinoco**: < 1ms typical (parallel + concurrent + incremental).
|
||||
|
||||
### 매 응용
|
||||
1. SLO design (p99 latency budget).
|
||||
2. JVM tuning (heap + GC choice).
|
||||
3. Real-time / financial / game 의 latency-critical app.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Pattern 1: 매 JVM 의 STW 의 measure (GC log)
|
||||
```bash
|
||||
# Java 21+
|
||||
java -Xlog:gc*:file=gc.log:time,uptime,level,tags -Xmx4g -XX:+UseZGC App
|
||||
# 매 log 의 분석
|
||||
grep 'Pause' gc.log | awk '{print $NF}' | sort -n | tail
|
||||
```
|
||||
|
||||
### Pattern 2: 매 V8 의 GC pause 의 trace (Node.js)
|
||||
```bash
|
||||
node --trace-gc --trace-gc-verbose app.js
|
||||
# [12345:0x..] 1234 ms: Mark-sweep 64.5 (98.4) -> 32.1 (98.4) MB, 12.3 / 0.0 ms
|
||||
```
|
||||
|
||||
### Pattern 3: 매 Go 의 GODEBUG 의 STW trace
|
||||
```bash
|
||||
GODEBUG=gctrace=1 ./myapp
|
||||
# gc 1 @0.012s 0%: 0.012+0.36+0.005 ms clock, ...
|
||||
# ^^^^^ ^^^^^^^^ ^^^^^
|
||||
# STW init concurrent STW final
|
||||
```
|
||||
|
||||
### Pattern 4: 매 STW-aware code (allocation 의 reduce)
|
||||
```ts
|
||||
// V8 매 large allocation 매 LO space → mark-sweep 의 trigger
|
||||
// Hot path 매 매 allocation 의 minimize
|
||||
const buf = Buffer.allocUnsafe(1024); // reuse
|
||||
function process(data: Uint8Array): number {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < data.length; i++) sum += data[i]; // 매 no allocation
|
||||
return sum;
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 5: 매 production GC tuning (JVM)
|
||||
```bash
|
||||
# 매 SLO p99 < 50ms 매 latency-critical service
|
||||
java -Xmx8g -Xms8g \
|
||||
-XX:+UseZGC -XX:+ZGenerational \
|
||||
-XX:+UnlockExperimentalVMOptions \
|
||||
-XX:SoftMaxHeapSize=6g \
|
||||
-Xlog:gc*:file=gc.log \
|
||||
-jar app.jar
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Java batch / throughput | Parallel GC (longer STW OK) |
|
||||
| Java latency-critical (p99 < 50ms) | ZGC (JDK 21+) or Shenandoah |
|
||||
| Java legacy heap < 4G | G1 (default JDK 17+) |
|
||||
| Go service | runtime default — tune `GOGC` |
|
||||
| Node.js 매 long-lived process | `--max-old-space-size`, profile incremental marking |
|
||||
| 매 Hard real-time (audio, robotics) | manual memory mgmt — 매 GC 의 X (Rust, C++) |
|
||||
|
||||
**기본값**: 매 latency app — 매 ZGC (Java) / 매 default Go runtime / 매 V8 incremental.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[V8 가비지 컬렉션(Garbage Collection)]] · [[가비지 컬렉터(Garbage Collector)]]
|
||||
- 변형: [[Mark-Sweep-Compact(메이저 GC)]] · [[Major GC]] · [[Scavenge]]
|
||||
- 응용: [[V8 Engine]] · [[자바 가상 머신(JVM)]] · [[동시성 및 점진적 마킹(Concurrent Incremental Marking)]]
|
||||
- Adjacent: [[Memory Management]] · [[오리노코(Orinoco GC)]] · [[Cheneys Algorithm]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 GC log 의 parse + summarize, 매 STW outlier 의 root-cause hypothesis, 매 GC flag 의 trade-off 분석.
|
||||
**언제 X**: 매 production GC flag 의 LLM-only 의 decision — 매 load test 의 confirm 의 필요.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 GC 의 manual trigger** (`System.gc()`, `--expose-gc`) 매 production — 매 STW 의 force, 매 worse latency.
|
||||
- **매 huge heap** (-Xmx32g) + 매 G1 의 expectation 의 STW < 10ms — 매 G1 의 multi-GB heap 매 longer pause 의 inevitable, 매 ZGC 의 use.
|
||||
- **매 short-lived object 의 fixed pool 의 cache** — 매 generational GC 의 already 의 efficient. 매 over-engineering.
|
||||
- **매 GC log 의 production 의 disable** — 매 incident 의 post-mortem 의 impossible.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (HotSpot ZGC tuning guide JDK 21, Go runtime/mgc.go, V8 blog 'Orinoco' 2020-2024).
|
||||
- 신뢰도 A.
|
||||
- 중복 risk: [[Major GC]] (related phase), [[동시성 및 점진적 마킹(Concurrent Incremental Marking)]] (technique that 매 reduces STW).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — STW phases, modern GC pause budgets, tuning patterns 정리 |
|
||||
@@ -0,0 +1,155 @@
|
||||
---
|
||||
id: wiki-2026-0508-storybook
|
||||
title: Storybook
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [Storybook.js, Component Workshop, UI Sandbox]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [frontend, components, testing, design-system, react]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: TypeScript
|
||||
framework: Storybook 8 / React / Vue / Svelte
|
||||
---
|
||||
|
||||
# Storybook
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 component 의 isolated workshop — 매 visual catalog + 매 interaction test + 매 a11y 의 single source"**. 2016 React Storybook (Arunoda) → 2026 Storybook 8 매 Vite-first + Test 매 first-class + 매 Chromatic 매 visual regression. 매 design-system 매 매 매 indispensable.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 3 value
|
||||
- **Isolation**: 매 component 의 매 props/state 의 explore 매 app context 의 X.
|
||||
- **Documentation**: 매 stories 의 living spec — 매 Figma 의 ↔ 매 code 의 sync.
|
||||
- **Testing**: 매 visual regression (Chromatic), 매 interaction (`play` fn), 매 a11y (axe).
|
||||
|
||||
### 매 file structure
|
||||
- `Button.stories.tsx` 매 매 component 의 옆.
|
||||
- `meta` (component, args, argTypes, parameters) + 매 export 별 매 story.
|
||||
- CSF 3 (Component Story Format) 매 standard.
|
||||
|
||||
### 매 응용
|
||||
1. Design-system component library.
|
||||
2. Visual regression test (Chromatic / Loki).
|
||||
3. Designer ↔ engineer collaboration.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Pattern 1: 매 CSF 3 매 story
|
||||
```tsx
|
||||
// Button.stories.tsx
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { fn } from '@storybook/test';
|
||||
import { Button } from './Button';
|
||||
|
||||
const meta = {
|
||||
title: 'UI/Button',
|
||||
component: Button,
|
||||
args: { onClick: fn() },
|
||||
argTypes: {
|
||||
variant: { control: 'select', options: ['primary', 'secondary', 'ghost'] },
|
||||
size: { control: 'radio', options: ['sm', 'md', 'lg'] },
|
||||
},
|
||||
parameters: { layout: 'centered' },
|
||||
} satisfies Meta<typeof Button>;
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
export const Primary: Story = { args: { variant: 'primary', children: 'Save' } };
|
||||
export const Disabled: Story = { args: { variant: 'primary', disabled: true, children: 'Save' } };
|
||||
```
|
||||
|
||||
### Pattern 2: 매 interaction test (`play`)
|
||||
```tsx
|
||||
import { expect, userEvent, within } from '@storybook/test';
|
||||
|
||||
export const ClickIncrements: Story = {
|
||||
args: { children: 'Click me' },
|
||||
play: async ({ canvasElement, args }) => {
|
||||
const canvas = within(canvasElement);
|
||||
const btn = canvas.getByRole('button');
|
||||
await userEvent.click(btn);
|
||||
await userEvent.click(btn);
|
||||
expect(args.onClick).toHaveBeenCalledTimes(2);
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Pattern 3: 매 a11y addon
|
||||
```ts
|
||||
// .storybook/preview.ts
|
||||
import type { Preview } from '@storybook/react';
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
a11y: { config: { rules: [{ id: 'color-contrast', enabled: true }] } },
|
||||
},
|
||||
};
|
||||
export default preview;
|
||||
// 매 axe-core 매 매 story 매 자동 audit, panel 의 violation 의 surface
|
||||
```
|
||||
|
||||
### Pattern 4: 매 Chromatic 매 visual regression CI
|
||||
```yaml
|
||||
# .github/workflows/chromatic.yml
|
||||
- uses: chromaui/action@latest
|
||||
with:
|
||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
onlyChanged: true
|
||||
exitZeroOnChanges: false
|
||||
```
|
||||
|
||||
### Pattern 5: 매 design token 의 import + 매 theme switch
|
||||
```tsx
|
||||
// .storybook/preview.tsx
|
||||
import { withThemeByClassName } from '@storybook/addon-themes';
|
||||
export const decorators = [
|
||||
withThemeByClassName({
|
||||
themes: { light: 'theme-light', dark: 'theme-dark' },
|
||||
defaultTheme: 'light',
|
||||
}),
|
||||
];
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| Design-system / component lib | Storybook + Chromatic — default |
|
||||
| App-only, no shared component | Storybook 매 optional — 매 cost > value 의 risk |
|
||||
| Vue / Svelte / Angular | Storybook 의 multi-framework 의 native support |
|
||||
| 매 mobile (RN) | Storybook React Native — viable but small ecosystem |
|
||||
| Lightweight alt | Ladle (Vite-only, faster), Histoire (Vue-first) |
|
||||
|
||||
**기본값**: Storybook 8 + Vite + interaction test + Chromatic CI.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Design System]]
|
||||
- 응용: [[Component Library]] · [[Figma-to-Code-Workflow]]
|
||||
- Adjacent: [[Test_Automation]] · [[CI_CD_Pipeline]] · [[Figma]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 component 의 stories 의 boilerplate 의 generate, 매 interaction-test 의 scaffold, 매 design-spec ↔ args 의 sync.
|
||||
**언제 X**: 매 visual judgment (snapshot review) — 매 designer 의 human review.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 stories 의 component 의 모든 prop combo 의 explosion** — 매 visual diff 매 noise. 매 representative 매 5-10 의 keep.
|
||||
- **매 fetch / global store 의 story 의 raw use** — 매 isolation broken. 매 mock + decorator.
|
||||
- **매 interaction test 의 unit test 의 replace** — 매 unit (Vitest) + 매 interaction (Storybook) 의 complement.
|
||||
- **Chromatic 의 baseline 의 매 PR 매 auto-accept** — 매 visual regression 의 silent miss.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Storybook 8 docs 2025, Chromatic guide, CSF 3 RFC).
|
||||
- 신뢰도 A.
|
||||
- 중복 risk: 매 X (unique tool).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — CSF 3 patterns, play interaction, Chromatic, a11y 정리 |
|
||||
@@ -0,0 +1,188 @@
|
||||
---
|
||||
id: wiki-2026-0508-test-automation
|
||||
title: Test Automation
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [automated testing, test automation pyramid, CI testing]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [testing, automation, ci-cd, qa, devops]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: typescript
|
||||
framework: vitest-playwright-msw-pact
|
||||
---
|
||||
|
||||
# Test Automation
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 confidence 의 deploy 의 — 매 tests 의 paying 의"**. Test automation 의 unit / integration / e2e / contract / performance 의 의 CI 의 의 mechanically running 의 의 — 매 regression 의 catch, 매 deploy velocity 의 unlock. 2026 의 stack: Vitest (unit), Playwright (e2e), MSW (API mock), Pact (contract), k6 (load).
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 testing pyramid (modern)
|
||||
- **Unit** (60-70%): 매 fast (<100ms each), 매 isolated, 매 logic 의.
|
||||
- **Integration** (20-30%): 매 real DB / Redis 의 (testcontainers), 매 module boundaries.
|
||||
- **Component** (10%): 매 React/Vue 의 isolated rendering.
|
||||
- **E2E** (5-10%): 매 Playwright, 매 critical user journeys 의 only.
|
||||
- **Contract**: producer/consumer 의 — 매 microservices.
|
||||
|
||||
### 매 매 modern paradigms
|
||||
- **TDD** still relevant for libraries / domain logic.
|
||||
- **Snapshot testing** judiciously — 매 churn explosion 위험.
|
||||
- **Property-based** (fast-check, hypothesis) — 매 invariants.
|
||||
- **Visual regression** (Chromatic, Percy, Playwright trace).
|
||||
|
||||
### 매 응용
|
||||
1. PR-blocking unit + critical e2e.
|
||||
2. Pre-merge contract tests (Pact broker).
|
||||
3. Nightly load test + regression budget.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Vitest unit test
|
||||
```typescript
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { calcTax } from './tax';
|
||||
|
||||
describe('calcTax', () => {
|
||||
it.each([
|
||||
[100, 'CA', 8.25],
|
||||
[100, 'OR', 0],
|
||||
])('%i in %s = %f', (amt, state, expected) => {
|
||||
expect(calcTax(amt, state)).toBe(expected);
|
||||
});
|
||||
it('rejects negative', () => {
|
||||
expect(() => calcTax(-1, 'CA')).toThrow(/non-negative/);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### MSW — API mocking
|
||||
```typescript
|
||||
import { http, HttpResponse } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
|
||||
export const server = setupServer(
|
||||
http.get('/api/users/:id', ({ params }) =>
|
||||
HttpResponse.json({ id: params.id, name: 'Alice' })),
|
||||
);
|
||||
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
|
||||
afterEach(() => server.resetHandlers());
|
||||
afterAll(() => server.close());
|
||||
```
|
||||
|
||||
### Playwright e2e (critical path)
|
||||
```typescript
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('checkout flow', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: /add to cart/i }).first().click();
|
||||
await page.getByRole('link', { name: /cart/i }).click();
|
||||
await page.getByRole('button', { name: /checkout/i }).click();
|
||||
await page.getByLabel(/email/i).fill('test@example.com');
|
||||
await page.getByLabel(/card number/i).fill('4242424242424242');
|
||||
await page.getByRole('button', { name: /pay/i }).click();
|
||||
await expect(page.getByRole('heading', { name: /thank you/i })).toBeVisible();
|
||||
});
|
||||
```
|
||||
|
||||
### Testcontainers (real Postgres in CI)
|
||||
```typescript
|
||||
import { PostgreSqlContainer } from '@testcontainers/postgresql';
|
||||
let container: any, db: any;
|
||||
beforeAll(async () => {
|
||||
container = await new PostgreSqlContainer('postgres:16').start();
|
||||
db = drizzle(postgres(container.getConnectionUri()));
|
||||
await migrate(db, { migrationsFolder: './drizzle' });
|
||||
}, 60_000);
|
||||
afterAll(async () => container.stop());
|
||||
```
|
||||
|
||||
### Pact contract test (consumer)
|
||||
```typescript
|
||||
import { PactV3, MatchersV3 } from '@pact-foundation/pact';
|
||||
const provider = new PactV3({ consumer: 'web', provider: 'api' });
|
||||
provider.given('user 1 exists').uponReceiving('a request for user 1')
|
||||
.withRequest({ method: 'GET', path: '/users/1' })
|
||||
.willRespondWith({ status: 200, body: MatchersV3.like({ id: 1, name: 'Alice' }) });
|
||||
await provider.executeTest(async (mock) => {
|
||||
const r = await fetch(`${mock.url}/users/1`);
|
||||
expect((await r.json()).name).toBe('Alice');
|
||||
});
|
||||
```
|
||||
|
||||
### Property-based (fast-check)
|
||||
```typescript
|
||||
import fc from 'fast-check';
|
||||
test('reverse twice = identity', () => {
|
||||
fc.assert(fc.property(fc.array(fc.integer()), (arr) => {
|
||||
expect([...arr].reverse().reverse()).toEqual(arr);
|
||||
}));
|
||||
});
|
||||
```
|
||||
|
||||
### Flaky-test quarantine (Playwright)
|
||||
```typescript
|
||||
test.describe.configure({ retries: 2 });
|
||||
test('flaky-known @quarantine', async ({ page }) => { /* ... */ });
|
||||
// CI: skip @quarantine on PR, run nightly only
|
||||
```
|
||||
|
||||
### k6 load test
|
||||
```javascript
|
||||
import http from 'k6/http';
|
||||
import { check } from 'k6';
|
||||
export const options = {
|
||||
stages: [{ duration: '2m', target: 100 }, { duration: '5m', target: 100 }],
|
||||
thresholds: { http_req_duration: ['p(99)<500'] },
|
||||
};
|
||||
export default () => {
|
||||
const r = http.get('https://staging.app/api/items');
|
||||
check(r, { '200': (x) => x.status === 200 });
|
||||
};
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Layer |
|
||||
|---|---|
|
||||
| pure function / domain logic | unit (Vitest) |
|
||||
| DB query / SQL correctness | integration (testcontainers) |
|
||||
| critical revenue path | e2e (Playwright) |
|
||||
| microservice API stability | contract (Pact) |
|
||||
| invariant property | property-based (fast-check) |
|
||||
|
||||
**기본값**: 60/30/10 unit/integration/e2e split, MSW for external APIs, testcontainers for DB, Pact for service boundaries.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Software Quality]]
|
||||
- 변형: [[TDD]] · [[BDD]] · [[Property-based Testing]]
|
||||
- 응용: [[Continuous Integration]] · [[Visual Regression]]
|
||||
- Adjacent: [[Playwright]] · [[Pact]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: test scaffolding from impl, edge-case enumeration, flaky root-cause analysis from trace.zip, snapshot diff explanation.
|
||||
**언제 X**: auto-generated tests 의 review 없이 의 merge — 매 tautological tests (mock returns x → assert x).
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Ice-cream cone** (e2e-heavy, unit-light): 매 slow CI, 매 flaky.
|
||||
- **Mocking what you don't own** (deep mocks of fetch): 매 mock drift.
|
||||
- **Snapshot of everything**: 매 PR diff 의 noise.
|
||||
- **Shared mutable state in tests**: 매 order-dependent flaky.
|
||||
- **No quarantine**: 매 1 flaky 의 CI 의 distrust.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Vitest docs, Playwright docs, MSW v2, Pact docs, k6 docs, Kent Beck TDD).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — pyramid + Vitest/Playwright/MSW/Pact patterns |
|
||||
@@ -0,0 +1,148 @@
|
||||
---
|
||||
id: wiki-2026-0508-texture-atlas
|
||||
title: Texture Atlas
|
||||
category: 10_Wiki/Topics
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: [P-Reinforce-AUTO-71CA1F, Sprite Sheet, Atlas, Texture Sheet]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.95
|
||||
verification_status: applied
|
||||
tags: [graphics, gpu, texture, draw-call, optimization]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
tech_stack:
|
||||
language: GLSL / TypeScript
|
||||
framework: Three.js / WebGL2 / Unity / Unreal
|
||||
---
|
||||
|
||||
# Texture Atlas
|
||||
|
||||
## 매 한 줄
|
||||
> **"매 매 sprite/material 의 별도 texture 의 X — 매 single big texture 의 sub-rect 의 share, 매 draw-call 의 batch"**. 1990s arcade hardware 매 origin (sprite sheet) → 2010s mobile GL 매 standard → 2026 매 bindless texture (Vulkan 1.3, WebGPU)+ virtual texturing 의 era. 매 atlas 매 매 still 매 fundamental.
|
||||
|
||||
## 매 핵심
|
||||
|
||||
### 매 4 motivation
|
||||
- **Draw-call reduction**: 매 same-material batch — 매 매 mobile GPU 매 critical.
|
||||
- **Texture switch cost**: 매 GPU 의 texture-binding 매 stall — 매 atlas 매 single bind.
|
||||
- **Cache locality**: 매 nearby UV 의 same memory page.
|
||||
- **Compression efficiency**: 매 큰 texture 의 BC7/ASTC 의 better ratio.
|
||||
|
||||
### 매 trade-off
|
||||
- **Bleeding**: 매 mipmap + 매 bilinear 매 인접 sub-rect 의 sample → 매 padding (2-4 px) 의 필요.
|
||||
- **Wrap mode**: 매 atlas 매 `REPEAT` 의 incompatible — 매 `CLAMP_TO_EDGE` 만.
|
||||
- **Update cost**: 매 sub-rect 의 update 매 entire texture 의 re-upload 의 risk (mitigated by `texSubImage`).
|
||||
|
||||
### 매 응용
|
||||
1. 2D game sprite (Phaser, Pixi.js).
|
||||
2. 3D static prop (Unreal lightmap atlas).
|
||||
3. Font (signed-distance-field atlas).
|
||||
4. UI icon system.
|
||||
|
||||
## 💻 패턴
|
||||
|
||||
### Pattern 1: 매 atlas 의 build (offline, TexturePacker / 매 자체)
|
||||
```ts
|
||||
// 매 자체 packer 매 simple max-rects
|
||||
import { MaxRectsPacker } from 'maxrects-packer';
|
||||
const packer = new MaxRectsPacker(2048, 2048, 2 /* padding */);
|
||||
const inputs = [
|
||||
{ width: 64, height: 64, name: 'icon-a' },
|
||||
{ width: 128, height: 96, name: 'icon-b' },
|
||||
// ...
|
||||
];
|
||||
packer.addArray(inputs);
|
||||
const atlasJson = packer.bins[0].rects.map((r) => ({
|
||||
name: r.data?.name, x: r.x, y: r.y, w: r.width, h: r.height,
|
||||
}));
|
||||
// 매 actual pixel composition 매 sharp / canvas 의 use
|
||||
```
|
||||
|
||||
### Pattern 2: 매 Three.js 매 sub-UV
|
||||
```ts
|
||||
import * as THREE from 'three';
|
||||
const atlas = new THREE.TextureLoader().load('/atlas.png');
|
||||
atlas.wrapS = atlas.wrapT = THREE.ClampToEdgeWrapping;
|
||||
|
||||
// rect: { x: 64, y: 0, w: 64, h: 64 } in 1024x1024 atlas
|
||||
const u0 = 64 / 1024, v0 = 0 / 1024;
|
||||
const du = 64 / 1024, dv = 64 / 1024;
|
||||
const geom = new THREE.PlaneGeometry(1, 1);
|
||||
geom.setAttribute('uv', new THREE.Float32BufferAttribute([
|
||||
u0, v0 + dv,
|
||||
u0 + du, v0 + dv,
|
||||
u0, v0,
|
||||
u0 + du, v0,
|
||||
], 2));
|
||||
```
|
||||
|
||||
### Pattern 3: 매 dynamic atlas (`texSubImage2D`)
|
||||
```ts
|
||||
// runtime 매 새 sprite 의 add (e.g., user avatar)
|
||||
gl.bindTexture(gl.TEXTURE_2D, atlasTex);
|
||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
||||
```
|
||||
|
||||
### Pattern 4: 매 SDF font atlas (msdfgen)
|
||||
```glsl
|
||||
// fragment shader 매 매 distance field 의 alpha 의 derive
|
||||
in vec2 vUv;
|
||||
uniform sampler2D uMsdf;
|
||||
float median(vec3 v) { return max(min(v.r,v.g),min(max(v.r,v.g),v.b)); }
|
||||
out vec4 fragColor;
|
||||
void main() {
|
||||
vec3 s = texture(uMsdf, vUv).rgb;
|
||||
float d = median(s) - 0.5;
|
||||
float alpha = smoothstep(-0.05, 0.05, d);
|
||||
fragColor = vec4(1.0, 1.0, 1.0, alpha);
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 5: 매 array texture 매 atlas alternative (WebGL2)
|
||||
```ts
|
||||
const tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
|
||||
gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, 256, 256, layers, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
// 매 layer 별 upload — 매 bleeding X, wrap OK, but 매 same size 의 require
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 매 same size 의 sprite | Array texture (no bleed) |
|
||||
| 매 매 mixed size, mobile | Atlas + 2-4 px padding + CLAMP |
|
||||
| 매 매 procedural / runtime sprite add | Dynamic atlas + `texSubImage` |
|
||||
| 매 매 large unique texture (terrain) | Virtual / sparse texture |
|
||||
| 매 font | SDF / MSDF atlas |
|
||||
| 매 modern desktop / WebGPU | Bindless / array — atlas 의 less critical |
|
||||
|
||||
**기본값**: 2048x2048 atlas + 2px padding + CLAMP_TO_EDGE + offline packer (TexturePacker / sharp).
|
||||
|
||||
## 🔗 Graph
|
||||
- 응용: [[Draw Call]] · [[BatchedMesh 및 InstancedMesh 성능 벤치마크]]
|
||||
- Adjacent: [[Frustum Culling]] · [[Geometry Merging]] · [[Data Array Textures]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 atlas layout 의 design (rect packing strategy), 매 padding/wrap bug 의 diagnose, 매 SDF shader 의 derivation.
|
||||
**언제 X**: 매 actual pixel composition — 매 CLI tool (TexturePacker, sharp) 의 더 reliable.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **매 padding 의 X** + 매 mipmap → 매 visible bleeding seam.
|
||||
- **매 atlas 의 `REPEAT` 의 expectation** — 매 sub-rect 매 wrap mode 의 incompatible.
|
||||
- **매 atlas 의 over-large** (> 4096 매 mobile) — 매 GPU memory + 매 fillrate cost.
|
||||
- **매 매 frame 매 atlas 의 rebuild** — 매 GPU upload cost 매 huge. 매 dirty-rect partial update.
|
||||
- **매 매 sprite 의 별도 atlas** — 매 batching 의 defeat 의 purpose.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Real-Time Rendering 4e Ch.6, Three.js docs r170, msdfgen Chlumský 2017).
|
||||
- 신뢰도 A.
|
||||
- 중복 risk: [[Sprite Sheet]] (alias).
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — atlas motivation, packer/Three.js/SDF/array texture patterns 정리 |
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
id: wiki-2026-0508-toss-front-sdk의-facade-패턴-적용-사례
|
||||
title: Toss Front SDK의 Facade 패턴 적용 사례
|
||||
category: 10_Wiki/Topics
|
||||
status: duplicate
|
||||
canonical_id: facade-pattern
|
||||
duplicate_of: "[[Facade Pattern]]"
|
||||
aliases: []
|
||||
source_trust_level: A
|
||||
confidence_score: 0.9
|
||||
verification_status: redirected
|
||||
tags: [duplicate, design-pattern, facade, sdk]
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
---
|
||||
|
||||
# Toss Front SDK의 Facade 패턴 적용 사례
|
||||
|
||||
> **이 문서는 [[Facade Pattern]] 의 중복본입니다.** Canonical 문서로 redirect.
|
||||
|
||||
## 핵심 요약 (Toss-specific)
|
||||
- Toss Payments SDK 매 internal: HTTP client + auth + retry + iframe + risk-engine 의 합.
|
||||
- 매 외부 노출 의 `loadTossPayments(clientKey).requestPayment(...)` 의 single facade.
|
||||
- 매 caller 의 internal coupling 0 — 매 SDK upgrade 의 backward-compat 유지.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Facade Pattern]] (canonical)
|
||||
- Adjacent: [[SDK Design]]
|
||||
|
||||
## 🕓 변경 이력
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | 중복 처리 — Facade Pattern canonical 문서로 redirect |
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user