diff --git a/AGENTS.md b/AGENTS.md index c2886a9..921102a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,12 +2,147 @@ Rust-based digital asset management system with video analysis and RAG capabilities. +--- + +## ⚠️ CRITICAL: 開發隔離原則 + +### 絕對禁止事項 +- **絕對不可修改 `/Users/accusys/wordpress/` 目錄下的任何檔案** +- **絕對不可修改 n8n 工作流或設定** +- **絕對不可修改 WordPress 或 n8n 的資料庫 table** +- **除非是 release 作業,絕對不可動 port 3002 (production)** + +### 開發範圍界定 +| 範圍 | 狀態 | 說明 | +|------|------|------| +| `momentry_core_0.1/` | ✅ **可開發** | Momentry Core 主要開發目錄 | +| `momentry_core_0.1/portal/` | ✅ **可開發** | Tauri Portal 前端 | +| `momentry_core_0.1/src/` | ✅ **可開發** | Rust 後端程式碼 | +| `/Users/accusys/wordpress/` | ❌ **禁止修改** | WordPress/Marcom 團隊負責 | +| n8n 工作流 | ❌ **禁止修改** | 自動化流程,與 dev 無關 | +| WordPress/n8n 資料庫 table | ❌ **禁止修改** | Marcom 團隊管理,與 dev 無關 | + +### 開發環境 +| 服務 | Port | 用途 | 命令 | +|------|------|------|------| +| Playground | 3003 | **唯一開發環境** | `cargo run --bin momentry_playground -- server` | +| Production | 3002 | ❌ 禁止修改 | `cargo run -- server` (僅 release 時) | +| Portal (Tauri) | 1420 | 前端開發 | `npm run tauri dev` | + +### 違反後果 +- 修改 WordPress/n8n 可能影響 marcom 團隊工作與生產環境 +- 修改 WordPress/n8n 資料庫 table 可能破壞自動化流程與資料完整性 +- 修改 port 3002 可能中斷正在使用的服務 +- 所有 dev 測試必須在 playground (3003) 進行 + +--- + +## AI Coding Principles (Karpathy-Inspired) + +Behavioral guidelines to reduce common LLM coding mistakes. +Source: [andrej-karpathy-skills](https://github.com/forrestchang/andrej-karpathy-skills) (94K stars) + +**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment. + +### 1. Think Before Coding + +**Don't assume. Don't hide confusion. Surface tradeoffs.** + +- State your assumptions explicitly. If uncertain, ask. +- If multiple interpretations exist, present them - don't pick silently. +- If a simpler approach exists, say so. Push back when warranted. +- If something is unclear, stop. Name what's confusing. Ask. + +### 2. Simplicity First + +**Minimum code that solves the problem. Nothing speculative.** + +- No features beyond what was asked. +- No abstractions for single-use code. +- No "flexibility" or "configurability" that wasn't requested. +- No error handling for impossible scenarios. +- If you write 200 lines and it could be 50, rewrite it. + +Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify. + +### 3. Surgical Changes + +**Touch only what you must. Clean up only your own mess.** + +When editing existing code: +- Don't "improve" adjacent code, comments, or formatting. +- Don't refactor things that aren't broken. +- Match existing style, even if you'd do it differently. +- If you notice unrelated dead code, mention it - don't delete it. + +When your changes create orphans: +- Remove imports/variables/functions that YOUR changes made unused. +- Don't remove pre-existing dead code unless asked. + +The test: Every changed line should trace directly to the user's request. + +### 4. Goal-Driven Execution + +**Define success criteria. Loop until verified.** + +Transform tasks into verifiable goals: +- "Add validation" -> "Write tests for invalid inputs, then make them pass" +- "Fix the bug" -> "Write a test that reproduces it, then make it pass" +- "Refactor X" -> "Ensure tests pass before and after" + +For multi-step tasks, state a brief plan: +``` +1. [Step] -> verify: [check] +2. [Step] -> verify: [check] +3. [Step] -> verify: [check] +``` + +Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification. + +--- + +These guidelines are working if: fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes. + +--- + +## Terminology (V4.0) + +| Term | Scope | Description | Example | +|------|-------|-------------|---------| +| **file_uuid** | Video file | Video file identifier (renamed from `video_uuid`) | `384b0ff44aaaa1f1` | +| **identity_uuid** | Global identity | Global person identity (cross-file) | `a9a90105-6d6b-46ff-92da-0c3c1a57dff4` | +| **face_id** | Single detection | Single face detection (frame-level) | `face_100` | +| **trace_id** | Face tracking | Face tracking ID (Face Tracker output) | `2` | +| **chunk_id** | Sentence chunk | Sentence chunk (from pre_chunks via rules) | `chunk_1` | +| **speaker_id** | Speaker segment | Speaker ID (from ASRX) | `SPEAKER_0` | +| **person_id** | ❌ **Deprecated** | Video-local person ID (removed in V4.0) | - | + +### Architecture (V4.0) + +``` +Face → Identity (Two-layer, direct binding) + ↓ + person_identities table: REMOVED + file_identities table: ADDED (N:N relationship) +``` + +### Key Changes (V3.x → V4.0) + +| Change | V3.x | V4.0 | +|--------|------|------| +| **video_uuid** | Used everywhere | **file_uuid** | +| **person_identities** | Required (303 records) | **Removed** | +| **person_id APIs** | 28 endpoints | **Removed** (except register/bind) | +| **Face binding** | Person → Identity | **Face → Identity** (direct) | +| **Chunk binding** | Manual | **Auto** (time alignment) | + +--- + ## Build & Run Commands ```bash -# Build project +# Build project (use debug builds for development/testing) cargo build -cargo build --release cargo build --bin momentry cargo build --bin momentry_playground @@ -24,6 +159,12 @@ cargo run --bin momentry_playground -- server cargo run --bin momentry_playground -- --help ``` +### ⚠️ CRITICAL: `cargo build --release` PROHIBITION +- **NEVER run `cargo build --release` unless the user explicitly says "release the binary" or "正式 release"** +- `cargo build --release` is SLOW and only needed when producing a production binary for deployment +- For all development, testing, debugging, and linting: use `cargo build` or `cargo check` +- If uncertain, ALWAYS ask the user first + ## Binaries | Binary | Purpose | Port | Redis Prefix | Environment | @@ -343,6 +484,51 @@ shellcheck scripts/*.sh monitor/**/*.sh **注意**: Hook 只檢查 error 等級的 shellcheck 問題,style 警告會顯示但不阻擋提交。 +## Release Workflow + +### Release 前準備 +每次 release production binary 前,必須: + +1. **建立 Release Tag** + ```bash + git tag -a v0.X.X -m "Release vX.X.X - YYYY-MM-DD" + git push origin v0.X.X + ``` + +2. **備份獨立 Source Code** + ```bash + # 建立 release 獨立目錄 + RELEASE_DIR="/Users/accusys/momentry_core_releases/v0.X.X" + mkdir -p "$RELEASE_DIR" + + # 複製完整原始碼(排除不必要的檔案) + rsync -av --exclude='.git' --exclude='target' --exclude='node_modules' \ + /Users/accusys/momentry_core_0.1/ "$RELEASE_DIR/" + + # 記錄 release 資訊 + echo "Release: v0.X.X" > "$RELEASE_DIR/RELEASE_INFO.txt" + echo "Date: $(date)" >> "$RELEASE_DIR/RELEASE_INFO.txt" + echo "Git Commit: $(git rev-parse HEAD)" >> "$RELEASE_DIR/RELEASE_INFO.txt" + echo "Binary: $(ls -la target/release/momentry)" >> "$RELEASE_DIR/RELEASE_INFO.txt" + ``` + +3. **備份 Binary** + ```bash + cp target/release/momentry "$RELEASE_DIR/momentry_v0.X.X" + cp target/release/momentry_playground "$RELEASE_DIR/momentry_playground_v0.X.X" 2>/dev/null + ``` + +4. **記錄資料庫 Schema** + ```bash + pg_dump -U accusys -d momentry --schema-only > "$RELEASE_DIR/schema_v0.X.X.sql" + ``` + +### 重要性 +- 避免 release binary 與 current source code 不一致 +- 方便追蹤特定 release 的程式碼狀態 +- 必要時可快速復原或比對差異 +- 確保資料庫 schema 與程式碼版本對應 + ## Reference Documents | 文件 | 用途 | diff --git a/Cargo.lock b/Cargo.lock index 5ffa288..b205f01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2209,6 +2209,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "mac_address" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0aeb26bf5e836cc1c341c8106051b573f1766dfa05aa87f0b98be5e51b02303" +dependencies = [ + "nix", + "winapi", +] + [[package]] name = "matches" version = "0.1.10" @@ -2243,6 +2253,15 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -2340,6 +2359,7 @@ dependencies = [ "hex", "jieba-rs", "libc", + "mac_address", "md5", "moka", "mongodb", @@ -2356,6 +2376,7 @@ dependencies = [ "sha2", "sqlx 0.8.6", "subtle", + "tempfile", "thiserror 1.0.69", "tokio", "tower 0.4.13", @@ -2448,6 +2469,19 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.11.1", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + [[package]] name = "no_std_io2" version = "0.9.3" diff --git a/Cargo.toml b/Cargo.toml index 21c4b56..4cead5e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ chrono = { version = "0.4", features = ["serde"] } sha2 = "0.10" hex = "0.4" uuid = { version = "1.0", features = ["v4"] } +mac_address = "1.1" # Security subtle = "2.5" @@ -123,3 +124,6 @@ path = "src/bin/integrated_player.rs" [build-dependencies] chrono = "0.4" + +[dev-dependencies] +tempfile = "3"