Lessons: Scout Before Suggest (in homelab/infra repos)¶
Meta-lesson về workflow. Cross-cutting — áp dụng cho mọi task "thêm/scaffold/create/replace" trong repo có cấu trúc
stacks/,services/, hoặc tương tự.
Related docs:
- ../../.claude/rules/review-audit-self-decision.md §4 "Scout-First, Ask-Second" — rule gốc nhưng bị vi phạm
- ../../docs/deploy-checklist.md §3 — checklist pre-replacement (đã có sẵn, nhưng rule này rộng hơn: áp dụng cả khi chưa định replace)
- replacing-stacks.md — case study MeTube vs Cobalt, hậu quả của skip checklist
Nguyên tắc¶
Trước khi đề xuất "thêm mới" một service/stack/tool trong repo có khả năng đã có sẵn, bắt buộc scout (grep/glob) trước. Confidence < 85% về trạng thái hiện tại → scout, không đề xuất.
Homelab/infra repo đặc biệt rủi ro vì:
- Service đã tồn tại ở dạng container khác tên (vd:
aria2sống tronggluetunstack, không phảiaria2stack). - Service đã được migrate giữa stack (vd:
aria2từng ởopenlist, giờ ởgluetunđể route VPN). - README/docs đôi khi落后 thực tế — không tin README, tin compose files.
Anti-pattern¶
Đề xuất scaffold tool X rồi mới verify khi user nhắc. Vi phạm
Scout-First, Ask-Second rule và gây 2 hậu quả:
- Wasted turn: user phải correct lại thay vì việc tự scout mất 5s.
- Erosion of trust: user sẽ nghi ngờ các đề xuất tiếp theo — đã thật sự check chưa?
Rule cụ thể¶
Trigger pattern: task nói "thêm/scaffold/create/replace X" trong repo có
stacks/ hoặc services/
Flow:
1. grep -i "<name>" stacks/ services/ compose files (5s)
2. Nếu match → verify, không đề xuất mới
3. Nếu không match → đề xuất mới (confidence ≥ 85%)
4. Confidence < 85% → scout sâu hơn (read compose, check llms-full.txt) trước khi đề xuất
Không thay Scout-First, Ask-Second — rule này là concrete trigger cho rule đó trong
domain homelab/infra.
Case study: FluxDown → Aria2 (2026-07-06)¶
Trigger: User hỏi về FluxDown (desktop download manager). Tôi xác nhận không có remote server mode, rồi đề xuất scaffold stack Aria2 + AriaNg.
Vi phạm: Không grep stacks/ trước khi đề xuất.
Thực tế: Stack đã có sẵn hoàn chỉnh:
| Component | Location | Note |
|---|---|---|
aria2 daemon |
stacks/networking/gluetun/compose.yaml L11–40 |
Route qua VPN, IP 10.99.0.4 |
ariang web UI |
stacks/storage/openlist/compose.yaml L16–30 |
Port 6880, auto-connect RPC |
| Integration scripts | scripts/onejav/*.py |
aria2.addUri/addTorrent via RPC+SSH |
| Healthcheck | scripts/onejav/njav_healthcheck.py |
Auto-replace dead torrents |
ariang-seed.js |
stacks/storage/openlist/ariang/ |
localStorage pre-seed RPC URL |
Đáng lẽ một grep aria2 stacks/ (5s) là đủ để biết — thay vì đề xuất sai và bắt
user phải nhắc.
Hậu quả: 1 turn lãng phí + user phải tự verify bằng "hãy verify lại".
Verification commands (cheat sheet)¶
# Service trong compose?
grep -ril "<name>" stacks/ services/
# Đọc tất cả compose có service đó
grep -ril "<name>" stacks/ | xargs grep -A 20 "<name>:"
# Cross-reference docs
grep -i "<name>" llms-full.txt docs/ README.md
# Check integration scripts
grep -ril "<name>" scripts/
When NOT to apply¶
- User explicit create mới ("tạo stack X mới, chưa có") → skip scout, nhưng vẫn confirm nếu tìm thấy trùng.
- Domain knowledge rõ ràng — service chắc chắn chưa tồn tại (vd: "add service cho app mới được tạo lần đầu"). Vẫn nên grep để safe.
- PoC / brainstorm — ở giai đoạn exploratory, đề xuất rộng là OK.
Boundaries¶
Rule này không cho phép:
- Bỏ qua user intent (user nói "tạo mới" → vẫn tạo mới, chỉ verify trước).
- Trì hoãn câu trả lời factual — scout chỉ cho đề xuất thêm mới, không cho câu hỏi factual (vd: "X chạy port nào" → trả lời trực tiếp nếu biết, scout nếu không).
- Replace
Scout-First, Ask-Second— đây là concrete trigger cho rule đó.