From 6089603b5687d08e16127f8789e1d0c9925417f6 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 23 Apr 2026 15:57:54 +0900 Subject: [PATCH 1/5] refactor(harness): drop SPEC.md from GUARDRAIL_FILES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 루트 SPEC.md 단일 파일 관행을 이슈 스코프 raw/design/specs/ski-NNN-*.md로 전환하기 위한 첫 단계. harness preamble 주입 대상에서 SPEC 제거. - scripts/execute.py GUARDRAIL_FILES tuple에서 "SPEC.md" 엔트리 제거 - tests/test_execute_script.py::test_load_guardrails_uses_repo_specific_documents fixture의 SPEC.md 생성 및 assertion 제거 이후 phase에서 skill/정책/문서가 raw/design/specs/ 경로를 가리키도록 업데이트되고 현재 uncommitted 루트 SPEC.md를 raw/design/specs/ski-011-*.md로 이동시킨다. Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/execute.py | 1 - tests/test_execute_script.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/scripts/execute.py b/scripts/execute.py index d37deea..0dd7988 100755 --- a/scripts/execute.py +++ b/scripts/execute.py @@ -25,7 +25,6 @@ GUARDRAIL_FILES = ( "AGENTS.md", "README.md", - "SPEC.md", ".agents/policies/local-adaptation.md", ) SubprocessRunner = Callable[..., subprocess.CompletedProcess[str] | Any] diff --git a/tests/test_execute_script.py b/tests/test_execute_script.py index f48c179..f05dcce 100644 --- a/tests/test_execute_script.py +++ b/tests/test_execute_script.py @@ -44,7 +44,6 @@ def test_load_guardrails_uses_repo_specific_documents(tmp_path: Path) -> None: (tmp_path / "AGENTS.md").write_text("# Repo Rules\nAGENTS content\n", encoding="utf-8") (tmp_path / "README.md").write_text("# Readme\nREADME content\n", encoding="utf-8") - (tmp_path / "SPEC.md").write_text("# Spec\nSPEC content\n", encoding="utf-8") policies_dir = tmp_path / ".agents" / "policies" policies_dir.mkdir(parents=True) (policies_dir / "local-adaptation.md").write_text( @@ -58,7 +57,6 @@ def test_load_guardrails_uses_repo_specific_documents(tmp_path: Path) -> None: assert "AGENTS content" in guardrails assert "README content" in guardrails - assert "SPEC content" in guardrails assert "Adaptation content" in guardrails From 30975f4cb6241f16ddc69aa9d1a9125c6eab9544 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 23 Apr 2026 15:58:38 +0900 Subject: [PATCH 2/5] docs(skills): retarget /spec and /plan to raw/design/specs/ski-NNN-*.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - spec SKILL.md: step 1에 raw/design/specs/ 파일명 스캔 추가, step 3을 이슈 스코프 ski-NNN-.md 생성으로 변경 - spec openai.yaml: default_prompt를 새 경로로 - plan SKILL.md: step 1을 raw/design/specs/ski-NNN-*.md 읽기로 - using-agent-skills SKILL.md: Repository Overrides의 spec artifacts 위치 기술을 raw/design/specs/ski-NNN-*.md로 교체 Co-Authored-By: Claude Opus 4.7 (1M context) --- .agents/skills/plan/SKILL.md | 2 +- .agents/skills/spec/SKILL.md | 4 ++-- .agents/skills/spec/agents/openai.yaml | 2 +- .agents/skills/using-agent-skills/SKILL.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.agents/skills/plan/SKILL.md b/.agents/skills/plan/SKILL.md index bb41a1a..cdc3fca 100644 --- a/.agents/skills/plan/SKILL.md +++ b/.agents/skills/plan/SKILL.md @@ -9,7 +9,7 @@ Use the `planning-and-task-breakdown` workflow for this repository. ## Procedure -1. Read `SPEC.md` if it exists, then inspect the relevant code and docs. +1. 사용자가 지정한 `raw/design/specs/ski-NNN-*.md`를 먼저 읽는다. 지정이 없으면 `raw/design/specs/` 하위에서 가장 최근 파일을 기준으로 확인한 뒤, 관련 코드와 문서를 검사한다. 2. Stay in read-only planning mode. 3. Identify the dependency graph between components. 4. Slice work vertically (one complete path per task) and draft tasks with acceptance criteria + verification steps. diff --git a/.agents/skills/spec/SKILL.md b/.agents/skills/spec/SKILL.md index 55cffab..4163bf2 100644 --- a/.agents/skills/spec/SKILL.md +++ b/.agents/skills/spec/SKILL.md @@ -9,9 +9,9 @@ Use the `spec-driven-development` workflow for this repository. ## Procedure -1. Read `AGENTS.md`, `README.md`, and `.agents/policies/local-adaptation.md`. +1. Read `AGENTS.md`, `README.md`, and `.agents/policies/local-adaptation.md`. `raw/design/specs/` 하위 파일명만 스캔해 다음 번호와 기존 패턴을 확인한다 (내용 선탐독 불필요). 2. Clarify the objective, acceptance criteria, constraints, and boundaries. -3. Produce a structured `SPEC.md` in the repository root. +3. 새 spec은 `raw/design/specs/ski-NNN-.md` 형식으로 생성한다. `NNN`은 3자리 zero-pad된 다음 번호, ``는 짧은 영어 kebab-case 요약. 4. Include repository-specific commands such as: - `uv run pytest` - `uv run ruff check .` diff --git a/.agents/skills/spec/agents/openai.yaml b/.agents/skills/spec/agents/openai.yaml index 7c4384a..62fe62a 100644 --- a/.agents/skills/spec/agents/openai.yaml +++ b/.agents/skills/spec/agents/openai.yaml @@ -1,5 +1,5 @@ interface: display_name: "Spec" short_description: "Write a structured spec before implementation" - default_prompt: "Use $spec to produce a repository-specific SPEC.md before implementation starts." + default_prompt: "Use $spec to produce a repository-specific issue-scoped spec under raw/design/specs/ski-NNN-.md before implementation starts." diff --git a/.agents/skills/using-agent-skills/SKILL.md b/.agents/skills/using-agent-skills/SKILL.md index 4cf2ed3..0840415 100644 --- a/.agents/skills/using-agent-skills/SKILL.md +++ b/.agents/skills/using-agent-skills/SKILL.md @@ -18,7 +18,7 @@ In this repository, the imported skill pack runs with these local rules: - Repository-specific command substitutions live in `.agents/policies/local-adaptation.md`. - Primary verification commands are `uv run pytest`, `uv run ruff check .`, `uv run mypy src`, and `uv run sid-reco doctor`. - Shared checklists live in `.agents/playbooks/`. -- Idea artifacts belong in `ideas/`; spec/task artifacts belong in `SPEC.md` and `tasks/`. +- Idea artifacts belong in `ideas/`; spec artifacts belong in `raw/design/specs/ski-NNN-*.md`; task artifacts belong in `tasks/`. ## Skill Discovery From d5aa0701c1003b14c24f1c9ea2d6fcc31c3d2c74 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 23 Apr 2026 16:01:24 +0900 Subject: [PATCH 3/5] docs(policy): retarget local-adaptation + READMEs to raw/design/specs/ski-NNN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이슈 스코프 spec 관행을 공식 convention으로 반영. - .agents/policies/local-adaptation.md: * /spec 설명에 raw/design/specs/ski-NNN-*.md 명시 * Output Locations에서 스펙 경로 갱신 * Language Conventions의 SPEC.md 대상을 raw/design/specs/**로 확장 - README.md / README.ko.md: Graphify 입력 제외 목록에서 SPEC.md 드롭 + raw/design/specs/가 source corpus임을 명시 - raw/README.md: 동일 반영 (운영 원칙 섹션) Co-Authored-By: Claude Opus 4.7 (1M context) --- .agents/policies/local-adaptation.md | 6 +++--- README.ko.md | 2 +- README.md | 2 +- raw/README.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.agents/policies/local-adaptation.md b/.agents/policies/local-adaptation.md index ee13cc1..c1bb3ed 100644 --- a/.agents/policies/local-adaptation.md +++ b/.agents/policies/local-adaptation.md @@ -77,7 +77,7 @@ uv run sid-reco compile-sid-index --help 공식 Codex App built-in slash command와는 별개로, enabled skill은 slash 목록에 나타날 수 있다. - `/docs-manager` 또는 `/doc-manager` — `raw/` source corpus 관리와 `README.md`, `AGENTS.md`, `.github/copilot-instructions.md`, `.agents/policies/local-adaptation.md` 동기화를 포함한 문서 반영 루틴 -- `/spec` — 구현 전에 `SPEC.md`를 정리하는 spec-driven workflow +- `/spec` — 구현 전에 `raw/design/specs/ski-NNN-*.md`를 정리하는 spec-driven workflow (이슈 단위 1 파일) - `/plan` — spec-driven workflow 후속 작업 분해 - `/build` — incremental-implementation + TDD 기반 구현 흐름 - `/test` — TDD / Prove-It 기반 검증 흐름 @@ -89,14 +89,14 @@ uv run sid-reco compile-sid-index --help ## Output Locations -- 스펙: `SPEC.md` +- 스펙: `raw/design/specs/ski-NNN-*.md` (이슈 단위 1 파일, ADR 네이밍 규약과 동일 패턴) - primary graph artifact: `graphify-out/` - source corpus: `raw/` ## Language Conventions - `raw/design/**` 문서는 한국어로 유지한다. -- `SPEC.md`, `tasks/plan.md`, `tasks/todo.md`는 신규 작성 또는 의미있는 개정 시 한국어로 작성한다. 기존 영어 내용은 즉시 번역할 의무는 없다. +- `raw/design/specs/**`, `tasks/plan.md`, `tasks/todo.md`는 신규 작성 또는 의미있는 개정 시 한국어로 작성한다. 기존 영어 내용은 즉시 번역할 의무는 없다. > graphify orchestration 세부(실행 경로, 커밋 산출물, BUILD_INFO trust signal, hooks auto-refresh 동작 등)는 [`.agents/skills/graphify-manager/SKILL.md`](../.agents/skills/graphify-manager/SKILL.md)를 참조한다. diff --git a/README.ko.md b/README.ko.md index 9b27da9..eebe5bf 100644 --- a/README.ko.md +++ b/README.ko.md @@ -342,7 +342,7 @@ source corpus: - `raw/design/` - `raw/external/` -Graphify 입력에는 `.agents/`, `README*`, `SPEC.md`, `CLAUDE.md`/`AGENTS.md`가 포함되지 않는다. +Graphify 입력에는 `.agents/`, `README*`, `CLAUDE.md`/`AGENTS.md`가 포함되지 않는다. 이슈 단위 스펙은 `raw/design/specs/ski-NNN-*.md`에 두고 source corpus의 일부로 취급한다. ## Copilot 및 Agent 하네스 diff --git a/README.md b/README.md index d12619b..38cca19 100644 --- a/README.md +++ b/README.md @@ -384,7 +384,7 @@ Source corpus: - `raw/design/` - `raw/external/` -Graphify does not treat `.agents/`, `README*`, `SPEC.md`, or `CLAUDE.md`/`AGENTS.md` as source input. +Graphify does not treat `.agents/`, `README*`, or `CLAUDE.md`/`AGENTS.md` as source input. Issue-scoped specs under `raw/design/specs/ski-NNN-*.md` are part of the source corpus. ## Copilot and Agent Harness diff --git a/raw/README.md b/raw/README.md index 1cf68d2..fad6ac2 100644 --- a/raw/README.md +++ b/raw/README.md @@ -19,4 +19,4 @@ - 설계 문서와 외부 자료는 `raw/` 아래에 계속 누적한다. - Graphify full refresh는 `src/`, `tests/`, `raw/`를 읽고 `graphify-out/`만 최신 상태로 갱신한다. -- `README.md`, `README.ko.md`, `SPEC.md`, `CLAUDE.md`/`AGENTS.md`는 source corpus가 아니라 결과/운영 문서다. +- `README.md`, `README.ko.md`, `CLAUDE.md`/`AGENTS.md`는 source corpus가 아니라 결과/운영 문서다. 이슈 단위 스펙은 `raw/design/specs/ski-NNN-*.md`에 두고 source corpus의 일부다. From 0a39f30e9cc10188c76374b5b24321436a8b70e9 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 23 Apr 2026 16:06:35 +0900 Subject: [PATCH 4/5] =?UTF-8?q?refactor(specs):=20move=20SPEC.md=20?= =?UTF-8?q?=E2=86=92=20raw/design/specs/ski-011-upstream-graphify-entrypoi?= =?UTF-8?q?nt.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이슈 스코프 spec 관행의 첫 실적용. 루트 SPEC.md 삭제 + 현재 uncommitted 상태였던 SKI-11 (upstream Graphify public entrypoint 복구) 스펙 내용을 이슈 파일로 보존. - git mv로 rename 추적: 루트 SPEC.md → raw/design/specs/ski-011-*.md - working tree의 SKI-11 내용을 새 경로에 복원 (HEAD의 SKI-10 버전은 git history로 추적 가능) - 이동된 파일 내부 자기참조 3곳 정리: * line 5 가정 1: 루트 SPEC.md 교체 → 마이그레이션 맥락으로 재진술 * line 62 비목표: Graphify source input 승격 목록에서 SPEC.md 드롭 * line 160: non-source 디렉토리 bullet에서 SPEC.md 엔트리 삭제 이제 `.graphifyignore`가 `raw/`를 제외하지 않으므로 다음 graphify refresh에서 이 spec이 자동으로 source corpus에 포함된다. Co-Authored-By: Claude Opus 4.7 (1M context) --- SPEC.md | 446 ------------------ .../ski-011-upstream-graphify-entrypoint.md | 295 ++++++++++++ 2 files changed, 295 insertions(+), 446 deletions(-) delete mode 100644 SPEC.md create mode 100644 raw/design/specs/ski-011-upstream-graphify-entrypoint.md diff --git a/SPEC.md b/SPEC.md deleted file mode 100644 index 0336cd0..0000000 --- a/SPEC.md +++ /dev/null @@ -1,446 +0,0 @@ -# 스펙: SKI-10 — Query-SID 런타임 재현 - -## 가정 (Assumptions I'm Making) - -1. 이 기능은 기존 Phase 1 `compile-sid-index`와 Phase 2 `recommend` 파이프라인 위에서 동작한다. 둘 다 이미 구현되어 운영 중이다. -2. `train_codebooks`가 학습한 residual K-means quantizer(`TrainedResidualCodebooks`)는 현재 할당 직후 버려진다. 이 스펙은 이 quantizer에 1급 저장과 런타임 재사용을 부여한다. -3. 런타임 query는 catalog item과 **같은 SID 공간**에 떨어져야 한다 — 같은 codebook, 같은 정규화 규칙, 같은 residual 시퀀스. 그렇지 않으면 `query_sid`를 item SID와 비교할 수 없다. -4. `apps/demo`는 실제 Phase 1 artifact를 읽지 않는 브라우저-로컬 mock 파이프라인이다. 이 스펙은 데이터 소스가 아니라 계약 shape만 조정한다. -5. 기존 `id_map.jsonl`은 이미 item별 `sid_path`를 기록한다. 런타임은 현재 `sid_string`만 로드한다. 이 스펙은 `sid_path`를 검증하고 파이프라인 전체에 보존한다. -6. 이 스펙은 retrieval score, adaptive radius, bootstrap rerank 정책, confidence aggregation을 수정하지 않는다. 이들은 명시적으로 범위 밖이고 후속 이슈로 남긴다. -7. 분할 PR보다 단일 PR을 선호한다 — 타입 리팩터와 런타임 재현은 같은 주제다. -8. 기본 출력 디렉터리 `data/processed/foodcom/sid_index/`는 이미 `data/processed/*`로 `.gitignore` 처리되어 있다. 이 스펙은 새 gitignore 규칙을 추가하지 않는다. - -## 목표 (Objective) - -런타임 추천 query를 retrieval 대상 catalog item과 재현 가능하게 같은 계층적 SID 공간에 떨어지게 만들고, 그 할당을 추천 응답의 1급 필드로 노출한다. - -구체적으로: - -1. `compile-sid-index`가 학습한 residual K-means quantizer를 런타임 artifact(`residual_codebooks.npz` + `residual_codebooks_manifest.json`)로 저장한다. -2. `recommend` 내부에서 이 quantizer를 로드하고, taxonomy-aligned query 벡터를 **컴파일 시점과 완전히 동일한 residual 정규화 규칙**으로 계층적 SID path에 할당한다. -3. 결과 `query_sid`를 `SemanticSearchResult`, `RecommendationResponse`, `recommend` CLI, `apps/demo` mock 파이프라인 shape에 노출한다. -4. 그 과정에서 SID 타입 레이어를 정리해 `ItemSID` / `QuerySID` 두 구체 타입만 남기고, 중복된 `CompiledSIDItems` 번들 타입과 장황한 함수명을 제거한다. - -제품 효과는 모든 추천 응답이 query 자신의 SID 좌표를 함께 가지고 나가는 것이다. 이는 향후 query-SID locality를 활용하는 검색 반경·그룹 confidence·rerank prior 작업(명시적으로 유보)의 기초가 된다. - -## 비목표 (Non-Goals) - -이 스펙은 **다음을 포함하지 않는다**: - -- `query_sid` 기반 FAISS score·retrieval `k`·survivor cap 조정 -- `query_sid` 근접성에 연동된 adaptive 검색 반경 -- SID-group confidence aggregation -- bootstrap rerank pass 수·selection size·prompt 내용 변경 -- grounding·최종 payload 조립 변경 -- 어떤 모델의 학습 혹은 파인튜닝 -- `apps/demo`가 실제 artifact를 소비하도록 재작성 -- `TrainedResidualCodebooks`를 `SIDSpace`로 리네임 (유보 — 본 범위에서 구조적 이득 없이 비용만 발생) -- `compile-sid-index` CLI 명령 이름 변경 (사용자 워크플로 영향) - -## 타입 시스템 리팩터 (Type System Refactor) - -런타임 작업의 구조적 전제 조건이며 같은 PR에 묶는다. - -### Before - -``` -TrainedResidualCodebooks # quantizer -CompiledSIDItem # recipe_id + sid_path + sid_string -CompiledSIDItems # items + branching_factor + depth + embedding_dim + levels - # ^ 4개 필드가 TrainedResidualCodebooks와 중복 -``` - -### After - -``` -TrainedResidualCodebooks # quantizer — 유지, 저장 대상으로 승격 -ItemSID # recipe_id + sid_path + sid_string (CompiledSIDItem 대체) -QuerySID # sid_path + sid_string (신규) -# CompiledSIDItems 삭제. -# compile_residual_kmeans 편의 래퍼 삭제. -# base dataclass 없음 — 두 타입 사이의 2필드 중복은 수용(4줄). -``` - -근거: - -- `item`과 `query`는 실제 코드에서 공통 호출자가 없다. 두 타입을 `isinstance(x, SomeBase)`로 묶어야 할 자리가 현재도 이번 범위에서도 없으므로 base dataclass는 비용 대비 이득이 없다. -- 삭제되는 `CompiledSIDItems` 번들 타입은 `TrainedResidualCodebooks`가 이미 소유한 4개 필드를 중복 보관한다. 제거하면 공간-shape 메타데이터의 단일 진실 원천이 quantizer로 집중된다. -- 편의 래퍼는 호출처가 두 곳(CLI + 테스트 한 곳)이다. 두 줄의 명시적 호출로 대체하는 편이 codebook 반환값을 숨기는 얇은 indirection을 유지하는 것보다 저렴하다. -- 함수 이름에서 `_trained_`, `_residual_`, `assign_*_to_sid` 같은 장황한 수식어는 `TrainedResidualCodebooks` 타입 이름이 이미 전달하므로 제거한다. 남는 이름은 동사(`train`/`write`/`load`/`build`) + 대상으로 간결하다. - -Python 측 제약: - -- `ItemSID`와 `QuerySID`는 각각 독립 `@dataclass(frozen=True, slots=True)`이며 상속을 쓰지 않는다. frozen+slots 상속의 함정을 원천 배제한다. -- `CompiledSIDItem` / `CompiledSIDItems` 삭제는 hard rename이다 — backward-compat alias 없음. 저장소의 "backwards-compat 우회 금지" 관례에 따른다. - -## 런타임 artifact 계약 (Runtime Artifact Contract) - -모든 신규 artifact는 기존 `sid_index_dir`(기본 `data/processed/foodcom/sid_index/`) 안에 저장한다. - -### `residual_codebooks.npz` - -NumPy archive, float32. 키: - -- `branching_factor` — scalar int32 -- `depth` — scalar int32 -- `embedding_dim` — scalar int32 -- `normalize_residuals` — scalar int32 (0/1) -- `level_{i}_centroids` (`i ∈ 1..depth`) — shape `(cluster_count_i, embedding_dim)` -- `level_{i}_cluster_sizes` (`i ∈ 1..depth`) — shape `(cluster_count_i,)` int32 -- `level_{i}_iteration_count` (`i ∈ 1..depth`) — scalar int32 -- `level_{i}_inertia` (`i ∈ 1..depth`) — scalar float32 - -단일 NPZ 레이아웃은 quantizer를 한 파일로 유지하면서 `ResidualKMeansLevel`이 이미 가진 per-level replay 메타데이터를 보존한다. - -### `residual_codebooks_manifest.json` - -작고 사람이 읽기 좋은 JSON(정렬): - -```json -{ - "branching_factor": 256, - "depth": 3, - "embedding_dim": 3584, - "normalize_residuals": true, - "level_cluster_counts": [256, 256, 256], - "codebooks_path": "residual_codebooks.npz" -} -``` - -`codebooks_path`는 **`sid_index_dir` 기준 상대 파일명**이다. 절대경로 금지. - -### 상위 `manifest.json` 갱신 - -기존 키는 모두 유지. 신규 키를 append만 한다: - -- `normalize_residuals` (bool) -- `codebooks_path` (상대 파일명, 예: `"residual_codebooks.npz"`) -- `codebooks_manifest_path` (상대 파일명, 예: `"residual_codebooks_manifest.json"`) - -기존 manifest 키는 rename·삭제하지 않는다. - -### 로드 시 검증 - -`load_codebooks`는 다음을 검증해야 한다: - -- NPZ 키가 manifest의 `branching_factor`, `depth`, `embedding_dim`, `normalize_residuals`, `level_cluster_counts`와 존재·일관성 모두 맞는다. -- 불일치 시 `ValueError`를 던지며, 메시지에 충돌 필드명과 `compile-sid-index` 재실행 안내를 포함한다. -- 파일 부재는 `FileNotFoundError`로 remediation hint와 함께 던진다(silent downgrade 금지). - -## 공개 인터페이스 (Public Interfaces) - -### `sid_reco.sid.compiler` - -```python -@dataclass(frozen=True, slots=True) -class ItemSID: - sid_path: tuple[int, ...] - sid_string: str - recipe_id: int - -@dataclass(frozen=True, slots=True) -class QuerySID: - sid_path: tuple[int, ...] - sid_string: str - -def train_codebooks(matrix, *, branching_factor=256, depth=3, - normalize_residuals=True, max_iter=50, - tolerance=1e-6) -> TrainedResidualCodebooks: ... - -def build_item_sids(recipe_ids, matrix, *, - codebooks: TrainedResidualCodebooks - ) -> list[ItemSID]: ... - -def build_query_sid(vector, *, - codebooks: TrainedResidualCodebooks - ) -> QuerySID: ... - -def write_codebooks(codebooks: TrainedResidualCodebooks, *, - out_dir: Path) -> tuple[Path, Path]: - """(npz_path, manifest_path) 반환. 둘 다 out_dir 안.""" - -def load_codebooks(npz_path: Path) -> TrainedResidualCodebooks: - """NPZ에서 quantizer 로드, 형제 manifest와 교차 검증.""" -``` - -`compile_residual_kmeans`, `assign_trained_residual_kmeans`는 삭제한다. -`train_residual_codebooks`는 `train_codebooks`로 rename한다 (의미는 `TrainedResidualCodebooks` 타입에 이미 드러남). - -### `sid_reco.sid.indexing` - -```python -@dataclass(frozen=True, slots=True) -class SIDIndexWriteSummary: - item_count: int - embedding_dim: int - compiled_sid_path: Path - item_to_sid_path: Path - sid_to_items_path: Path - id_map_path: Path - index_path: Path - manifest_path: Path - codebooks_path: Path # 신규 - codebooks_manifest_path: Path # 신규 - -def write_sid_index_outputs( - *, - embedded: EmbeddedSIDItems, - codebooks: TrainedResidualCodebooks, - items: list[ItemSID], - out_dir: Path, -) -> SIDIndexWriteSummary: ... -``` - -### `sid_reco.recommendation.semantic_search` - -```python -@dataclass(frozen=True, slots=True) -class SemanticCandidate: - faiss_idx: int - recipe_id: int - sid_string: str - sid_path: tuple[int, ...] # 신규 — id_map.jsonl에서 보존 - score: float - serialized_text: str - taxonomy: Mapping[str, tuple[str, ...]] - popularity: int - cooccurrence_with_history: int - -@dataclass(frozen=True, slots=True) -class SemanticSearchResult: - query_text: str - query_sid: QuerySID # 신규 - candidates: tuple[SemanticCandidate, ...] - dropped_candidates: tuple[DroppedCandidate, ...] - retrieved_count: int - survivor_count: int - low_coverage: bool -``` - -내부 변경: encoder 호출이 `raw_vector`를 생성한다. FAISS는 정규화된 사본(기존 동작)을 사용한다. query-SID 할당에는 `raw_vector`를 그대로 쓴다 — quantizer가 학습 시 본 분포와 동일해야 하기 때문. - -### `sid_reco.recommendation.types` - -```python -@dataclass(frozen=True, slots=True) -class RecommendationResponse: - sketch: InterestSketch - items: tuple[RecommendedItem, ...] - rerank_summary: str - confidence_summary: str - selected_candidate_indices: tuple[int, ...] - query_sid: QuerySID # 신규 -``` - -### CLI - -`compile-sid-index` 결과 테이블에 한 행 추가: - -- `Codebooks path` → `residual_codebooks.npz` 상대 경로 - -`recommend` 결과 블록의 기존 summary 아래 한 줄 추가: - -- `Query SID: path=` - -### `apps/demo` - -`window.runPipeline(...)` 반환 shape에 다음 추가: - -- `conf.items[i].sid_path: number[]` — mock 계층 경로(기존 `buildSid`가 문자열과 path 모두 반환하도록 확장) -- `conf.query_sid: { sid_string: string, sid_path: number[] }` — sketch facets에서 mock으로 도출 - -`i18n.js` JSON preview와 overview grid copy는 신규 필드가 실제로 노출되는 위치에서만 확장. 그 외 가시 copy 변경 없음. - -## 명령 (Commands) - -### 기존 검증 명령 (변경 없음) - -```bash -uv sync --all-groups -uv run pytest -uv run ruff check . -uv run mypy src -uv run sid-reco doctor -``` - -### 이 스펙을 위한 타겟 검증 - -```bash -uv run pytest tests/test_sid_compiler.py tests/test_sid_indexing.py \ - tests/test_cli_compile_sid_index.py tests/test_semantic_search.py \ - tests/test_recommendation_pipeline.py tests/test_cli_recommend.py -uv run ruff check . -uv run mypy src -node apps/demo/tests/pipeline.test.cjs -node apps/demo/tests/i18n.test.cjs -``` - -### End-to-end smoke (선택, MLX 환경 필요) - -```bash -uv run sid-reco compile-sid-index --out-dir data/processed/foodcom/sid_index -uv run sid-reco recommend --query "cozy weeknight vegetarian dinner" --top-k 3 -``` - -## 프로젝트 구조 (Project Structure) - -### 수정 파일 - -```text -src/sid_reco/sid/compiler.py -> 타입 rename, 새 helper, persistence, query 할당 -src/sid_reco/sid/indexing.py -> 시그니처 변경, codebook artifact write, summary 필드 추가 -src/sid_reco/sid/__init__.py -> export 갱신 -src/sid_reco/recommendation/semantic_search.py - -> codebook 로드, query_sid 계산, candidate sid_path 보존 -src/sid_reco/recommendation/types.py -> RecommendationResponse.query_sid -src/sid_reco/recommendation/pipeline.py -> query_sid를 응답까지 전달 -src/sid_reco/recommendation/__init__.py -> 필요시 QuerySID re-export -src/sid_reco/cli.py -> compile-sid-index 호출 정리, recommend 출력 라인 추가 -apps/demo/data/pipeline.js -> buildSid + runPipeline shape 확장 -apps/demo/src/app.jsx (최소) -> query_sid를 결과/JSON preview에 렌더 (신규 필드 노출 위치만) -apps/demo/src/i18n.js -> 신규 필드가 나타나는 EN/KR 라벨 -tests/test_sid_compiler.py -> codebook round-trip + query-SID 재현성 -tests/test_sid_indexing.py -> 신규 artifact 파일 + summary 필드 + manifest 키 -tests/test_cli_compile_sid_index.py -> CLI 출력의 codebook path 확인 -tests/test_semantic_search.py -> query_sid + candidate sid_path + missing-codebook 에러 -tests/test_recommendation_pipeline.py -> 응답이 query_sid 포함 -tests/test_cli_recommend.py -> CLI가 query_sid 라인 출력 -apps/demo/tests/pipeline.test.cjs -> mock pipeline shape에 query_sid 포함 -apps/demo/tests/i18n.test.cjs -> 신규 라벨의 EN/KR 동기화 -``` - -### 신규 파일 - -없음. 모든 변경이 기존 모듈에 들어간다. - -### 설계 노트 (`raw/design/notes/`, 한국어) - -구현 후 `docs-manager`를 통해 갱신: - -- `sid-compilation-indexing.md` — 출력 목록에 codebook artifact 추가 -- `phase2-recommendation-runtime.md` — 런타임 계약에 `query_sid` 추가 -- `phase2-recommendation-runtime-validation.md` — 신규 테스트 목록 추가 - -이들은 raw/ 수정이므로 staged Graphify full-refresh 흐름을 트리거한다. 코드 PR의 자동 refresh에 포함되지 않는다. - -## 코드 스타일 (Code Style) - -저장소의 기존 관례를 계승한다: - -- 각 Python 파일 최상단에 `from __future__ import annotations` -- 계약 타입은 `@dataclass(frozen=True, slots=True)` -- I/O는 `Path` 기반. `os.path` 금지. -- CLI는 `typer` + `rich`, 결과는 `rich.table.Table` -- rename/삭제된 타입에 대한 backward-compat shim 금지 — 삭제하고 모든 호출처 갱신 -- 누락·무효 artifact에 대한 silent fallback 금지 — remediation 메시지와 함께 raise -- 타입이 이미 드러내는 *무엇*에 대한 주석 금지; 비자명한 *왜*만 한 줄 - -이 스펙 특화: - -- `build_query_sid`는 `normalize_residuals=True`일 때 **raw(L2 정규화 전) encoder output**을 사용해야 한다. `_prepare_level_inputs`가 이미 per-level residual을 정규화하기 때문에 query에서 추가 정규화를 하면 컴파일 시점과 분포가 어긋난다. -- NPZ round-trip은 float32 centroid 기준 비트-동일이어야 한다. 정밀도 손실 금지. - -## 테스트 전략 (Testing Strategy) - -### 프레임워크 - -Python은 `pytest` + `ruff` + `mypy`, `apps/demo`는 `node` + 프로젝트 기존 CJS loader. - -### 테스트 매트릭스 - -1. **`tests/test_sid_compiler.py`** - - 타입: `ItemSID`, `QuerySID`가 예상대로 생성·비교된다. - - Round-trip: `write_codebooks` → `load_codebooks` 결과가 원본과 구조적으로 동치(centroid `allclose`, 메타데이터 동일). - - **재현성 (핵심 정합성)**: 임베딩 행렬 `M`, codebooks `C = train_codebooks(M)`, `items = build_item_sids(ids, M, codebooks=C)` 에서 모든 행 `k`에 대해 `build_query_sid(M[k], codebooks=C).sid_path == items[k].sid_path`. - - 무효 artifact: 잘린 NPZ, `embedding_dim` 불일치 manifest, 형제 manifest 부재 — 각각 충돌 필드명을 명시하는 `ValueError`. - -2. **`tests/test_sid_indexing.py`** - - `write_sid_index_outputs(codebooks=..., items=...)`가 `residual_codebooks.npz`와 `residual_codebooks_manifest.json` 둘 다 쓴다. - - `SIDIndexWriteSummary`에 두 신규 path 노출. - - 상위 `manifest.json`이 세 신규 키(상대 경로)를 가진다. - - 기존 artifact 계약(compiled_sid.jsonl, id_map.jsonl, item_index.faiss 등) 불변 — 기대 스키마와 명시 동등성 검사. - -3. **`tests/test_cli_compile_sid_index.py`** - - CLI 실행 후 두 codebook 파일이 `out_dir`에 존재. - - CLI `rich` 출력이 상대 파일명과 함께 `Codebooks path` 행을 포함. - -4. **`tests/test_semantic_search.py`** - - query 벡터가 fixture item 임베딩과 동일할 때 `SemanticSearchResult.query_sid`가 그 item의 `sid_path`와 같은 `QuerySID`. - - `SemanticCandidate.sid_path` tuple이 해당 `faiss_idx`의 `id_map.jsonl` 기록과 일치. - - codebook artifact 부재 시 FAISS 검색 이전에 clear error. - -5. **`tests/test_recommendation_pipeline.py` / `tests/test_cli_recommend.py`** - - stubbed generator/encoder로 `RecommendationResponse.query_sid`가 end-to-end 채워진다. - - `recommend` CLI 출력에 `Query SID:` 라인과 예상 `sid_string` 포함. - - rerank summary, confidence summary, 아이템 rank가 변경 전 baseline과 바이트-동일("동작 변화 없음" 회귀 가드). - -6. **`apps/demo/tests/pipeline.test.cjs`** - - `runPipeline(...)` 반환에 `conf.query_sid.sid_string`, `conf.query_sid.sid_path` 존재. - - 모든 `conf.items[i]`에 기존 `sid` 문자열 외에 `sid_path: number[]` 존재. - -7. **`apps/demo/tests/i18n.test.cjs`** - - EN, KR 로케일 모두 신규 라벨 키를 가진다 — 로케일 drift 없음. - -### 커버리지 태도 - -모든 신규 공개 함수와 신규 응답 필드는 직접 테스트를 가진다. **재현성 테스트**(항목 1 서브 3)가 단일 최중요 게이트다 — 런타임과 컴파일 경로가 하나의 SID 공간을 공유함을 증명한다. - -## 경계 (Boundaries) - -### Always - -- `TrainedResidualCodebooks`를 `sid_index_dir` 안의 1급 artifact로 저장한다. -- query 시점의 residual 정규화 규칙을 컴파일 시점과 동일하게 사용한다 — 코드 기본값이 아니라 저장된 manifest에서 읽는다. -- `id_map.jsonl`의 `sid_path`를 `SemanticCandidate`에 보존·전달한다. -- codebook artifact 누락·불일치 시 remediation 메시지와 함께 raise. -- manifest의 모든 artifact 경로는 `sid_index_dir` 기준 **상대 파일명**. -- 기존 retrieval, rerank, confidence, grounding 동작을 완전히 동일하게 유지. -- rename/삭제된 타입·함수를 깔끔히 제거 — alias 금지, re-export 금지, stub 주석 금지. - -### Ask first - -- 기본 출력 디렉터리 변경. -- 스펙 수락 이후 NPZ 키 레이아웃 변경(사용자가 컴파일한 시점부터 artifact 호환성 깨짐). -- `TrainedResidualCodebooks`를 `SIDSpace` 등으로 rename. -- `compile-sid-index` CLI 명령 이름 변경. -- `query_sid`를 retrieval scoring 입력으로 승격(명시 유보). - -### Never - -- codebook artifact 부재 시 silent downgrade — query-SID를 건너뛰는 "best-effort" 경로 금지. -- 추천 시점에 codebook을 다시 학습. -- query 벡터의 정규화를 컴파일 시점 level-input residual 정규화와 다르게 적용. -- manifest에 절대경로 기재. -- `item_index.faiss`, retrieval `k`, survivor cap, rerank prompt, grounding 로직 수정. -- compat alias(`CompiledSIDItem = ItemSID`) 도입 — rename은 hard cut. -- `apps/demo` mock 파이프라인을 권위 있는 동작으로 취급 — shape 계약 맞춤 용도로만 존재. - -## 성공 기준 (Success Criteria) - -1. `compile-sid-index`가 `sid_index_dir`에 `residual_codebooks.npz`와 `residual_codebooks_manifest.json`을 쓰고, 상위 `manifest.json`에 상대 경로 항목을 기록한다. -2. `load_codebooks`가 quantizer를 비트-정확하게 round-trip(centroid `allclose`, 메타데이터 동일). -3. 임의의 catalog 임베딩 행 `M[k]`에 대해 `build_query_sid(M[k], codebooks=C)`가 같은 row의 컴파일된 item과 동일한 `sid_path`를 반환. 직접 테스트로 보장. -4. `SemanticSearchResult`가 `query_sid: QuerySID`를 가지고, 각 `SemanticCandidate`가 `sid_path: tuple[int, ...]`를 가진다. -5. `RecommendationResponse`가 `query_sid: QuerySID`를 가지고, `recommend` CLI가 출력한다. -6. 누락·불일치 codebook artifact는 remediation 텍스트가 포함된 지정 에러를 raise. silent fallback 없음. -7. 동일 stubbed LLM/encoder fixture에서 rerank summary, confidence summary, ranked `recipe_id`, grounded payload가 변경 전 baseline과 동일. -8. `apps/demo/data/pipeline.js` 반환 shape에 `query_sid`와 per-candidate `sid_path`가 포함되고 `i18n.js` 두 로케일이 동기. -9. `src/`, `tests/` 어디에도 `CompiledSIDItem`, `CompiledSIDItems`, `compile_residual_kmeans`, `assign_trained_residual_kmeans`, `train_residual_codebooks`, `write_trained_codebooks`, `load_trained_codebooks`, `assign_items_to_sid`, `assign_query_embedding_to_sid`가 import되지 않는다. -10. `uv run pytest`, `uv run ruff check .`, `uv run mypy src`가 모두 통과하고 `apps/demo/tests/*.cjs` 통과. - -## 확정 결정 (Resolved Decisions) - -1. **NPZ 키 인덱싱** — 1-based (`level_1_*` ... `level_N_*`). [src/sid_reco/sid/compiler.py:121](src/sid_reco/sid/compiler.py:121)의 기존 `ResidualKMeansLevel.level` 관례와 일치. -2. **할당 타입 구조** — `ItemSID`·`QuerySID` 두 구체 dataclass만 둔다. base dataclass 없음. 공통 필드 `sid_path`·`sid_string`의 2필드 중복(총 4줄)은 상속 인프라보다 저렴하고, 실제 코드에 두 타입을 공통으로 다루는 호출자가 없다. -3. **함수 네이밍** — `_trained_`·`_residual_` 수식어는 `TrainedResidualCodebooks` 타입 이름이 이미 전달하므로 함수에서 제거. `assign_*_to_sid`의 `assign_` 접두사는 `build_*_sids` / `build_*_sid` 동사로 대체. 결과: `train_codebooks`, `write_codebooks`, `load_codebooks`, `build_item_sids`, `build_query_sid`. -4. **`apps/demo` mock `query_sid`** — `buildSid` 패턴에 `QSID::` 접두사를 붙여 재사용하며 `sketch.positive_facets` 슬롯(cuisine → dish_type → flavor_profile)을 입력으로 한다. 슬롯 부재 시 `"any"`로 fallback. mock 전용. -5. **codebook artifact 에러 타입** — 파일 부재는 built-in `FileNotFoundError`, 스키마·shape 불일치는 `ValueError`. 기존 `_load_id_map` 관례와 일치. silent downgrade 방지를 위해 메시지에 재실행 명령 `uv run sid-reco compile-sid-index --out-dir ` 반드시 포함. -6. **raw/design/notes** — 이 PR에서 제외. 후속 `docs-manager` pass에서 `sid-compilation-indexing.md`, `phase2-recommendation-runtime.md`, `phase2-recommendation-runtime-validation.md`를 갱신하고 staged Graphify full refresh를 실행한다. - -## 리뷰용 구현 노트 (Implementation Notes for Review) - -- 이 스펙은 이전에 `SPEC.md`를 채우던 Phase 2 end-to-end 스펙을 대체한다. Phase 2 내용은 `src/sid_reco/recommendation/` 하위 실구현 코드로 landed 되었고 의도는 `raw/design/notes/phase2-recommendation-runtime.md`와 AGENTS.md 모듈 테이블에 남는다. -- 단일 묶음 PR. 타입·네이밍 정리와 런타임 재현이 함께 간다 — 런타임 기능이 `QuerySID`·`build_query_sid`를 도입하고, 정리가 `ItemSID`·`build_item_sids`의 명명·책임 경계를 확정하기 때문이다. -- `raw/design/notes/` 갱신은 코드 PR에서 의도적으로 분리되어 후속 `docs-manager` pass로 넘긴다. 이는 staged Graphify full-refresh가 안정된 코드 트리 위에서 실행되도록 하기 위함이다. -- 이 스펙이 리뷰·수락되기 전에는 구현에 착수하지 않는다. diff --git a/raw/design/specs/ski-011-upstream-graphify-entrypoint.md b/raw/design/specs/ski-011-upstream-graphify-entrypoint.md new file mode 100644 index 0000000..26e86bc --- /dev/null +++ b/raw/design/specs/ski-011-upstream-graphify-entrypoint.md @@ -0,0 +1,295 @@ +# 스펙: SKI-11 — upstream Graphify public entrypoint 복구 + +## 가정 (Assumptions I'm Making) + +1. 이 스펙은 루트 `SPEC.md` 단일 파일 관행을 `raw/design/specs/ski-NNN-*.md` 이슈 스코프 레이아웃으로 대체하는 마이그레이션(SKI 구조 전환) 이후 작성되었다. +2. 실제 구현은 전용 branch/worktree에서 진행한다. 이 스펙은 그 전제를 포함한다. +3. integration 기준선은 repo-local wrapper가 아니라 upstream Graphify가 제공하는 다음 install surface다. + - `graphify claude install` + - `graphify codex install` + - `graphify opencode install` +4. 이 저장소의 3-레이어 모델(`AGENTS.md` / `graphify-out/` / `raw/`)과 `raw/` source boundary는 유지한다. +5. 현재의 staged full refresh, verify, sync, `BUILD_INFO.json` trust signal은 의도된 guardrail이며 제거 대상이 아니다. +6. 현재 public surface인 `/graphify-manager`, `/graphify-full`는 migration 완료 후 제거 대상이다. +7. upstream가 생성하는 얇은 `AGENTS.md`/`CLAUDE.md`/hook 자산은 이 저장소의 richer schema와 안전 훅을 **통째로 대체할 수 없고**, merge/composition 대상으로 다뤄야 한다. + +## 목표 (Objective) + +이 작업의 목표는 **original/upstream Graphify의 기본 UX를 `/graphify` 단일 public entrypoint로 복구**하면서도, +현재 저장소가 이미 갖고 있는 curated corpus와 verify gate를 그대로 보존하는 것이다. + +구체적으로: + +1. `/graphify`를 이 저장소의 **유일한 공개 Graphify 진입점**으로 복구한다. +2. assistant 통합은 upstream install 산출물(Claude/Codex/OpenCode)을 **1차 source of truth**로 사용한다. +3. `AGENTS.md`, `CLAUDE.md`, `.claude/settings.json`, `.codex/hooks.json`는 upstream 산출물과 **충돌 없이 merge/composition**한다. +4. repo-local guardrail은 유지한다. + - `raw/`는 human-owned source corpus + - `graphify-out/BUILD_INFO.json`은 trust signal + - full refresh는 staged corpus -> producer -> verify -> sync 순서를 강제 + - raw `graphify update .`는 full refresh 대체 경로가 아님 +5. `/graphify-manager`, `/graphify-full`를 제거하고, 문서/테스트/하네스를 `/graphify` 중심으로 재정렬한다. + +## 원래 Graphify와의 동일성 범위 + +이번 스펙의 목표는 **upstream Graphify와 public UX/mental model을 최대한 같게 만드는 것**이지, +이 저장소의 내부 운영 정책까지 byte-for-byte 동일하게 만드는 것은 아니다. + +### 같아지는 부분 + +1. 공개 진입점이 `/graphify` 하나로 복구된다. +2. assistant integration 기준선이 upstream install 산출물로 돌아간다. +3. 사용자는 repo-specific command를 먼저 배우지 않고, upstream Graphify 감각으로 진입할 수 있다. +4. 가능 범위에서 `query`, `path`, `explain` 계열 follow-up surface도 upstream command model 기준으로 검토한다. + +### 의도적으로 남기는 차이 + +1. full refresh source boundary는 `src/`, `tests/`, `raw/`로 제한한다. +2. `raw/`만 human-owned source corpus로 취급한다. +3. `graphify-out/BUILD_INFO.json`의 `mode`/`verified`를 공식 trust signal로 유지한다. +4. semantic full refresh는 staged `prepare -> producer -> verify -> sync`를 반드시 거친다. +5. raw `graphify update .`는 `code_update` 전용 bootstrap으로만 사용한다. + +즉 최종 결과는 **“겉으로는 원래 Graphify처럼 쓰이되, 안쪽에는 이 저장소의 검증/신뢰 모델이 남아 있는 상태”**다. + +## 비목표 (Non-Goals) + +이 스펙은 **다음을 포함하지 않는다**: + +- upstream Graphify 엔진 자체를 재구현하거나 포크하는 일 +- `graphifyy` 패키지나 upstream CLI를 repo-local bespoke implementation으로 치환하는 일 +- full refresh source corpus를 `src/`, `tests/`, `raw/` 밖으로 넓히는 일 +- `.agents/`, `scripts/`, `README*`, `AGENTS.md`, `CLAUDE.md`를 Graphify source input으로 승격하는 일 (단 `raw/design/specs/`는 이미 source corpus 일부) +- raw `graphify update .`를 semantic full refresh의 동등 경로로 인정하는 일 +- verify gate, auto-refresh, `BUILD_INFO.json` trust model을 제거하거나 약화하는 일 +- `/graphify` 외의 새 public Graphify entrypoint를 추가로 유지하는 일 +- unrelated Query-SID, 추천 로직, MLX 파이프라인 범위의 변경 + +## 현재 문제 (Why Change) + +현재 저장소는 Graphify를 완전히 없앤 상태가 아니라, **repo-local full-refresh orchestration 중심으로 재배치**한 상태다. + +### 현재 상태 + +| 항목 | 현재 | +|---|---| +| public entrypoint | `/graphify-manager`, `/graphify-full` | +| code-only refresh | `scripts/graphify_code_refresh.sh` -> `graphify update .` -> `mode=code_update` | +| full semantic refresh | staged corpus -> `scripts/graphify_full_refresh.py` -> `scripts/graphify_verify_full_refresh.py` -> `scripts/graphify_sync_staged.sh` | +| trust signal | `graphify-out/BUILD_INFO.json` | +| public docs | README / Copilot instructions / local adaptation이 `graphify-manager` 계열을 안내 | +| assistant integration baseline | upstream installer가 아니라 repo-local wrapper/문서 중심 | + +### 문제점 + +1. upstream Graphify의 기본 mental model인 **“assistant 안에서 `/graphify`로 폴더를 knowledge graph로 만든다”**가 public surface에서 사라졌다. +2. Claude/Codex/OpenCode install surface가 현재 설계의 baseline이 아니라, 나중에 참고하는 부가 정보로 밀려났다. +3. `AGENTS.md`, `CLAUDE.md`, `.claude/settings.json`, `.codex/hooks.json`는 이미 존재하지만, upstream integration과의 composition 규칙이 문서화되어 있지 않다. +4. 결과적으로 사용자는 **repo-specific command를 먼저 학습**해야 하고, upstream Graphify를 기대한 접근과 어긋난다. + +## Source of Truth 계층 + +이번 복구는 “upstream 우선 + repo-local 예외 최소화” 원칙을 따른다. + +| 관심사 | 1차 기준 | repo-local 제약 | +|---|---|---| +| public `/graphify` UX | upstream Graphify command model | skill wrapper는 thin composition만 수행 | +| assistant integration | `graphify claude install`, `graphify codex install`, `graphify opencode install` 산출물 | 기존 `AGENTS.md`, `CLAUDE.md`, hook 파일은 보존하며 merge | +| source corpus | upstream의 느슨한 any-folder model | 이 저장소에서는 `src/`, `tests/`, `raw/`만 curated full-refresh 대상 | +| docs/design semantic coverage | upstream general graph build | `raw/` source boundary + verify gate 필수 | +| graph freshness/trust | upstream refresh 결과 | `graphify-out/BUILD_INFO.json`의 `mode`/`verified`를 공식 trust signal로 사용 | + +## 공개 계약 (Public Contract) + +### 1. `/graphify`가 단일 public entrypoint다 + +- 구현 후 사용자가 Graphify 작업을 시작할 때 기본 진입점은 `/graphify` 하나다. +- `/graphify-manager`, `/graphify-full`는 migration 이후 public surface에서 제거한다. +- 문서, skill index, Copilot instructions, 테스트는 모두 이 계약을 기준으로 갱신한다. + +### 2. `/graphify`는 upstream mental model을 우선한다 + +`/graphify`는 최소한 아래 성격의 요청을 upstream Graphify 감각으로 수용해야 한다. + +1. 현재 그래프 생성/갱신 +2. 그래프 상태와 trust signal 확인 +3. 특정 refresh가 code update인지 full refresh인지 안내 +4. 가능하다면 `query`, `path`, `explain` 계열 follow-up surface도 `/graphify` 아래에서 설명/지원 + +단, slash 환경이나 repo-local 제약 때문에 1차 구현에서 보류되는 sub-surface가 있더라도: + +- legacy command로 조용히 우회하지 않는다. +- `/graphify`가 **지원/보류/예외 조건**을 명시적으로 설명해야 한다. + +### 3. code update와 full refresh의 경계는 유지한다 + +`/graphify`는 upstream UX를 제공하더라도, 내부 동작은 다음 구분을 유지해야 한다. + +#### code update + +- 경로: `scripts/graphify_code_refresh.sh` +- 핵심 명령: `uvx --from "graphifyy==0.4.23" graphify update .` +- 산출물: `graphify-out/graph.html`, `GRAPH_REPORT.md`, `graph.json`, `BUILD_INFO.json` +- 결과 의미: `BUILD_INFO.json.mode = "code_update"` + +#### full refresh + +- 경로: + 1. `bash scripts/graphify_prepare_corpus.sh` + 2. `uv run --with graphifyy==0.4.23 python scripts/graphify_full_refresh.py .graphify-work/corpus` + 3. `python3 scripts/graphify_verify_full_refresh.py .graphify-work/corpus/graphify-out` + 4. `bash scripts/graphify_sync_staged.sh` +- 결과 의미: + - staged verify가 통과해야 root sync 가능 + - root `graphify-out/BUILD_INFO.json`이 `mode=full_refresh`이고 `verified=true`일 때만 raw source corpus 반영 상태로 간주 + +### 4. `raw/` source boundary는 public contract에 포함된다 + +full refresh에서 사람 문맥 source corpus는 `raw/`가 유일하다. + +- semantic required: `raw/design/adr/**`, `raw/design/notes/**` +- semantic optional: `raw/design/specs/**` +- presence only: `raw/design/diagrams/**`, `raw/design/screenshots/**`, `raw/external/**` + +다음은 Graphify source input이 아니다. + +- `.agents/` +- `.agents/policies/` +- `scripts/` +- `README*` +- `AGENTS.md` +- `CLAUDE.md` + +### 5. raw `graphify update .`는 full refresh 대체 경로가 아니다 + +- `/graphify`가 upstream UX를 보여주더라도, semantic docs/design coverage가 필요한 상황에서는 staged full refresh로 분기해야 한다. +- `graphify update .`는 **code bootstrap refresh**로만 취급한다. +- public docs와 skill 설명은 이 차이를 분명히 드러내야 한다. + +## Assistant별 integration / composition 계약 + +### Claude + +- upstream의 `graphify claude install` 산출물을 baseline으로 분석한다. +- 하지만 이 저장소의 `.claude/settings.json`이 현재 보유한 active hook surface는 유지해야 한다. + - `bash scripts/hooks/graphify-pretool.sh` + - `bash scripts/hooks/graphify-auto-refresh.sh` +- `CLAUDE.md`는 얇은 upstream template로 교체하지 않고, repo-local schema 문서를 유지하면서 upstream directive를 흡수한다. + +### Codex + +- upstream의 `graphify codex install` 산출물을 baseline으로 분석한다. +- `.codex/hooks.json`의 현재 active behaviors는 유지해야 한다. + - `SessionStart` -> `scripts/hooks/session-start.sh` + - `Stop` -> `scripts/hooks/claude-stop-checks.sh` + - `PreToolUse` Graphify pretool + destructive-command / graphify-out / secret-file guard + - `PostToolUse` auto-refresh + git secret check +- Codex 쪽에서도 `/graphify`가 repo-local public surface로 노출되도록 wrapper skill과 문서가 정렬돼야 한다. + +### OpenCode + +- upstream의 `graphify opencode install` 산출물도 1차 기준으로 inventory한다. +- 저장소가 현재 OpenCode를 주 실행 환경으로 쓰지 않더라도, 최소한 다음은 문서화되어야 한다. + 1. upstream가 생성하는 integration 자산 종류 + 2. 이 저장소의 schema/hook와 충돌 시 merge/composition 원칙 + 3. `/graphify` public contract와의 정합성 + +### 공통 규칙 + +1. upstream installer가 생성하는 파일/문구/manifest는 **reference only가 아니라 source of truth**다. +2. repo-local 파일은 이를 흡수하는 composition layer이지, 별도 계약을 창조하는 레이어가 아니다. +3. upstream installer 산출물이 현재 저장소 파일과 충돌할 때는: + - 통째 overwrite 금지 + - preserved local guardrail 명시 + - merge 지점과 책임 경계 문서화 + +## 구현 방향 (Design Direction) + +### Step 0. 전용 branch/worktree 준비 + +- Graphify public surface 복구는 breaking change 성격이 있으므로 전용 branch/worktree에서 진행한다. +- spec/implementation/test/doc migration 모두 이 격리된 작업 단위 안에서 수행한다. + +### Step 1. upstream install 자산 inventory + +반드시 먼저 정리할 것: + +1. `graphify claude install`이 생성/수정하는 자산 +2. `graphify codex install`이 생성/수정하는 자산 +3. `graphify opencode install`이 생성/수정하는 자산 +4. 각 assistant별로 이 저장소의 현재 파일과 충돌하는 지점 +5. 그대로 유지 가능한 부분 / merge 필요한 부분 / 1차 보류 부분 + +### Step 2. thin `/graphify` composition layer 추가 + +- `.agents/skills/graphify/SKILL.md`를 추가한다. +- 필요 시 `agents/openai.yaml`을 둔다. +- 이 wrapper는 repo-local bespoke workflow를 설명하는 문서가 아니라, + **upstream Graphify contract를 이 저장소 제약 안에 매핑하는 얇은 composition layer**여야 한다. + +### Step 3. legacy skill 역할 흡수 + +기존 `graphify-manager` / `graphify-full`가 설명하던 staged producer -> verify -> sync는 +`/graphify` contract 안의 explicit full-refresh branch로 흡수한다. + +- full refresh는 사라지지 않는다. +- public entrypoint만 `/graphify`로 통합된다. +- implementation 중간 단계에서 temporary alias를 둘 수는 있지만, 최종 상태에서 public docs는 `/graphify`만 안내한다. + +### Step 4. 문서/지침/테스트 migration + +최소한 아래 surface는 `/graphify` 기준으로 다시 써야 한다. + +- `README.md` +- `README.ko.md` +- `.github/copilot-instructions.md` +- `.agents/policies/local-adaptation.md` +- `AGENTS.md` +- `CLAUDE.md` +- `tests/test_graphify_harness.py` + +## 완료 조건 (Acceptance Criteria) + +1. 저장소에 `/graphify` repo-local skill이 존재한다. +2. `/graphify`가 단일 public Graphify entrypoint로 문서화된다. +3. assistant integration 기준이 upstream installer 산출물이라는 점이 구현/문서/테스트에서 드러난다. +4. `.claude/settings.json`과 `.codex/hooks.json`의 현재 guardrail/auto-refresh/session-start/stop 동작이 유지된다. +5. `raw/` source boundary, staged full refresh, verify gate, `BUILD_INFO.json` trust signal이 그대로 유지된다. +6. `graphify update .`는 여전히 `code_update` 전용으로만 취급된다. +7. `/graphify-manager`, `/graphify-full`는 최종 public surface에서 제거된다. +8. README / Copilot instructions / local adaptation / AGENTS / CLAUDE / tests가 모두 같은 계약을 설명한다. + +## 검증 (Validation) + +구현 전후 기본 게이트: + +```bash +uv sync --all-groups +uv run pytest +uv run ruff check . +uv run mypy src +uv run sid-reco doctor +``` + +추가로 확인할 것: + +1. `tests/test_graphify_harness.py`가 `/graphify` 존재와 legacy surface 제거를 검증하도록 갱신되었는가 +2. `README.md`, `.github/copilot-instructions.md`, `.agents/policies/local-adaptation.md`가 동일한 public contract를 설명하는가 +3. full refresh 경로가 여전히 `prepare -> producer -> verify -> sync` 순서를 강제하는가 + +## 주요 리스크 (Risks) + +1. upstream installer 산출물 버전 차이로 generated manifest/hook 형태가 달라질 수 있다. +2. upstream의 느슨한 “any folder” UX와 이 저장소의 curated corpus/verify gate 사이에는 구조적 긴장이 있다. +3. `AGENTS.md`/`CLAUDE.md`를 얇은 upstream template로 덮으면 현재 저장소의 richer schema가 사라질 수 있다. +4. `/graphify-manager`, `/graphify-full` 제거는 문서와 테스트에서 광범위한 drift를 유발할 수 있다. + +## 구현 시작 전 확인 + +이 스펙이 승인되면 다음 순서로 진행한다. + +1. 전용 branch/worktree 생성 +2. upstream Claude/Codex/OpenCode install 자산 inventory +3. `/graphify` thin composition layer 설계 +4. legacy skill migration +5. 문서/테스트/하네스 정렬 From 1de480a24aff9acab0594af770713ba85deb1575 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 23 Apr 2026 16:10:09 +0900 Subject: [PATCH 5/5] chore(graphify): refresh graph after spec migration to raw/design/specs/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit raw/design/specs/ski-011-upstream-graphify-entrypoint.md가 추가되면서 raw/ source corpus에 변경 발생 → auto-refresh가 code refresh를 트리거. 새 spec이 knowledge graph의 일부로 포함됨. Co-Authored-By: Claude Opus 4.7 (1M context) --- graphify-out/BUILD_INFO.json | 2 +- graphify-out/GRAPH_REPORT.md | 159 +- graphify-out/graph.html | 8 +- graphify-out/graph.json | 4533 +++++++++++++++++++++------------- 4 files changed, 2852 insertions(+), 1850 deletions(-) diff --git a/graphify-out/BUILD_INFO.json b/graphify-out/BUILD_INFO.json index 5b158bb..43f35ec 100644 --- a/graphify-out/BUILD_INFO.json +++ b/graphify-out/BUILD_INFO.json @@ -2,5 +2,5 @@ "graphify_version": "0.4.23", "mode": "code_update", "command": "uvx --from graphifyy==0.4.23 graphify update .", - "generated_at": "2026-04-23T04:13:37.078532+00:00" + "generated_at": "2026-04-23T07:08:31.613879+00:00" } diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index 061eb14..5815e96 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,12 +1,12 @@ # Graph Report - /Users/skiiwoo/PERSONAL/Training-Free-SID-Reco (2026-04-23) ## Corpus Check -- 64 files · ~195,008 words +- 64 files · ~196,067 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 1010 nodes · 4237 edges · 27 communities detected -- Extraction: 30% EXTRACTED · 70% INFERRED · 0% AMBIGUOUS · INFERRED: 2960 edges (avg confidence: 0.81) +- 1023 nodes · 4310 edges · 24 communities detected +- Extraction: 30% EXTRACTED · 70% INFERRED · 0% AMBIGUOUS · INFERRED: 2998 edges (avg confidence: 0.82) - Token cost: 0 input · 0 output ## Community Hubs (Navigation) @@ -34,16 +34,13 @@ - [[_COMMUNITY_Community 21|Community 21]] - [[_COMMUNITY_Community 22|Community 22]] - [[_COMMUNITY_Community 23|Community 23]] -- [[_COMMUNITY_Community 24|Community 24]] -- [[_COMMUNITY_Community 25|Community 25]] -- [[_COMMUNITY_Community 26|Community 26]] ## God Nodes (most connected - your core abstractions) -1. `MLXTextGenerator` - 103 edges +1. `MLXTextGenerator` - 100 edges 2. `Context` - 93 edges -3. `Settings` - 66 edges -4. `MLXEmbeddingEncoder` - 64 edges -5. `InterestSketch` - 50 edges +3. `Settings` - 63 edges +4. `MLXEmbeddingEncoder` - 61 edges +5. `InterestSketch` - 45 edges 6. `Context` - 44 edges 7. `SID recommender package.` - 40 edges 8. `후속 변경` - 37 edges @@ -55,159 +52,135 @@ /Users/skiiwoo/PERSONAL/Training-Free-SID-Reco/tests/test_foodcom_dataset.py → raw/design/adr/adr-003-neighbor-context-retrieval.md - `MLXTextGenerator` --rationale_for--> `Context` [INFERRED] /Users/skiiwoo/PERSONAL/Training-Free-SID-Reco/src/sid_reco/llm.py → raw/design/adr/adr-002-foodcom-preprocessing-policy.md -- `MLXTextGenerator` --rationale_for--> `부정적/제약` [INFERRED] - /Users/skiiwoo/PERSONAL/Training-Free-SID-Reco/src/sid_reco/llm.py → raw/design/adr/adr-004-taxonomy-dictionary-generation.md -- `main()` --rationale_for--> `Context` [INFERRED] - /Users/skiiwoo/PERSONAL/Training-Free-SID-Reco/src/sid_reco/cli.py → raw/design/adr/adr-005-taxonomy-dictionary-hardening.md -- `doctor()` --rationale_for--> `Context` [INFERRED] - /Users/skiiwoo/PERSONAL/Training-Free-SID-Reco/src/sid_reco/cli.py → raw/design/adr/adr-005-taxonomy-dictionary-hardening.md +- `from_settings()` --rationale_for--> `Context` [INFERRED] + /Users/skiiwoo/PERSONAL/Training-Free-SID-Reco/src/sid_reco/llm.py → raw/design/adr/adr-002-foodcom-preprocessing-policy.md +- `_format_chat_prompt()` --rationale_for--> `Context` [INFERRED] + /Users/skiiwoo/PERSONAL/Training-Free-SID-Reco/src/sid_reco/llm.py → raw/design/adr/adr-002-foodcom-preprocessing-policy.md +- `Local MLX LLM utilities.` --rationale_for--> `Context` [INFERRED] + src/sid_reco/llm.py → raw/design/adr/adr-002-foodcom-preprocessing-policy.md ## Communities ### Community 0 - "Community 0" -Cohesion: 0.03 -Nodes (148): Run the full training-free recommendation pipeline., Run the full training-free recommendation pipeline., _assign_to_centroids(), build_item_sids(), build_query_sid(), _canonicalize_clusters(), _centroids_close(), _fit_deterministic_kmeans() (+140 more) +Cohesion: 0.06 +Nodes (167): build_neighbor_context_command(), build_taxonomy_dictionary_command(), doctor(), main(), _parse_hard_filters(), prepare_foodcom(), CLI entry points for local development., Run a single prompt against the configured local MLX LLM. (+159 more) ### Community 1 - "Community 1" -Cohesion: 0.03 -Nodes (132): QuerySID, Hierarchical SID assignment for one runtime query vector., FewShotExample, load_fewshot_examples(), _normalize_matrix(), Dynamic few-shot example retrieval for Module 2.3., Small protocol for few-shot example encoding., One successful recommendation example used for dynamic prompting. (+124 more) +Cohesion: 0.04 +Nodes (135): QuerySID, Hierarchical SID assignment for one runtime query vector., compute_bootstrap_confidence(), _confidence_band(), ConfidenceCandidate, _MutableConfidenceAggregate, Module 2.4 CPU confidence aggregation for bootstrap rerank outputs., Create a compact confidence summary for final delivery. (+127 more) ### Community 2 - "Community 2" -Cohesion: 0.08 -Nodes (117): Run the full training-free recommendation pipeline., Diagnose whether the current environment can initialize MLX safely., smoke_mlx(), build_bounded_taxonomy_payload(), build_taxonomy_dictionary(), build_taxonomy_dictionary_prompt(), _evenly_spaced_indices(), generate_taxonomy_dictionary() (+109 more) +Cohesion: 0.04 +Nodes (136): compile_sid_index_command(), Compile structured taxonomy items into hierarchical SIDs and a FAISS index., _assign_to_centroids(), build_item_sids(), build_query_sid(), _canonicalize_clusters(), _centroids_close(), _fit_deterministic_kmeans() (+128 more) ### Community 3 - "Community 3" Cohesion: 0.04 -Nodes (97): from_settings(), MLXEmbeddingEncoder, Local MLX embedding utilities., Lazy wrapper around an MLX embedding model., Build an encoder from application settings., Encode a batch of texts into normalized embedding vectors., Encode a single text and return one embedding vector., Load the embedding model only once. (+89 more) +Nodes (94): from_settings(), MLXEmbeddingEncoder, Local MLX embedding utilities., Lazy wrapper around an MLX embedding model., Build an encoder from application settings., Encode a batch of texts into normalized embedding vectors., Encode a single text and return one embedding vector., Load the embedding model only once. (+86 more) ### Community 4 - "Community 4" -Cohesion: 0.07 -Nodes (99): apply_k_core_filter(), build_manifest(), build_recipe_stats(), build_temporal_splits(), DatasetSummary, _ensure_columns(), filter_positive_interactions(), load_raw_interactions() (+91 more) +Cohesion: 0.09 +Nodes (92): apply_k_core_filter(), build_manifest(), build_recipe_stats(), build_temporal_splits(), DatasetSummary, _ensure_columns(), filter_positive_interactions(), load_raw_interactions() (+84 more) ### Community 5 - "Community 5" Cohesion: 0.06 -Nodes (96): Related, Taxonomy Item Structuring, 개요, 동작 규칙, 사용법/설정, 실행 명령, 현재 구현과 GRLM 레퍼런스의 대응, 현재 상태 (+88 more) +Nodes (72): build_item_projection_context(), build_item_projection_evidence(), build_item_projection_prompt(), build_retry_prompt(), build_self_refine_prompt(), _canonicalize_feature_value(), consolidate_item_taxonomy(), _context_ingredient_tokens() (+64 more) ### Community 6 - "Community 6" -Cohesion: 0.05 -Nodes (83): build_neighbor_context_command(), build_taxonomy_dictionary_command(), compile_sid_index_command(), doctor(), main(), _parse_hard_filters(), prepare_foodcom(), CLI entry points for local development. (+75 more) +Cohesion: 0.04 +Nodes (61): 1. `/graphify`가 단일 public entrypoint다, 2. `/graphify`는 upstream mental model을 우선한다, 3. code update와 full refresh의 경계는 유지한다, 4. `raw/` source boundary는 public contract에 포함된다, 5. raw `graphify update .`는 full refresh 대체 경로가 아니다, Assistant별 integration / composition 계약, Claude, code update (+53 more) ### Community 7 - "Community 7" -Cohesion: 0.09 -Nodes (0): +Cohesion: 0.07 +Nodes (31): Project-level configuration helpers., Runtime settings resolved from the environment., Create default directories used by the local workflow., Resolve relative paths against the project root., _resolve_project_path(), CLI 명령, Codex 명령, Related (+23 more) ### Community 8 - "Community 8" Cohesion: 0.12 Nodes (7): App(), avgMscp(), buildLangHref(), escapeHtml(), JsonView(), MetricsStrip(), OverviewGrid() ### Community 9 - "Community 9" +Cohesion: 0.21 +Nodes (12): _FakeEncoder, _FakeGenerator, _make_candidate(), _make_sketch(), test_parse_rerank_response_rejects_long_reasoning(), test_parse_rerank_response_rejects_wrong_selection_size(), test_run_bootstrap_rerank_injects_one_dynamic_example_and_runs_multiple_passes(), test_run_bootstrap_rerank_limits_structured_output_to_selection_size() (+4 more) + +### Community 10 - "Community 10" Cohesion: 0.39 Nodes (11): _clean_env(), _init_repo(), _seed_raw_corpus(), test_graphify_ci_candidate_is_candidate_only_even_when_staged_output_exists(), test_graphify_ci_candidate_writes_manual_note_when_no_staged_output(), test_graphify_prepare_corpus_script_copies_only_curated_inputs(), test_graphify_sync_staged_copies_verified_outputs(), test_graphify_sync_staged_requires_verify_marker() (+3 more) -### Community 10 - "Community 10" +### Community 11 - "Community 11" Cohesion: 0.69 Nodes (10): _clean_env(), _commit_all(), _copy_graphify_runtime(), _init_repo(), _seed_repo(), test_graphify_auto_refresh_bootstrap_does_not_skip_first_doc_change(), test_graphify_auto_refresh_bootstrap_runs_code_refresh_for_first_code_change(), test_graphify_auto_refresh_runs_code_refresh_after_code_only_change() (+2 more) -### Community 11 - "Community 11" +### Community 12 - "Community 12" Cohesion: 0.4 Nodes (8): _load_execute_module(), test_build_preamble_keeps_git_ownership_in_executor(), test_check_blockers_exits_for_blocked_steps(), test_ensure_clean_worktree_exits_when_repo_is_dirty(), test_ensure_created_at_records_task_timestamp(), test_invoke_claude_writes_output_and_uses_expected_command(), test_load_guardrails_uses_repo_specific_documents(), _write_phase_index() -### Community 12 - "Community 12" +### Community 13 - "Community 13" Cohesion: 0.2 Nodes (2): _EmptyTaxonomyGenerator, _FakeGenerator -### Community 13 - "Community 13" -Cohesion: 0.33 -Nodes (6): _ProjectionGenerator, test_structure_taxonomy_batch_cli_can_include_evidence(), test_structure_taxonomy_batch_cli_writes_jsonl(), test_structure_taxonomy_item_cli_can_include_evidence(), test_structure_taxonomy_item_cli_prints_json(), _write_projection_inputs() - ### Community 14 - "Community 14" -Cohesion: 0.71 -Nodes (6): _clean_env(), _copy_script(), _init_repo(), test_graphify_full_refresh_produces_staged_outputs_with_doc_context(), test_graphify_full_refresh_reports_partial_state_on_semantic_failure(), _write_file() +Cohesion: 0.29 +Nodes (7): load_recommendation_stats_store(), _parse_double_nested_int_mapping(), _parse_nested_int_mapping(), Load and query offline recommendation statistics., Lookup-friendly popularity and co-occurrence statistics., Load recommendation statistics persisted by compile-sid-index., RecommendationStatsStore ### Community 15 - "Community 15" -Cohesion: 0.4 -Nodes (5): GroundingDecision, Module 2.4 SID-aware fallback mapping helpers., Resolved canonical identity for a recommendation candidate., Resolve a candidate through direct id_map lookup, then SID fallback., resolve_grounding() +Cohesion: 0.33 +Nodes (6): _ProjectionGenerator, test_structure_taxonomy_batch_cli_can_include_evidence(), test_structure_taxonomy_batch_cli_writes_jsonl(), test_structure_taxonomy_item_cli_can_include_evidence(), test_structure_taxonomy_item_cli_prints_json(), _write_projection_inputs() ### Community 16 - "Community 16" -Cohesion: 0.4 -Nodes (1): _FakeEncoder +Cohesion: 0.43 +Nodes (4): _FakeEncoder, test_compile_sid_index_cli_reports_missing_taxonomy_dictionary(), test_compile_sid_index_cli_writes_all_outputs(), _write_sid_inputs() ### Community 17 - "Community 17" -Cohesion: 1.0 -Nodes (2): _recipe_row(), test_prepare_foodcom_cli_writes_processed_outputs() +Cohesion: 0.71 +Nodes (6): _clean_env(), _copy_script(), _init_repo(), test_graphify_full_refresh_produces_staged_outputs_with_doc_context(), test_graphify_full_refresh_reports_partial_state_on_semantic_failure(), _write_file() ### Community 18 - "Community 18" -Cohesion: 1.0 -Nodes (0): +Cohesion: 0.4 +Nodes (5): GroundingDecision, Module 2.4 SID-aware fallback mapping helpers., Resolved canonical identity for a recommendation candidate., Resolve a candidate through direct id_map lookup, then SID fallback., resolve_grounding() ### Community 19 - "Community 19" -Cohesion: 1.0 -Nodes (0): +Cohesion: 0.4 +Nodes (1): _FakeEncoder ### Community 20 - "Community 20" Cohesion: 1.0 -Nodes (0): +Nodes (2): _recipe_row(), test_prepare_foodcom_cli_writes_processed_outputs() ### Community 21 - "Community 21" Cohesion: 1.0 -Nodes (1): Normalized request contract for recommendation entrypoints. +Nodes (0): ### Community 22 - "Community 22" Cohesion: 1.0 -Nodes (1): Taxonomy-constrained representation of user intent. +Nodes (0): ### Community 23 - "Community 23" Cohesion: 1.0 -Nodes (1): Final recommendation payload for one catalog item. - -### Community 24 - "Community 24" -Cohesion: 1.0 -Nodes (1): Public response contract for recommendation entrypoints. - -### Community 25 - "Community 25" -Cohesion: 1.0 -Nodes (1): Normalize runtime request fields into a stable typed contract. - -### Community 26 - "Community 26" -Cohesion: 1.0 -Nodes (1): Load residual codebooks from NPZ and validate against the sibling manifest. +Nodes (0): ## Knowledge Gaps -- **204 isolated node(s):** `Load and query offline recommendation statistics.`, `Lookup-friendly popularity and co-occurrence statistics.`, `Load recommendation statistics persisted by compile-sid-index.`, `Module 2.4 SID-aware fallback mapping helpers.`, `Resolved canonical identity for a recommendation candidate.` (+199 more) +- **223 isolated node(s):** `Load and query offline recommendation statistics.`, `Lookup-friendly popularity and co-occurrence statistics.`, `Load recommendation statistics persisted by compile-sid-index.`, `Module 2.4 SID-aware fallback mapping helpers.`, `Resolved canonical identity for a recommendation candidate.` (+218 more) These have ≤1 connection - possible missing edges or undocumented components. -- **Thin community `Community 18`** (2 nodes): `test_git_hooks_delegate_to_shared_scripts_with_repo_root_fallback()`, `test_git_hook_scripts.py` - Too small to be a meaningful cluster - may be noise or needs more connections extracted. -- **Thin community `Community 19`** (1 nodes): `app.jsx` - Too small to be a meaningful cluster - may be noise or needs more connections extracted. -- **Thin community `Community 20`** (1 nodes): `i18n.js` - Too small to be a meaningful cluster - may be noise or needs more connections extracted. -- **Thin community `Community 21`** (1 nodes): `Normalized request contract for recommendation entrypoints.` - Too small to be a meaningful cluster - may be noise or needs more connections extracted. -- **Thin community `Community 22`** (1 nodes): `Taxonomy-constrained representation of user intent.` - Too small to be a meaningful cluster - may be noise or needs more connections extracted. -- **Thin community `Community 23`** (1 nodes): `Final recommendation payload for one catalog item.` - Too small to be a meaningful cluster - may be noise or needs more connections extracted. -- **Thin community `Community 24`** (1 nodes): `Public response contract for recommendation entrypoints.` +- **Thin community `Community 21`** (2 nodes): `test_git_hooks_delegate_to_shared_scripts_with_repo_root_fallback()`, `test_git_hook_scripts.py` Too small to be a meaningful cluster - may be noise or needs more connections extracted. -- **Thin community `Community 25`** (1 nodes): `Normalize runtime request fields into a stable typed contract.` +- **Thin community `Community 22`** (1 nodes): `app.jsx` Too small to be a meaningful cluster - may be noise or needs more connections extracted. -- **Thin community `Community 26`** (1 nodes): `Load residual codebooks from NPZ and validate against the sibling manifest.` +- **Thin community `Community 23`** (1 nodes): `i18n.js` Too small to be a meaningful cluster - may be noise or needs more connections extracted. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `SID recommender package.` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 5`, `Community 6`, `Community 15`?** - _High betweenness centrality (0.059) - this node is a cross-community bridge._ -- **Why does `Settings` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 6`?** - _High betweenness centrality (0.051) - this node is a cross-community bridge._ -- **Why does `MLXTextGenerator` connect `Community 5` to `Community 0`, `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 6`?** - _High betweenness centrality (0.036) - this node is a cross-community bridge._ -- **Are the 99 inferred relationships involving `MLXTextGenerator` (e.g. with `_FakeTokenizer` and `_FakeTokenListTokenizer`) actually correct?** - _`MLXTextGenerator` has 99 INFERRED edges - model-reasoned connections that need verification._ +- **Why does `SID recommender package.` connect `Community 1` to `Community 0`, `Community 2`, `Community 3`, `Community 5`, `Community 14`, `Community 18`?** + _High betweenness centrality (0.045) - this node is a cross-community bridge._ +- **Why does `MLXTextGenerator` connect `Community 0` to `Community 1`, `Community 2`, `Community 3`, `Community 4`, `Community 5`, `Community 7`?** + _High betweenness centrality (0.039) - this node is a cross-community bridge._ +- **Why does `Settings` connect `Community 2` to `Community 0`, `Community 1`, `Community 3`, `Community 7`, `Community 16`?** + _High betweenness centrality (0.030) - this node is a cross-community bridge._ +- **Are the 96 inferred relationships involving `MLXTextGenerator` (e.g. with `_FakeTokenizer` and `_FakeTokenListTokenizer`) actually correct?** + _`MLXTextGenerator` has 96 INFERRED edges - model-reasoned connections that need verification._ - **Are the 92 inferred relationships involving `Context` (e.g. with `main()` and `doctor()`) actually correct?** _`Context` has 92 INFERRED edges - model-reasoned connections that need verification._ -- **Are the 64 inferred relationships involving `Settings` (e.g. with `_FakeEncoder` and `_FakeEncoder`) actually correct?** - _`Settings` has 64 INFERRED edges - model-reasoned connections that need verification._ -- **Are the 59 inferred relationships involving `MLXEmbeddingEncoder` (e.g. with `_FakeArray` and `Settings`) actually correct?** - _`MLXEmbeddingEncoder` has 59 INFERRED edges - model-reasoned connections that need verification._ \ No newline at end of file +- **Are the 61 inferred relationships involving `Settings` (e.g. with `_FakeEncoder` and `_FakeEncoder`) actually correct?** + _`Settings` has 61 INFERRED edges - model-reasoned connections that need verification._ +- **Are the 56 inferred relationships involving `MLXEmbeddingEncoder` (e.g. with `_FakeArray` and `Settings`) actually correct?** + _`MLXEmbeddingEncoder` has 56 INFERRED edges - model-reasoned connections that need verification._ \ No newline at end of file diff --git a/graphify-out/graph.html b/graphify-out/graph.html index 8cf7ef6..97286ba 100644 --- a/graphify-out/graph.html +++ b/graphify-out/graph.html @@ -50,12 +50,12 @@

Node Info

Communities

-
1010 nodes · 4237 edges · 27 communities
+
1023 nodes · 4310 edges · 24 communities