diff --git a/.claude/agents/adr-drafter.md b/.claude/agents/adr-drafter.md new file mode 100644 index 0000000..7ba0068 --- /dev/null +++ b/.claude/agents/adr-drafter.md @@ -0,0 +1,52 @@ +--- +name: adr-drafter +description: Drafts a new Architecture Decision Record (ADR) for cimery following the existing ADR-001/002/003 format. Given a decision summary or research output, produces complete ADR markdown with proper frontmatter, sections, wikilinks, and writes it to Output/reports/ADR-NNN-.md. Use when the user asks to "ADR 작성", "ADR 추가", "decision record for X". +tools: Read, Glob, Grep, Write, Edit, Bash +model: sonnet +color: green +--- + +You draft Architecture Decision Records for the **cimery** project. + +## Before drafting +1. Read existing ADRs in `Output/reports/` to determine next ADR number and copy the exact style. +2. Read `Output/guides/cimery-dev-guide.md` for principles·conventions. +3. Confirm related wiki pages exist (via `wiki/index.md`). + +## Required frontmatter +```yaml +--- +id: ADR-NNN +title: <한국어 제목 — 간결한 핵심> +status: accepted +date: YYYY-MM-DD +related-wiki: + - "[[페이지명]]" +related-adr: + - "[[ADR-NNN-slug]]" +principles: [비패밀리, 증분, 선형-GIS] # 해당되는 것만 +--- +``` + +## Required sections +- **결정 (Decision)** — 1~3 문장 핵심 +- **배경 (Context)** — 제약·동기 +- **결정 상세** — 표·하위 섹션 +- **기각된 대안** — 이유와 함께 +- **후속 결정 필요** — 체크박스 목록 +- **검토 시점** — 재검토 트리거 + +## Numbering & slug +- Scan `Output/reports/ADR-*.md`, pick `NNN = max + 1` (zero-padded to 3 digits). +- Slug = kebab-case English for filename (e.g., `feature-catalog`, `ui-framework`). + +## After writing +1. Append one-line entry to `wiki/log.md` (format: `- YYYY-MM-DD meta — ADR-NNN <제목> 작성. <한 줄 요약>.`). +2. Append one-line entry to `PROGRESS.md` timeline (format: `- YYYY-MM-DD adr — ADR-NNN <제목>: <한 줄 요약>.`). +3. Report back: path + next ADR number consumed + summary. +4. **Do NOT commit or push.** The caller handles git. + +## Style +- 한국어 + 영어 병기 +- AI 친화·diff 친화 (결정론적 섹션 순서, 표 왼쪽정렬) +- 간결. 장황 금지. diff --git a/.claude/agents/cimery-architect-researcher.md b/.claude/agents/cimery-architect-researcher.md new file mode 100644 index 0000000..5042d53 --- /dev/null +++ b/.claude/agents/cimery-architect-researcher.md @@ -0,0 +1,32 @@ +--- +name: cimery-architect-researcher +description: Used for deep research on cimery architecture topics. Compares options, gives one recommendation with rationale, drafts decision text. Reads project memory, wiki, ADRs first, then web-researches. Invoke when the user asks to "조사", "research", "비교", or any open architecture question about cimery (UI framework, library choice, protocol, etc.). +tools: Read, Grep, Glob, Bash, WebFetch, WebSearch +model: sonnet +color: blue +--- + +You are a research agent for the **cimery** project (d:\myObsidian\ParaWiki). +cimery = 토목용 Revit (civil parametric modeling tool, FBM-based). + +## Context priority (read in this order before researching) +1. `PROGRESS.md`, `PLAN.md` at project root — current state +2. `Output/guides/cimery-dev-guide.md` — decided conventions +3. `Output/reports/ADR-001-tech-stack.md` · `ADR-002-feature-dsl.md` · `ADR-003-architecture-followups.md` — decided architecture +4. `wiki/index.md` + relevant wiki pages (FBM, LPG, PCE, alignment-GIS, etc.) +5. User memory at `~/.claude/projects/d--myObsidian-ParaWiki/memory/MEMORY.md` +6. Web research (latest, 2026-04 baseline) + +## Rules +- **Never reopen decided items.** If ADR already decided it, treat as fixed and build on top. +- **Parallel-safe.** Do not write to PROGRESS.md or PLAN.md. Do not commit. +- **No file writes.** Report via message only. + +## Output format +- Markdown, 300~500 단어 +- 한국어 + 중요 용어 영어 병기 +- Structure: 맥락 정합성 확인 → 선택지 비교표(2~4개) → 추천 1개 + 근거 → 후속/리스크 → Sources +- 기존 ADR과 충돌이 있으면 명시하고 사용자 판단을 요청 + +## Input format +The caller will provide a single research topic or a comma-separated list of subtopics. For multiple subtopics, produce one section per subtopic. diff --git a/.claude/commands/adr.md b/.claude/commands/adr.md new file mode 100644 index 0000000..a261537 --- /dev/null +++ b/.claude/commands/adr.md @@ -0,0 +1,19 @@ +--- +description: Draft a new ADR for the given decision topic using the adr-drafter agent +argument-hint: +--- + +cimery 아키텍처 결정을 ADR 문서로 만든다. + +## 절차 +1. `Output/reports/` 디렉터리를 읽어 다음 ADR 번호 결정 (`max(NNN) + 1`). +2. `adr-drafter` 에이전트를 호출한다 — 입력으로 현재 주제와 이미 결정된 맥락을 전달. +3. 에이전트가 `Output/reports/ADR-NNN-.md`를 작성하고 `wiki/log.md` · `PROGRESS.md`에 한 줄씩 추가. +4. 작성된 ADR 경로 + 요약을 사용자에게 보고. +5. **커밋·푸시는 사용자 명시 요청 시에만 수행.** + +## 주제 +$ARGUMENTS + +## 참고 +먼저 `PROGRESS.md`·`PLAN.md`·`Output/guides/cimery-dev-guide.md`·기존 ADR을 읽어 중복·충돌 여부 확인. diff --git a/.claude/commands/cimery-start.md b/.claude/commands/cimery-start.md new file mode 100644 index 0000000..33dd376 --- /dev/null +++ b/.claude/commands/cimery-start.md @@ -0,0 +1,29 @@ +--- +description: Start a cimery work session — load PROGRESS, PLAN, dev-guide context +--- + +cimery 작업 세션 진입 루틴. 실제 구현은 시작하지 않고 **상황을 정리**만 한다. + +## 실행 절차 +1. `PROGRESS.md` 읽기 — "현재 스냅샷" + 최근 10건 타임라인. +2. `PLAN.md` 읽기 — P0·P1 섹션만. +3. `Output/guides/cimery-dev-guide.md` 읽기 — "구현 우선순위" + "함정 체크리스트" 섹션만. +4. 다음 형식으로 요약: + +``` +## 지금까지 (PROGRESS) +- <최근 3~5건> +- 현재 cimery 코드 상태: <있음/없음/일부> + +## 지금 해야 할 일 (PLAN P0·P1) +- +- + +## 주의 (dev-guide) +- <가장 중요한 함정 2~3개> + +## 제안 +<다음에 할 가장 자연스러운 1~2개 행동> +``` + +5. **구현 시작 금지.** 사용자의 다음 지시를 기다린다. diff --git a/.claude/commands/plan.md b/.claude/commands/plan.md new file mode 100644 index 0000000..3e31dfc --- /dev/null +++ b/.claude/commands/plan.md @@ -0,0 +1,24 @@ +--- +description: Show PLAN.md current P0/P1 or add/complete items +argument-hint: [add | done | (empty)] +--- + +PLAN.md at project root 관리 커맨드. + +## 인수 없으면 +`PLAN.md`의 "현재 스프린트" 섹션(P0·P1)만 보여주고 백로그는 줄 수만 요약. + +## `add ` +백로그 적절한 카테고리에 `- [ ] ` 추가. 우선순위는 사용자에게 질문(기본 백로그). + +## `done ` +해당 항목을 찾아서: +1. `PLAN.md`에서 제거 +2. `PROGRESS.md` 타임라인 상단에 `- YYYY-MM-DD <유형> <항목 텍스트>` 추가 +3. 변경사항 요약 보고 + +## 규칙 +- 둘 다 같은 커밋에 포함되어야 함 (atomic). 단 커밋은 **자동 실행 금지** — 사용자 명시 요청 시만. +- 날짜는 오늘(`date +%F`). + +$ARGUMENTS diff --git a/.claude/commands/progress.md b/.claude/commands/progress.md new file mode 100644 index 0000000..e97b908 --- /dev/null +++ b/.claude/commands/progress.md @@ -0,0 +1,22 @@ +--- +description: Show recent PROGRESS.md entries or add a completion entry +argument-hint: [add | snapshot | (empty)] +--- + +PROGRESS.md at project root 관리 커맨드. + +## 인수 없으면 +타임라인 최근 10건 + "현재 스냅샷" 섹션 요약. + +## `add ` +타임라인 **오늘 섹션 맨 위**에 `- ` 추가. `type`은 `adr|wiki|guide|meta|raw|code|infra` 중 하나. +오늘 섹션이 없으면 `### YYYY-MM-DD` 헤더와 함께 새로 생성. + +## `snapshot` +"현재 스냅샷" 섹션을 현재 저장소 상태 기반으로 재작성 (위키 페이지 수·ADR 수·가이드 수·cimery 코드 존재 여부). + +## 규칙 +- PLAN.md에서 제거된 항목은 여기에 추가되어야 함 (pair). `/plan done` 명령과 대칭. +- 날짜는 오늘(`date +%F`). + +$ARGUMENTS diff --git a/.claude/commands/research.md b/.claude/commands/research.md new file mode 100644 index 0000000..ec8c2d3 --- /dev/null +++ b/.claude/commands/research.md @@ -0,0 +1,25 @@ +--- +description: Dispatch cimery-architect-researcher agent(s) to research a topic, optionally in parallel +argument-hint: | ; ; +--- + +cimery 아키텍처 주제를 `cimery-architect-researcher` 에이전트로 심층 조사한다. + +## 인수 파싱 +- 세미콜론(`;`)으로 구분된 여러 주제면 **병렬 dispatch** (단일 메시지에 multiple Agent tool calls). +- 단일 주제면 1개 에이전트. + +## 각 에이전트에 전달할 프롬프트 (자동 생성) +- 맥락 우선순위 알림 (PROGRESS·PLAN·dev-guide·ADR·wiki·메모리·웹) +- 주제 +- 출력 형식: 비교표·추천·근거·Sources, 300~500 단어 + +## 결과 집계 +모든 에이전트 리포트 수신 후: +1. 요약 테이블 제시 (주제별 추천 한 줄) +2. 상충 결정 있으면 명시 +3. 사용자에게 "추천대로 확정할지 / 수정할지" 묻기 +4. 확정 시 `/adr <주제>` 로 ADR 초안 작성 제안 + +## 주제 +$ARGUMENTS diff --git a/.claude/hooks/auto-approve.sh b/.claude/hooks/auto-approve.sh new file mode 100644 index 0000000..c7f3806 --- /dev/null +++ b/.claude/hooks/auto-approve.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# PreToolUse: auto-approve tool invocations to skip permission prompts. +# +# SAFETY NOTE: +# Specific deny hooks (e.g. block-raw-writes.sh) take precedence because +# Claude Code aggregates hook decisions — any "deny" wins over "allow". +# That is, this hook grants blanket allow, but surgical blocks remain enforced. +# +# This hook is user-scoped convenience. Remove or narrow its matcher if +# multiple team members share this project. + +cat <<'EOF' +{ + "hookSpecificOutput": { + "hookEventName": "PreToolUse", + "permissionDecision": "allow", + "permissionDecisionReason": "auto-approved by .claude/hooks/auto-approve.sh" + } +} +EOF +exit 0 diff --git a/.claude/hooks/block-raw-writes.sh b/.claude/hooks/block-raw-writes.sh new file mode 100644 index 0000000..1dca17e --- /dev/null +++ b/.claude/hooks/block-raw-writes.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# PreToolUse(Write|Edit): block writes to raw/ directory +# Karpathy LLM Wiki rule #1: raw/ is immutable + +json=$(cat) + +# Extract file_path from JSON (works for Write, Edit, MultiEdit tools) +path=$(printf '%s' "$json" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') + +if [ -z "$path" ]; then + exit 0 +fi + +# Normalize Windows backslashes to forward slashes +path_norm=$(printf '%s' "$path" | tr '\\' '/') + +case "$path_norm" in + */raw/*|raw/*) + cat <<'EOF' +{ + "hookSpecificOutput": { + "hookEventName": "PreToolUse", + "permissionDecision": "deny", + "permissionDecisionReason": "raw/ is immutable (Karpathy LLM Wiki rule #1). Edit or place new sources via manual copy only." + } +} +EOF + exit 0 + ;; +esac + +exit 0 diff --git a/.claude/hooks/session-start-context.py b/.claude/hooks/session-start-context.py new file mode 100644 index 0000000..2dcc80e --- /dev/null +++ b/.claude/hooks/session-start-context.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +"""SessionStart hook: inject PLAN.md P0/P1 and PROGRESS.md snapshot as additionalContext.""" +import json +import os +import re +import sys + + +def read_file(path: str) -> str: + try: + with open(path, encoding="utf-8") as f: + return f.read() + except Exception: + return "" + + +def main() -> None: + proj = os.environ.get("CLAUDE_PROJECT_DIR", ".") + plan = read_file(os.path.join(proj, "PLAN.md")) + progress = read_file(os.path.join(proj, "PROGRESS.md")) + + parts: list[str] = [] + + # PLAN: "### P0" through (not including) "## 백로그" + m = re.search(r"^### P0.*?(?=^## 백로그)", plan, re.M | re.S) + if m: + parts.append("## PLAN.md — 현재 스프린트\n\n" + m.group(0).strip()) + + # PROGRESS: "## 현재 스냅샷" to EOF + m = re.search(r"^## 현재 스냅샷.*$", progress, re.M | re.S) + if m: + parts.append(m.group(0).strip()) + + if not parts: + sys.exit(0) + + ctx = "\n\n".join(parts) + ( + "\n\n**에이전트 작업 시작 시 PLAN.md · PROGRESS.md를 읽는 것이 필수입니다.**" + ) + + print( + json.dumps( + { + "hookSpecificOutput": { + "hookEventName": "SessionStart", + "additionalContext": ctx, + } + }, + ensure_ascii=False, + ) + ) + + sys.exit(0) + + +if __name__ == "__main__": + try: + main() + except Exception as exc: + sys.stderr.write(f"session-start-context: {exc}\n") + sys.exit(0) diff --git a/.claude/hooks/wiki-log-reminder.sh b/.claude/hooks/wiki-log-reminder.sh new file mode 100644 index 0000000..fa13594 --- /dev/null +++ b/.claude/hooks/wiki-log-reminder.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# PostToolUse(Write|Edit): remind to update wiki/log.md and PROGRESS.md +# when wiki pages or Output/reports/ADRs are modified + +json=$(cat) + +path=$(printf '%s' "$json" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') + +if [ -z "$path" ]; then + exit 0 +fi + +path_norm=$(printf '%s' "$path" | tr '\\' '/') + +# Skip the log/index themselves — they ARE the trackers +case "$path_norm" in + */wiki/log.md|*/wiki/index.md|*/PROGRESS.md|*/PLAN.md) + exit 0 + ;; +esac + +case "$path_norm" in + */wiki/*|*/Output/reports/*|*/Output/guides/*) + fname=$(basename "$path_norm") + # Minimal JSON — no escaping of special chars needed since message is literal + printf '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"Reminder: %s 변경됨. wiki/log.md 기록 + PROGRESS.md 갱신 여부 확인."}}\n' "$fname" + exit 0 + ;; +esac + +exit 0 diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..23aa455 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,100 @@ +{ + "permissions": { + "allow": [ + "mcp__gitea__issue_write", + "Edit(/.claude/skills/ingest-raw/**)", + "Edit(/.claude/skills/query/**)", + "Edit(/.claude/skills/lint/**)", + "Edit(/.claude/skills/plan-commit/**)", + "Edit(/.claude/agents/**)", + "Edit(/.claude/commands/**)", + "Edit(/.claude/hooks/**)", + "mcp__gitea__actions_run_read", + "mcp__gitea__actions_config_read", + "Bash(obsidian:*)", + "Bash(obsidian-cli:*)" + ], + "additionalDirectories": [ + "d:\\myObsidian\\ParaWiki\\.claude\\skills", + "D:\\myObsidian\\ParaWiki\\.claude\\skills" + ] + }, + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "python ./.claude/hooks/session-start-context.py", + "timeout": 5 + } + ] + } + ], + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" session-context \"$t\";rm -f \"$t\"", + "timeout": 5 + } + ] + } + ], + "PreToolUse": [ + { + "matcher": "Write|Edit|MultiEdit", + "hooks": [ + { + "type": "command", + "command": "bash ./.claude/hooks/block-raw-writes.sh", + "timeout": 3 + } + ] + }, + { + "hooks": [ + { + "type": "command", + "command": "bash ./.claude/hooks/auto-approve.sh", + "timeout": 3 + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" stop-record \"$t\";rm -f \"$t\"", + "timeout": 5 + } + ] + } + ], + "PostToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "t=$(mktemp);cat>\"$t\";e=./.claude/hooks/token-usage/claude-hook.exe;[ -x \"$e\" ] && \"$e\" aptabase-commit \"$t\";rm -f \"$t\"", + "timeout": 15 + } + ] + }, + { + "matcher": "Write|Edit|MultiEdit", + "hooks": [ + { + "type": "command", + "command": "bash ./.claude/hooks/wiki-log-reminder.sh", + "timeout": 3 + } + ] + } + ] + } +} diff --git a/.claude/skills/ingest-raw/SKILL.md b/.claude/skills/ingest-raw/SKILL.md new file mode 100644 index 0000000..5215138 --- /dev/null +++ b/.claude/skills/ingest-raw/SKILL.md @@ -0,0 +1,95 @@ +--- +name: ingest-raw +description: Scan raw/ for sources not yet ingested and compile them into wiki/ pages per Karpathy LLM Wiki rules. Use when the user says "raw/ 인제스트", "raw 스캔 컴파일", "아직 인제스트 안 된 파일 처리", or "/ingest-raw". Updates wiki/index.md and wiki/log.md. Runs non-interactively and produces a final summary. +--- + +# ingest-raw + +ParaWiki의 `raw/` 폴더를 스캔해서 아직 위키로 컴파일되지 않은 소스들을 `wiki/`에 반영한다. 대화 없이 바로 실행, 끝나면 요약만 보고. + +## 입력 +- 사용자 추가 인자 없이 바로 실행 가능. 사용자가 특정 파일을 지정하면 그 파일만 처리. + +## 절차 + +### 1. 스캔 +- `find raw -type f \( -name "*.md" -o -name "*.pdf" -o -name "*.txt" \) -not -name "README.md" -not -name "CLAUDE.md"` 로 raw/ 전체 파일 수집. +- 서브폴더: `ai-research/`, `papers/`, `standards/`, `tools/`, `notes/` (있는 것만). + +### 2. 이미 인제스트된 소스 판별 +- `wiki/log.md` 를 읽고 기록된 소스 파일 경로를 수집. +- 그리고 `wiki/*.md` 파일들의 frontmatter `sources:` 필드 전체를 스캔해 교차 검증. +- **아직 인제스트 안 된 파일** = raw 스캔 결과에서 위 두 집합을 뺀 것. + +### 3. 컴파일 결정 +- 신규 파일이 없으면: "새 파일 없음"을 요약하고 종료. +- 신규 파일이 있으면 각각에 대해: + - 내용을 읽고 **핵심 개념**을 추출. + - **Rule 9 우선:** 기존 wiki 페이지(`wiki/*.md`)가 같은 주제를 이미 다룬다면 **업데이트 우선**. 새 페이지는 기존이 없을 때만. + - 한 소스가 여러 개념을 담고 있으면 여러 페이지에 쪼개 반영할 수 있음. 단, 과도한 페이지 양산 금지 (한 소스당 **최대 3~4개** 페이지 권장). + +### 4. 위키 페이지 작성/갱신 — Karpathy 10대 규칙 준수 +모든 신규/갱신 페이지 상단은 YAML frontmatter: + +```yaml +--- +title: 페이지 제목 +tags: [...] +sources: + - raw/.../원본파일.md +updated: YYYY-MM-DD +principles: [비패밀리|증분|선형-GIS] # 해당 시만 +--- +``` + +본문 구성(권장): +1. **요약** (1~3문장) +2. **사실 (Facts)** — 원문의 사실만. 해석 금지. 필요 시 표·리스트. +3. **해석 (Interpretation)** — 우리 프로젝트 관점. 잠정 설계 원칙과의 연결을 여기서. +4. **관련 페이지** — `[[...]]` wikilink. + +규칙 체크리스트: +- [ ] 내부 참조는 **wikilink** 형식. +- [ ] **사실과 해석 분리.** +- [ ] 모순 소스는 **양쪽 모두 인용.** +- [ ] 기존 페이지 업데이트를 새 페이지보다 우선. + +### 5. index.md 갱신 +- 신규 페이지는 해당 카테고리 아래 **한 줄, 120자 이내** 추가: + `- [[페이지명]] — 핵심 한 줄 설명.` +- 카테고리: 설계 원칙 허브 / 개념 / 도메인: 교량 / 기하·수학 / 도구·엔진 / 표준·스펙. 맞는 곳이 없으면 "개념" 아래. +- 페이지 삭제·병합·이름 변경 시도 해당 줄을 동일하게 갱신. + +### 6. log.md 갱신 +- **시간 역순(최신이 위).** 형식: + `- YYYY-MM-DD [action] [[페이지명]] — 한 줄 설명` +- 액션: `create` / `update` / `delete` / `rename` / `merge` / `meta`. +- 원칙 연결이 있으면 설명 끝에 "원칙: X,Y" 명시. + +### 7. 최종 요약 보고 +보고 형식: +``` +## 요약 + +**인제스트 신규 소스 N건**: +- <경로1> +- <경로2> + +**위키 변경**: +- 신규: [[A]], [[B]] +- 갱신: [[C]] + +**원칙 연결**: +- 비패밀리: ... +- 증분: ... +- 선형-GIS: ... + +**미커버 원칙**: 원칙 중 이번에도 소스가 없어 비어 있는 축. +``` + +## 주의사항 +- `raw/` 는 **절대 수정·삭제 금지** (불변 원본). +- 실행 중 사용자와 대화하지 말고 끝난 뒤 요약만. +- 문서 분량이 커 한 번에 읽기 어려우면 offset/limit으로 분할 읽기. +- 소스 2건 이상이 같은 주제를 다루면 같은 페이지에 합쳐 `sources:` 배열에 모두 포함. +- 소스 간 **모순**이 있으면 사실 섹션에서 양쪽 모두 인용하고 차이 기록. diff --git a/.claude/skills/lint/SKILL.md b/.claude/skills/lint/SKILL.md new file mode 100644 index 0000000..5a4be29 --- /dev/null +++ b/.claude/skills/lint/SKILL.md @@ -0,0 +1,95 @@ +--- +name: lint +description: Library-tidying scan over the entire wiki/. Detects broken wikilinks, orphan pages, missing frontmatter fields, stale sources, index mismatches, oversized index lines, and log gaps — then proposes and applies fixes. Use when the user says "위키 정리", "lint", "도서관 정리", or "/lint". +--- + +# lint + +위키 전체를 점검하고, 깨지거나 낡은 것·규칙 위반을 찾아 **수정·업데이트**까지 수행하는 도서관 정리 스킬. + +## 절차 (순서대로 실행) + +### 1. 인벤토리 수집 +- `wiki/*.md` 전체 파일 목록(이하 `WIKI_FILES`). +- `raw/` 전체 파일 목록(이하 `RAW_FILES`, README/CLAUDE 제외). +- `wiki/index.md` 내 모든 `[[...]]` wikilink 목록(`INDEX_LINKS`). +- `wiki/log.md` 내 `create`/`delete`/`rename` 이벤트 목록(`LOG_EVENTS`). +- 각 위키 페이지의 frontmatter(`title`, `tags`, `sources`, `updated`, `principles`)와 본문 내 wikilink 전체(`PAGE_LINKS_BY_FILE`). + +### 2. 점검 항목 + +각 항목은 **찾기(detect) → 제안(report) → 가능하면 자동 수정(apply)**. 의미가 모호한 수정은 제안만 하고 사용자 확인을 남겨둠. + +#### A. 깨진 wikilink (자동 수정 어려움 — 제안) +- 각 페이지의 `[[X]]` 에 대해 `wiki/X.md` 가 존재하는지 검사. +- 없으면 **깨진 링크**. 유사 이름(대소문자·띄어쓰기 차이) 페이지가 있으면 자동 교정 제안. + +#### B. 오탈자·이명 (자동 수정 어려움 — 제안) +- 페이지 제목과 wikilink 텍스트 불일치 확인. + +#### C. 고아 페이지 (자동) +- `WIKI_FILES` 중 어떤 다른 페이지에서도 링크되지 않고, **index.md에도 없는** 페이지. +- index.md에 한 줄 엔트리를 추가 (카테고리: 내용 기반 판단, 애매하면 "개념"). 120자 이내. + +#### D. index.md 누락·불일치 (자동) +- `WIKI_FILES` ⊄ `INDEX_LINKS` → 누락된 페이지는 index에 추가. +- `INDEX_LINKS` ⊄ `WIKI_FILES` → 삭제된 페이지에 대한 **죽은 엔트리**는 index에서 제거. + +#### E. index 엔트리 길이 (자동) +- `- [[X]] — ...` 한 줄이 **120자 초과** 시 설명을 요약해 자르기. + +#### F. frontmatter 누락·형식 (자동) +- 필수 필드: `title`, `sources`, `updated`. +- 누락이면 추가. `title`은 파일명에서, `updated`는 **오늘 날짜**로, `sources`는 빈 배열로 두고 사용자 보완 제안. + +#### G. 존재하지 않는 source 참조 (제안) +- 각 페이지의 `sources:` 배열이 가리키는 경로가 실제로 `raw/`에 있는지 확인. 없으면 이름 변경·삭제 여부 조사를 제안. + +#### H. 로그 누락 (자동) +- `WIKI_FILES` 각 페이지에 대해 `log.md`에 **해당 페이지명의 `create` 이벤트**가 있는지 확인. +- 없으면 "(late)" 태그와 함께 **오늘 날짜의 create 엔트리**를 log.md 맨 위에 추가: + `- YYYY-MM-DD create [[페이지명]] — (late) lint에 의해 역추적 등록.` + +#### I. 삭제된 페이지의 죽은 참조 (자동) +- `log.md`의 delete 이벤트 대상 페이지가 여전히 다른 페이지에서 링크되면, 해당 링크를 **일반 텍스트로 변환** 또는 새 대상 제안. + +#### J. 오래된 `updated:` (제안) +- 페이지의 `sources:` 파일들의 mtime이 페이지 `updated:`보다 **7일 이상 새것**이면 재검토 제안. + +#### K. 잠정 설계 원칙 연결 누락 (제안) +- 페이지가 "해석" 섹션에서 원칙(비패밀리/증분/선형-GIS) 중 하나를 언급하는데, frontmatter `principles:` 에 빠져 있으면 추가 제안. + +#### L. 중복 개념 (제안) +- 두 페이지 제목·핵심 용어가 과도하게 겹치면 **병합 후보**로 리포트. 자동 병합은 금지. + +### 3. 실행 순서 +1. 자동 가능한 항목부터 수정 (E → F → H → D → I → C 순서). +2. `log.md`에 `- YYYY-MM-DD meta — lint run: 자동 수정 N건 적용.` 한 줄 추가. +3. 제안만 가능한 항목(A, B, G, J, K, L)은 최종 보고에 리스트화. + +### 4. 최종 보고 형식 + +``` +## Lint 결과 + +### 자동 수정 N건 +- [A] ... +- [B] ... + +### 수동 확인 필요 M건 +- **깨진 링크**: [[X]] (페이지 [[Y]] 내부) → 제안: [[Z]] 로 변경? +- **병합 후보**: [[A]] ⟷ [[B]] +- **오래된 updated**: [[C]] (sources 변경된 지 N일) +- **원칙 연결 누락**: [[D]]에 'principles: [증분]' 추가? + +### 원칙 커버리지 현황 +- 비패밀리: 페이지 N개 +- 증분: 페이지 N개 +- 선형-GIS: 페이지 N개 ← ⚠️ 비어 있음 / 부족 +``` + +## 주의사항 +- `raw/` 파일은 **절대 수정·이동·삭제 금지** (불변 원본). lint는 오직 `wiki/` 쪽만 수정. +- 자동 수정 전, 각 변경은 사용자가 되돌릴 수 있도록 `log.md`에 흔적을 남긴다. +- 애매한 의미 수정(깨진 링크의 의도 추정, 병합)은 **절대 자동화 금지.** 보고만. +- 한 번의 실행에서 **너무 많은 파일을 재작성하지 않는다.** 30건 넘으면 일부만 처리하고 나머지는 보고. diff --git a/.claude/skills/plan-commit/SKILL.md b/.claude/skills/plan-commit/SKILL.md new file mode 100644 index 0000000..e9ba927 --- /dev/null +++ b/.claude/skills/plan-commit/SKILL.md @@ -0,0 +1,37 @@ +--- +name: plan-commit +description: Atomically mark a PLAN.md item as done, move it to PROGRESS.md, and optionally commit. Use when user says "완료 처리", "이 항목 done", "PLAN에서 PROGRESS로 이동", or similar phrasing about work item completion. +--- + +# plan-commit 스킬 + +완료된 작업 항목을 `PLAN.md`에서 제거하고 `PROGRESS.md`에 기록하는 **원자적** 작업. + +## 실행 절차 + +1. **확인**: 어느 항목을 완료 처리할지 사용자에게 확인한다. 애매하면 `PLAN.md` 해당 섹션을 보여주고 선택받는다. + +2. **`PLAN.md` 수정**: 해당 `- [ ] ...` 또는 `- [~] ...` 라인을 **제거**. + +3. **`PROGRESS.md` 수정**: 타임라인의 오늘 날짜 섹션에 한 줄 추가. + - 형식: `- — <한 줄 설명>` + - type 고르기: `adr|wiki|guide|meta|raw|code|infra`. 애매하면 사용자에게 묻는다. + - 오늘 섹션(`### YYYY-MM-DD`)이 없으면 상단에 새로 생성. + +4. **규칙 준수**: + - 두 수정은 **같은 응답 내**에 일어나야 한다 (원자성). + - 중간에 실패하면 rollback (Edit 실패 시 이전 상태로). + +5. **커밋은 기본값 OFF.** 사용자가 "커밋까지" 또는 "commit"을 명시하면 그때만 실행. + - 커밋 메시지: `plan: <완료 항목 요약>` + - 스테이징: `PLAN.md` · `PROGRESS.md`만. + - **푸시는 하지 않는다.** 사용자가 `push`를 명시할 때만. + +## 실패 케이스 +- PLAN.md에 해당 항목이 없음 → 사용자에게 알림, 중단. +- 여러 항목이 패턴 매치 → 번호로 선택지 제시. +- PROGRESS.md에 파일이 없음 → 파일 부재 경고, 중단. + +## 예시 호출 +- 사용자: "Girder Feature 정의 완료 처리해줘" +- 스킬: `PLAN.md`의 "Girder Feature 정의" 라인을 제거하고, `PROGRESS.md` 오늘 섹션에 `- code — Girder Feature 정의 완료`를 추가. diff --git a/.claude/skills/query/SKILL.md b/.claude/skills/query/SKILL.md new file mode 100644 index 0000000..502a1f7 --- /dev/null +++ b/.claude/skills/query/SKILL.md @@ -0,0 +1,68 @@ +--- +name: query +description: Answer a user question using wiki/ pages as the knowledge base. Document-based retrieval, NOT vector DB. Use when the user asks a substantive question about parametric modeling, civil BIM, Revit, or any topic likely covered in ParaWiki — or invokes "/query <질문>". Cites wikilinks as sources. +--- + +# query + +사용자 질문을 `wiki/` 문서를 근거로 답한다. 벡터 DB·임베딩 사용 안 함 — **파일 시스템 + 문자열 검색**으로 필요한 페이지를 찾고, 해당 페이지들을 읽어 답한다. + +## 절차 + +### 1. 질문 의도 파악 (한 번만 빠르게) +- 질문의 **핵심 키워드 2~5개** 추출. 한국어 + 영어 동의어 모두 고려 (예: "솔버" / "solver" / "GCS", "변경 엔진" / "PCE" / "propagation"). + +### 2. index.md 먼저 (Rule 8) +- `wiki/index.md` 를 읽는다. +- 한 줄 설명과 제목을 훑어 **관련성 높은 페이지 후보 3~7개** 선정. + +### 3. 본문 검색 보강 +- Grep으로 `wiki/*.md` 전체에서 키워드 검색 (`Grep` 도구, `path: wiki/`). +- index.md에서 놓친 페이지 발견 시 후보에 추가. + +### 4. 후보 페이지 읽기 +- 선정한 페이지들을 `Read` 로 열람. +- 각 페이지의 **frontmatter(sources, principles)** 와 **사실/해석 섹션**을 근거로 추출. +- 페이지 안의 **wikilink**로 연결된 페이지가 중요해 보이면 재귀적으로 1단계 더 타고 읽음 (과도한 확장 금지 — 보통 2단계 이내). + +### 5. raw/ 폴백 (최후 수단) +- 위키에 해당 내용이 **없거나 빈약**할 때만 `raw/` 검색. +- raw에서 근거를 찾았다면 답변 후 **새 위키 페이지·기존 페이지 업데이트를 제안** (자동 실행 금지 — `/ingest-raw`로 사용자가 트리거). + +### 6. 답변 작성 +형식: +- **결론부터**. 1~3문장 요약. +- **근거** — 사실은 어느 페이지에서 왔는지 `[[페이지명]]` 인용. 여러 페이지를 종합하면 각각 표기. +- **해석·제안** (선택) — 위키의 해석 섹션 또는 답변자 판단. 사실과 구분. +- **관련 페이지** — 사용자가 더 파고들 링크 2~4개. + +원칙: +- **사실과 해석을 섞지 않는다.** (Rule 7) +- 모순된 소스가 있으면 **양쪽 모두 인용**하고 차이를 드러낸다. (Rule 6) +- 위키에 없는 내용은 **"위키에 아직 없음"** 이라고 명시. 추측 금지. +- 답변은 간결하게. 장황한 배경 설명 자제. + +### 7. 사후 처리 +- 답변 중 **위키에 추가할 가치가 있는 사실·관점**이 드러나면 답변 끝에 한 줄 제안: + `📝 업데이트 제안: [[페이지명]] 의 '해석' 섹션에 X 추가` +- 자동 업데이트는 하지 않는다. 사용자가 명시적으로 요청 시 또는 `/ingest-raw` 시에만. + +## 출력 예시 + +``` +## 답변 +Revit의 GCS는 Siemens D-Cubed 2D DCM을 라이선스해 내장한다. [[GCS 기하학적 구속조건 솔버]] + +## 근거 +- Siemens 채택: [[Revit 파라메트릭 아키텍처]] §사실 +- 솔버 내부 메커니즘: [[GCS 기하학적 구속조건 솔버]] §사실 (Jacobian 랭크·뉴턴랩슨) + +## 관련 +- [[PCE 파라메트릭 변경 엔진]] +- [[파라메트릭 취약성 Davis 5가지]] +``` + +## 주의 +- 벡터 검색·임베딩 사용 금지. 파일 시스템 + 키워드 grep만. +- raw/ 파일을 직접 인용할 때도 **위키 페이지가 그 사실을 담고 있는지** 먼저 확인. 담고 있으면 위키 쪽을 우선 인용. +- 답변에 위키의 frontmatter 메타(원칙 태그 등)를 활용하면 좋음. diff --git a/.gitignore b/.gitignore index da3be36..8872345 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,24 @@ # Obsidian & editor workspace .obsidian/ -.claude/ .usage/ +# Claude Code — share agents/commands/skills/hooks/settings.json, ignore local state +.claude/* +!.claude/agents/ +!.claude/agents/** +!.claude/commands/ +!.claude/commands/** +!.claude/skills/ +!.claude/skills/** +!.claude/hooks/ +!.claude/hooks/** +!.claude/settings.json +.claude/hooks/token-usage/ +.claude/settings.local.json +.claude/scheduled_tasks.lock +.claude/logs/ +.claude/aptabase-cache/ + # Local backups Backup/ diff --git a/CLAUDE.md b/CLAUDE.md index 3de9c05..0dba545 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,82 +3,63 @@ ## 나는 누구인가 - **이름:** 김민성 (kimminsung) - **하는 일:** BIM SW 시니어 개발자. 25년간 3D 뷰어·에디터·모델링툴, DWG·CAD 엔진 개발. -- **핵심 가치:** 기능은 좁히되 **품질·아키텍처는 타협 없음.** MVP식이라도 스파게티 금지. 차근차근. +- **핵심 가치:** 기능은 좁히되 **품질·아키텍처는 타협 없음.** MVP식이라도 스파게티 금지. -## 나의 역할들 +## 나의 역할 +- **cimery 개발자** — Revit의 토목 버전 파라메트릭 모델링 도구 `cimery`(Civil + BIM + -ery) 설계·개발. MVP = 거더교. +- **ParaWiki 큐레이터** — AI가 활용할 파라메트릭 모델링 지식 저장소를 Obsidian 기반으로 구축. -### cimery 개발자 -- **하는 일:** `cimery` — Revit의 토목 버전 파라메트릭 모델링 도구 설계·개발. (명칭: Civil + BIM + -ery) -- **주요 관심사:** 토목 구조물(MVP: 거더교) 모델링, 선형·GIS 연동, 증분 인터랙티브 파라메트릭. -- **기술 스택 (2026-04-14 확정):** Rust 기반. 웹(PWA) + 데스크톱(Tauri) 듀얼 타깃. 기하 커널은 OpenCascade.js(웹) / opencascade-rs(데스크톱) 이원화, `GeomKernel` trait로 추상화. 렌더 wgpu→WebGPU. 기존 C# 엔진은 알고리즘·지식만 승계. 상세: `Output/reports/ADR-001-tech-stack.md`. +## 비전 +토목 엔지니어링 특성을 반영한 파라메트릭 모델링 도구를 시장에 공급. +두 단계: ① ParaWiki(AI용 세컨드 브레인) → ② cimery 개발. 타겟: 토목 설계자·시공사. -### ParaWiki 큐레이터 -- **하는 일:** AI가 읽고 활용할 수 있는 파라메트릭 모델링 지식 저장소를 Obsidian 기반으로 구축. -- **주요 관심사:** AI 친화적 구조, 빠른 인덱싱·링크, 잠정 설계 원칙과 연결되는 자료 우선 수집. +## 에이전트 작업 흐름 (필독) +작업을 **시작할 때** 항상 두 파일을 먼저 읽는다: +- **`PROGRESS.md`** — 지금까지 무엇이 끝났는지 (스냅샷 + 타임라인) +- **`PLAN.md`** — 무엇을 해야 하는지 (우선순위별 과제 목록) -## 나의 비전과 목표 -- **이루고자 하는 것:** 토목 엔지니어링 특성을 반영한 파라메트릭 모델링 도구를 시장에 공급. -- **두 단계 전략:** - 1. ParaWiki — "AI를 위한 세컨드 브레인" 지식 저장소 구축. - 2. AI와 함께 토목용 파라메트릭 모델링 도구 개발. -- **타겟 독자/고객:** 토목 설계자, 시공사. +작업 **중**: 착수한 PLAN 항목을 `- [~] 진행 중 (담당/에이전트명)`으로 표시. +작업 **완료 시:** `PROGRESS.md`에 한 줄 추가 + `PLAN.md`에서 해당 항목 제거. +**새 과제**가 생기면 `PLAN.md` 우선순위 위치에 즉시 삽입. -## AI에게 기대하는 것 -- **전부.** 개념 QA, 코드 초안 생성, 아키텍처 제안, 논문→구현 번역, 코드 리뷰·리팩터링. -- ParaWiki의 자료를 근거로 답할 것. -- 제품 스펙을 확정하기 전에 **저장소 구축**을 우선 도울 것. +여러 에이전트가 병렬로 일할 때 이 두 파일이 유일한 조정 지점이다. 다른 문서(ADR·가이드)는 참조용, 상태는 여기에. ## 작업 규칙 -- **언어:** 한국어로 작성. **중요 용어는 영어 병기** (예: 선형(alignment)). -- **톤:** 간결·명료. 장황한 설명·불필요한 예시 나열 금지. -- **질문:** 한 번에 **2~3개 이하**, 각 질문은 한 줄. -- **결과물 형태:** AI가 활용하기 좋은 구조가 1순위. 사람은 최상위 index 링크로 접근. -- **잠정 설계 원칙 (수집·개발의 나침반):** - 1. 비(非)패밀리 조립 단위 - 2. 증분 인터랙티브 파라메트릭(incremental) - 3. 선형·GIS 기반 좌표계 - 자료 편입 시 이 원칙 중 최소 하나와 연결되는지 확인. -- **MVP 원칙:** 기능은 좁힘 + 품질·아키텍처는 타협 없음. 철근 설계는 v2로 미룸. +- **언어:** 한국어 + 중요 용어 영어 병기 (예: 선형(alignment)). +- **톤:** 간결·명료. 장황 금지. +- **질문:** 한 번에 2~3개 이하, 각 한 줄. +- **결과물:** AI 활용 구조 1순위. 사람은 index 링크로 접근. +- **3대 잠정 설계 원칙:** ① 비(非)패밀리 조립 단위 ② 증분 인터랙티브 파라메트릭 ③ 선형·GIS 기반 좌표계. +- **MVP 원칙:** 기능 좁힘 + 품질 타협 없음. 철근은 v2. + +## 권위 문서 (Source of Truth) +상세 지침은 전부 분리 문서에 있다. 본 CLAUDE.md는 포인터만 제공. + +| 주제 | 문서 | +|---|---| +| **cimery 개발 지침** (기술 스택·코드 규약·함정·UX·구현 우선순위) | `Output/guides/cimery-dev-guide.md` | +| **아키텍처 결정(ADR)** | `Output/reports/ADR-001-tech-stack.md` · `ADR-002-feature-dsl.md` · `ADR-003-architecture-followups.md` | +| **위키 지식 저장소** | `wiki/index.md` | +| **Obsidian CLI 참조** | `Output/guides/obsidian-cli.md` | + +cimery 관련 작업 시작 시 `cimery-dev-guide.md`를 먼저 읽을 것. ADR과 지침이 충돌하면 **ADR 우선.** ## 위키 운영 규칙 (Karpathy LLM Wiki 패턴) - -폴더 구조: -- `raw/` — **불변 원본.** 인풋 유형별 하위 폴더(ai-research/papers/standards/tools/notes). 이 아래 파일은 **절대 수정·삭제 금지.** -- `wiki/` — **AI가 컴파일하는 위키 페이지.** 여기만 생성/수정 가능. `index.md`, `log.md` 포함. -- `Output/` — **결과물** (아키텍처 문서, 코드 초안, 조사 보고서 등). +**폴더:** +- `raw/` — 불변 원본. 수정·삭제 금지. +- `wiki/` — AI가 컴파일하는 위키 페이지 (`index.md`·`log.md` 포함). +- `Output/` — 결과물 (ADR·리포트·가이드). **10대 규칙:** -1. `raw/`는 절대 수정 금지 (불변 원본). -2. wiki 페이지 생성·삭제 시 `wiki/index.md` 필수 업데이트. -3. 모든 오퍼레이션마다 `wiki/log.md`에 기록. -4. 내부 참조는 **wikilink** 형식 (`[[페이지명]]`). -5. 모든 wiki 페이지 상단에 **YAML frontmatter** (title, tags, sources, updated). -6. 모순 발견 시 **양쪽 소스 모두 인용.** -7. 소스 요약은 **사실만**, 해석은 개념 페이지에서. +1. `raw/`는 절대 수정 금지. +2. wiki 페이지 생성·삭제 시 `wiki/index.md` 업데이트. +3. 오퍼레이션마다 `wiki/log.md` 기록. +4. 내부 참조는 wikilink `[[페이지명]]`. +5. wiki 페이지 상단 YAML frontmatter 필수. +6. 모순 발견 시 양쪽 소스 모두 인용. +7. 소스 요약은 사실만, 해석은 개념 페이지에서. 8. 질의 시 `wiki/index.md` 먼저, `raw/`는 마지막 수단. -9. **새 페이지보다 기존 페이지 업데이트 우선.** -10. `index.md` 항목은 **한 줄, 120자 이내.** +9. 새 페이지보다 기존 페이지 업데이트 우선. +10. `index.md` 항목은 한 줄, 120자 이내. -각 주요 폴더의 세부 규칙은 해당 폴더의 `CLAUDE.md` 참조. - -## Obsidian CLI 사용 - -이 프로젝트 볼트는 Obsidian 공식 CLI(1.12.4+)로 검색 가능. 파일시스템 grep보다 빠르고 Obsidian 인덱스·wikilink·백링크를 활용한다. - -**문법:** `obsidian key=value key=value` (Unix 플래그 아님) -값에 공백이 있으면 따옴표: `query="증분 파라메트릭"` - -**주요 명령:** -- `obsidian search query="<질의>" path=wiki` — 파일명 목록 반환 -- `obsidian search:context query="<질의>" path=wiki` — 매칭 라인 컨텍스트 포함 -- `obsidian read file="<페이지명>"` — 파일 내용 읽기 (wikilink 이름으로 해결) -- `obsidian backlinks file="<페이지명>"` — 백링크 조회 -- `obsidian outline file="<페이지명>"` — 헤딩 목록 -- `obsidian files folder=wiki` — wiki/ 파일 목록 -- `obsidian open file="<페이지명>"` — 앱에서 페이지 열기 -- `obsidian help` / `obsidian help ` — 전체·개별 도움말 - -**사용 원칙:** -- `wiki/` 검색 시 `obsidian search:context` 우선 (Obsidian 앱이 실행 중이어야 함). 미실행·미설치 시 Grep 폴백. -- 파일 읽기는 경로 대신 이름(`file=...`) 사용 가능 — Read 도구보다 wikilink 친화적. -- 복잡한 질의·개념 QA는 `query` skill이 상위 레이어 (index.md → 필요 시 CLI 보조). +각 폴더 세부 규칙은 해당 폴더의 `CLAUDE.md` 참조. diff --git a/Output/guides/cimery-dev-guide.md b/Output/guides/cimery-dev-guide.md new file mode 100644 index 0000000..1bbc3eb --- /dev/null +++ b/Output/guides/cimery-dev-guide.md @@ -0,0 +1,118 @@ +--- +title: cimery 개발 지침 +updated: 2026-04-14 +related-adr: + - "[[ADR-001-tech-stack]]" + - "[[ADR-002-feature-dsl]]" + - "[[ADR-003-architecture-followups]]" +--- + +# cimery 개발 지침 + +cimery 관련 작업 시 먼저 읽는 문서. CLAUDE.md에서 링크된다. + +## 권위 순서 (Source of Truth) +1. `Output/reports/ADR-001-tech-stack.md` — 기술 스택 +2. `Output/reports/ADR-002-feature-dsl.md` — Feature DSL 아키텍처 +3. `Output/reports/ADR-003-architecture-followups.md` — UI·IFC·CI/CD·USD·Plugin·Feature 카탈로그·LOD·UX 등 +4. 본 문서 — 지침 요약·규약 +5. `~/.claude/.../memory/` — 개인 선호·작업 방식 + +ADR과 본 문서가 충돌하면 **ADR 우선**. ADR 개정은 새 ADR로 수행 (`status: superseded-by:`). + +## 기술 스택 핵심 +- **언어:** Rust (전 계층) +- **UI:** Leptos + `` wgpu 3D 뷰포트 (Tauri v2 데스크톱 + PWA 웹 듀얼) +- **기하 커널:** OpenCascade.js(웹) / opencascade-rs(데스크톱), `GeomKernel` trait 추상화 +- **렌더:** wgpu → WebGPU (MVP Chromium 기반만) +- **IFC:** 런타임 `ifc-lite-core`, 검증용 `IfcOpenShell` +- **증분 계산:** `salsa` crate (Feature 단위 query, 비싼 sub-step만 개별) +- **IR 직렬화:** JSON 선행 → MessagePack 승격 +- **단위:** 자체 newtype (`Mm`, `M` 등), 경계 명시 변환 +- **FEM:** 자체 솔루션 연계 (외부 의존 최소) +- **파일 구조:** 폴더 기반 플레인 텍스트, AI·diff 친화 최우선 + +## 아키텍처 파이프라인 +``` +Rust DSL (builder + macro_rules! 설탕) + └─ #[param(unit, range, default)] attribute 메타 + ↓ +IR (JSON/MessagePack, 결정론적 직렬화) + ↓ +salsa query (Feature 단위, Lazy/Reactive) + ↓ +Evaluator → GeomKernel trait + ├─→ 자체 wgpu 뷰어 (주) + └─→ USD export (증분 Prim 단위, IFC alias 이중 태깅) +``` +CSV 라운드트립: 개발자 템플릿 → CSV export → 엔지니어 편집 → CSV import → DSL 소스 재생성. + +## 코드 규약 +- **단위 강제:** 구조물 `Mm`, 선형 `M`. 암묵 변환 금지. 경계 함수 시그니처에 명시. +- **Feature 파라미터 선언:** `#[param(unit="mm", range=10..=200, default=150)]` — AI 친화. +- **결정론:** 같은 IR → 같은 기하. 연산 순서 고정, 정렬된 입력만 통과. CI 1순위 테스트. +- **Feature 조합:** 2단 composite 허용, 공유 그래프 금지. +- **에러:** `Result<_, FeatureError>` + 경로 포함 메시지 (`girder_3.flange_thickness < web_thickness`). +- **검증:** 음수·단위 불일치는 타입 수준, 범위·상호제약은 런타임 `Result`. +- **테스트 4층 (MVP부터 필수):** + 1. IR 스냅샷 (`insta`) + 2. 기하 불변량 (부피·무게중심·바운딩박스·체크섬, 허용 오차) + 3. 두 커널 cross-check (OpenCascade.js ↔ opencascade-rs) + 4. `proptest` 속성 기반 (self-intersection 없음·부피 양수 등) + +## Revit UX 호환 +- 기본 마우스·키보드 조작, 리본·패널·속성창·뷰 큐브 = Revit 관습. +- 리본 12탭: Home·Alignment·Structure·Feature·Site&GIS·Annotate·Analyze·Construction·Insert·View·Manage·Modify. +- 2글자 keyin(VG·WT·ZE·SD) 보존 — **한글 IME 활성 시 입력 라우팅 주의.** +- 선택·필터: Category = **Feature kind**. cimery 고유 = 선형 기반 선택·규칙 선택·영향권 하이라이트. +- 개념 다른 영역은 "Revit Element ≠ cimery Feature instance"처럼 차이를 공식 문서화. + +## Feature 카탈로그 (MVP 거더교) +- **Must (v1):** Girder · Deck Slab · Pier · Abutment · Bearing · Alignment(입력) +- **Should (v1.1):** Cross Beam · Expansion Joint · Parapet +- **Could (v2):** Foundation · Approach Slab · Drainage +- **Won't (v3+):** 철근·사장교·현수교·아치·트러스 + +## 사용자 설정 (VS Code 3계층 모델) +``` +~/.cimery/settings.json # User 전역 +~/.cimery/keybindings.json # 키맵 분리 +/.cimery/settings.json # Project (Git 커밋) +/.cimery/settings.local.json # 개인 override (.gitignore) +``` +병합: Default ← User ← Project ← Project.local. 좌표계·tolerance는 **Project 전용 잠금.** + +## 구현 우선순위 — 엔드-투-엔드 수직 슬라이스 +**12개 ADR-003 결정을 동시 진행 금지.** +첫 **Girder 1개**로 전 계층(DSL → IR → salsa → evaluator → OCCT → wgpu → USD) **한 번 관통**한 뒤 수평 확장. 뷰어 한 달·DSL 한 달 식 수평 접근은 치명적. + +## 함정 체크리스트 +- 두 OCCT 백엔드 수치 미세 차이 → cross-check 조기 검증. +- 기하 연산 비결정성 → 결정론 테스트 CI 1순위. +- 대형 좌표 f32 정밀도 부족 → 내부 f64 + 프로젝트 원점 오프셋. GPU 전송 시 f32 + 원점 재계산. +- mm ↔ m 경계 타입 강제. +- Tauri WebView ≠ PWA 파일 I/O → 추상화 레이어 필수. +- WebGPU Safari/Firefox 미지원 → Chromium 전용 MVP, 사용자에 명확 고지. +- `ifc-lite-core` 단일 유지보수자 → 어댑터로 격리·핀·포크 정책. +- Tauri updater Ed25519 개인키 → HSM/Key Vault 수준 관리 (초기부터 계획). +- WASM 플러그인(v2 Extism) 무한 루프 → cooperative 중단 플래그. +- Revit 2글자 keyin vs 한글 IME → IME 상태 기반 입력 라우팅. + +## CI/CD·배포 (준비 단계) +- **메인 CI:** Gitea Actions (`.gitea/workflows/`). +- **Win/macOS 빌드·서명·릴리스:** GitHub Actions 미러. +- **업데이터:** Tauri v2 Ed25519 키쌍 + `latest.json` CDN. +- **Windows 서명:** Azure Trusted Signing 우선 검토. +- **채널:** `nightly` / `beta` / `stable` = Git 태그 prefix. +- **웹 배포:** Cloudflare Pages (별도 `cimery-web.pages.dev` 예정). + +## 프로젝트 구조 (예정) +``` +ParaWiki/ # 현 저장소 루트 +├── wiki/, raw/, Output/ # 지식 저장소 (기존) +└── cimery/ # 개발 시작 시 별도 서브프로젝트 + ├── CLAUDE.md # cimery 자체 세부 개발 지침 (본 문서 기반) + ├── Cargo.toml # workspace + └── crates/ # core / dsl / ir / kernel / ui / ... +``` +`cimery/` 디렉터리 생성 시 해당 폴더에 **세부 CLAUDE.md 작성** — 크레이트 의존 그래프, 빌드 명령, 코드 레이아웃, 기여 가이드. diff --git a/Output/guides/obsidian-cli.md b/Output/guides/obsidian-cli.md new file mode 100644 index 0000000..20ed2a8 --- /dev/null +++ b/Output/guides/obsidian-cli.md @@ -0,0 +1,27 @@ +--- +title: Obsidian CLI 참조 +updated: 2026-04-14 +--- + +# Obsidian CLI 참조 + +이 프로젝트 볼트는 Obsidian 공식 CLI(1.12.4+)로 검색 가능. 파일시스템 grep보다 빠르고 Obsidian 인덱스·wikilink·백링크를 활용한다. + +## 문법 +`obsidian key=value key=value` (Unix 플래그 아님) +값에 공백이 있으면 따옴표: `query="증분 파라메트릭"` + +## 주요 명령 +- `obsidian search query="<질의>" path=wiki` — 파일명 목록 반환 +- `obsidian search:context query="<질의>" path=wiki` — 매칭 라인 컨텍스트 포함 +- `obsidian read file="<페이지명>"` — 파일 내용 읽기 (wikilink 이름으로 해결) +- `obsidian backlinks file="<페이지명>"` — 백링크 조회 +- `obsidian outline file="<페이지명>"` — 헤딩 목록 +- `obsidian files folder=wiki` — 폴더 파일 목록 +- `obsidian open file="<페이지명>"` — 앱에서 페이지 열기 +- `obsidian help` / `obsidian help ` — 도움말 + +## 사용 원칙 +- `wiki/` 검색 시 `obsidian search:context` 우선 (Obsidian 앱 실행 필수). 미실행·미설치 시 Grep 폴백. +- 파일 읽기는 경로 대신 이름(`file=...`) 사용 가능 — Read 도구보다 wikilink 친화적. +- 복잡한 질의·개념 QA는 `query` skill이 상위 레이어 (index.md → 필요 시 CLI 보조). diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..24e072d --- /dev/null +++ b/PLAN.md @@ -0,0 +1,62 @@ +# PLAN.md — 앞으로 할 일 + +에이전트 시작 시 필독. 완료된 항목은 `PROGRESS.md`로 옮긴다. + +## 작성·갱신 규칙 +- 우선순위: **P0 (즉시)** · **P1 (다음 스프린트)** · **백로그** +- 항목 형식: `- [ ] 한 줄 설명 — (선택) 담당·의존 관계·참조 ADR` +- 작업 착수 시 `- [ ] → - [~]` (진행 중) 으로 바꾸고 담당/에이전트 메모. +- 완료 시 PROGRESS.md에 한 줄 추가하고 PLAN.md에서 제거. +- **새 과제 생길 때마다 우선순위대로 삽입.** 방치 금지. + +--- + +## 현재 스프린트 (Current) + +### P0 — 즉시 착수 +(없음 — 사용자 신호 대기) + +### P1 — 다음 단계 (사용자 승인 후 착수) +- [ ] **cimery 저장소 스캐폴딩** — Cargo workspace, crate 레이아웃(`core`/`dsl`/`ir`/`kernel`/`ui`), `cimery/CLAUDE.md` 작성. 참조: ADR-001·002·003. +- [ ] **첫 Girder 엔드-투-엔드 수직 슬라이스** — DSL → IR → salsa → evaluator → OCCT → wgpu → USD 한 번 관통. 참조: ADR-002 + cimery-dev-guide.md "구현 우선순위". + +--- + +## 백로그 (Backlog) + +### 지식 수집 (raw/) +- [ ] `raw/standards/ifc5-usd/` — bSI IFC5 + USD 전환 자료 (로드맵·워킹그룹) +- [ ] `raw/standards/openusd-aeco/` — AOUSD AECO IG 레퍼런스 +- [ ] `raw/tools/revit/` — Revit 조작 관습 표·단축키·UX 스크린샷 (로컬 매뉴얼 없음) + +### cimery 아키텍처·공용 크레이트 +- [ ] 단위 newtype 크레이트 (`Mm`·`M` 등) + 경계 함수 시그니처 규약 +- [ ] `GeomKernel` trait 설계 + OpenCascade.js·opencascade-rs 최소 구현 +- [ ] salsa Feature 단위 query 프로토타입 (IR 무효화·증분 재계산 검증) +- [ ] 테스트 4층 CI 골격 (insta·기하 불변량·두 커널 cross-check·proptest) +- [ ] Leptos + wgpu 뷰포트 프로토타입 (빈 뷰포트 + 리본 뼈대) +- [ ] CSV 라운드트립 최소 파이프라인 (`#[param]` 메타 → CSV → DSL 생성) + +### Feature 카탈로그 (MVP Must, 거더교 v1) +- [ ] Girder Feature 정의 (엔드-투-엔드 먼저, 위 P1에 연결) +- [ ] Deck Slab Feature 정의 +- [ ] Pier Feature 정의 +- [ ] Abutment Feature 정의 +- [ ] Bearing Feature 정의 +- [ ] Alignment 자체 포맷 로더 + +### 인프라·배포 +- [ ] Gitea Actions → GitHub Actions 미러 설정 (Win/macOS 빌드·서명·릴리스) +- [ ] Tauri v2 updater Ed25519 키 생성·시크릿 등록 +- [ ] Cloudflare Pages `cimery-web.pages.dev` 프로젝트 준비 +- [ ] Windows 코드서명 경로 확정 (Azure Trusted Signing) + +### ADR 개정 대상 +- [ ] ADR-003 B9(FEM) — 자체 솔루션 보유 반영하여 갱신. MIDAS·IFC SAV 전략의 비중 재조정. + +--- + +## 의존 관계 (Dependencies) +- P1의 "첫 Girder 엔드-투-엔드"는 **cimery 저장소 스캐폴딩** 선행. +- Feature 카탈로그 Must 6개 중 **Girder를 엔드-투-엔드 먼저**, 나머지는 후속 확장. +- WASM plugin 승격(A6 v2)은 **핵심 Feature 10개 이상 안정화** 후 게이팅. diff --git a/PROGRESS.md b/PROGRESS.md new file mode 100644 index 0000000..dc8037b --- /dev/null +++ b/PROGRESS.md @@ -0,0 +1,43 @@ +# PROGRESS.md — 완료 내역 + +시간 역순(최신이 위). 에이전트 시작 시 필독. 작업 완료 시 한 줄 추가. + +## 작성 규칙 +- 형식: `- YYYY-MM-DD [유형] 한 줄 설명` +- 유형: `adr` · `wiki` · `guide` · `meta`(구조·규칙) · `raw`(원본 수집) · `code`(cimery 코드) · `infra` +- 스냅샷 섹션은 의미 있는 변화가 생기면 갱신. + +--- + +## 타임라인 + +### 2026-04-14 +- meta — PLAN.md · PROGRESS.md 도입. 에이전트 간 작업 조정 프로토콜 확립. +- meta — CLAUDE.md 린화. 상세 지침을 `Output/guides/cimery-dev-guide.md` · `obsidian-cli.md`로 분리. 프롬프트 토큰 절감. +- adr — ADR-003 작성. 12개 후속 아키텍처 결정 (UI·IFC·CI/CD·USD·Alignment·Plugin·Feature 카탈로그·FEM·LOD·리본·선택/필터·설정). 병렬 조사 에이전트 기반. +- adr — ADR-002 작성. Feature DSL 아키텍처 20개 기본 결정 (Internal Rust DSL·IR·salsa·Lazy/Reactive·evaluator·테스트 4층·Revit UX 호환). +- adr — ADR-001 작성. 기술 스택 확정 (Rust + Tauri v2 + PWA 듀얼, OpenCascade.js/opencascade-rs, wgpu→WebGPU, `GeomKernel` trait). +- meta — Cloudflare Pages 자동 배포 워크플로 (`.gitea/workflows/publish.yml`, Quartz 4 빌드 → parawiki.pages.dev). +- meta — Pages 프로젝트 자동 생성 단계 추가. +- infra — Gitea Actions Runner 동작 확인용 ping 워크플로 추가. +- wiki — 위키 페이지 8건 컴파일: [[Revit 파라메트릭 아키텍처]] · [[GCS 기하학적 구속조건 솔버]] · [[PCE 파라메트릭 변경 엔진]] · [[파라메트릭 취약성 Davis 5가지]] · [[Revit 조립 단위 분류]] · [[특징 형상 기반 모델링 FBM]] · [[증분형 갱신 알고리즘 LPG]] · [[선형 GIS 기반 좌표계]]. +- meta — 위키 구조 초기화 (`raw/` · `wiki/` · `Output/`, Karpathy LLM Wiki 패턴). + +--- + +## 현재 스냅샷 (Snapshot — 2026-04-14) + +### 지식 저장소 (ParaWiki) +- 위키 페이지 **8건** (`wiki/index.md` 관리). +- ADR **3건** (`Output/reports/`). +- 개발 가이드 **2건** (`Output/guides/`). +- `wiki/log.md` 운영 중. +- `raw/` 수집 미개시 (PLAN.md 백로그 참조). + +### cimery 코드 +- **미작성.** 저장소 스캐폴딩 대기 (PLAN.md P1). + +### 아키텍처 결정 완성도 +- 기본 구조 결정(DSL·기술 스택·후속 12개) **완료**. +- 구현 고려사항(함정·체크리스트) 정리 완료. +- **미결·재검토:** FEM B9(자체 솔루션 보유 반영), IFC 5+USD 실제 표준화 진전 모니터링. diff --git a/wiki/log.md b/wiki/log.md index adbbb38..0edab4d 100644 --- a/wiki/log.md +++ b/wiki/log.md @@ -8,6 +8,8 @@ --- +- 2026-04-14 meta — PLAN.md · PROGRESS.md 도입. 에이전트 협업 프로토콜 확립. CLAUDE.md에 필독 섹션 추가. +- 2026-04-14 meta — CLAUDE.md 린화. 상세 지침을 Output/guides/cimery-dev-guide.md·Output/guides/obsidian-cli.md로 분리. 프롬프트 토큰 절감. - 2026-04-14 meta — ADR-003 후속 아키텍처 결정 작성. 12개 주제 병렬 조사 기반: UI(Leptos)·IFC(ifc-lite-core)·CI/CD(Gitea+GH 하이브리드)·USD(Codeless schema)·Alignment·Plugin(Extism→WIT)·Feature 카탈로그·FEM(MIDAS)·LOD 300·리본 12탭·선택/필터·설정 3계층. - 2026-04-14 meta — ADR-002 Feature DSL 아키텍처 작성 (Output/reports/). cimery DSL·IR·salsa·evaluator·Excel 라운드트립 등 20개 기본 결정. - 2026-04-14 meta — Cloudflare Pages 자동 배포 워크플로 추가 (.gitea/workflows/publish.yml). Quartz 4 빌드 → parawiki.pages.dev.