Skip to content

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:

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: aria2 sống trong gluetun stack, không phải aria2 stack).
  • Service đã được migrate giữa stack (vd: aria2 từ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ả:

  1. Wasted turn: user phải correct lại thay vì việc tự scout mất 5s.
  2. 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 đó.