OGV-2C R2 — Write Gate + Test Teardown Agent Prompt
OGV-2C R2 — Write Gate + Test Teardown — Agent Execution Prompt
Mục tiêu: Chặn rác lọt vào production KB. Fix hệ thống, không fix vụ việc. VPS:
ssh contabo. Container: discover trước khi sửa. Effort: /effort medium Mode: Discovery → Code changes → Test → Deploy → Post-deploy verify Report:knowledge/dev/laws/dieu44-trien-khai/reports/ogv-2c-write-gate-implementation-report-2026-05-07.md
KHÔNG ĐƯỢC LÀM
- ❌ Không sửa Qdrant code, embedding, chunking
- ❌ Không restart services trừ khi deploy bắt buộc
- ❌ Không xóa/move/cleanup KB documents — scope chỉ là write gate code
- ❌ Không sửa PG triggers, Directus, Nuxt
- ❌ Không dùng
git add -A— chỉgit addfiles đã sửa - ❌ Không sửa read path, delete path, search path
- ❌ Không refactor code không liên quan
Phase 0 — Discovery (READ-ONLY)
Trước khi sửa BẤT CỨ GÌ, agent phải lập bản đồ:
0.1 Tìm write routes
ssh contabo
# Discover container name
docker ps --format '{{.Names}}' | grep -i agent
# Tìm tất cả route/endpoint liên quan upload/create/ingest
docker exec <container> grep -rn "def upload\|def create.*doc\|def ingest\|POST.*doc\|PUT.*doc" /app/
Ghi lại:
- File nào chứa route handler
- Function signature
- Repository/store layer nào được gọi (pg_store? document_store?)
- Middleware nào chạy trước
0.2 Tìm error convention
docker exec <container> grep -rn "HTTPException\|raise.*Error\|abort\|JsonResponse.*4\|status_code.*4" /app/ | head -30
Ghi lại:
- Framework: FastAPI? Flask? Custom?
- Error response format:
{"error": ...}hay{"detail": ...}hay khác? - Status code convention: 400? 422? 403?
0.3 Tìm env/config pattern
docker exec <container> env | grep -i "MODE\|ENV\|DEBUG\|TEST"
docker exec <container> grep -rn "os.environ\|os.getenv\|settings\." /app/ | grep -i "mode\|env\|test" | head -20
0.4 Tìm test hiện có
docker exec <container> find /app -name "test_*" -o -name "*_test.py" -o -name "conftest.py" 2>/dev/null
docker exec <container> grep -rn "def test_\|pytest\|unittest" /app/ | head -20
0.5 Kiểm tra valid top-level paths hiện tại
# Từ KB hiện tại, liệt kê top-level prefixes
docker exec <container> python3 -c "
import requests
resp = requests.get('http://localhost:8000/api/kb/documents', headers={'X-API-Key': '<key>'})
paths = [d.get('path','') for d in resp.json().get('documents',[])]
prefixes = set(p.split('/')[0] for p in paths if '/' in p)
print(sorted(prefixes))
"
Nếu API không hỗ trợ list all → dùng output từ OGV-2A evidence: top prefixes đã biết là knowledge/, operations/, registries/.
Output Phase 0: Ghi tất cả findings vào report section "Discovery". Nếu không tìm được route/error convention → STOP, báo cáo.
Phase 1 — Implement validation
Sau Phase 0, thêm validation vào đúng chỗ trong write path. Dùng error convention thực tế của framework.
Rule 1: Chặn test/ prefix trong production
Nếu path bắt đầu bằng test/ VÀ không có env flag test mode → reject.
- Dùng env variable phát hiện ở Phase 0 (ví dụ
APP_ENV,TEST_MODE, hoặc tương đương). - Nếu không có env variable test mode → tạo mới
KB_TEST_MODEvà document. - Error response: dùng đúng convention Phase 0.2 (ví dụ
HTTPException(status_code=400, detail="...")nếu FastAPI).
Rule 2: Chặn inline- prefix
Mọi document có path bắt đầu bằng inline- bị reject qua API.
- Nếu hệ thống cần internal inline docs → agent phải tìm internal creation path (không qua API route) và chỉ chặn external route.
- Nếu KHÔNG phân biệt được internal/external → chặn toàn bộ
inline-prefix.
Rule 3: Chặn root-level document không có prefix hợp lệ
Valid top-level prefixes (dựa trên Phase 0.5 discovery):
knowledge/operations/registries/
Bất kỳ path nào KHÔNG bắt đầu bằng các prefix này → reject.
Lưu ý: KHÔNG thêm reports/ hay tham-khao/ vào allowlist trừ khi agent chứng minh đó là canonical governed root bằng evidence từ code/config. Root-level reports/ đã gây drift trước đó.
Rule 4: Chặn document chỉ chứa file path (bare path detection)
Chặn document mà TOÀN BỘ content (sau strip whitespace) match một trong:
- Regex:
^file:///.*$(bare file URI) - Regex:
^/Users/[a-zA-Z].*$(bare macOS path) - Content length < 500 chars VÀ match
^(file:///|/Users/|/home/|/tmp/|C:\\)(bare path dưới threshold)
KHÔNG chặn document dài (>500 chars) mention /tmp/ hoặc /Users/ — đó là report kỹ thuật hợp lệ bàn về paths.
Phase 2 — Test
Positive tests (phải PASS)
TEST-POS-1: Upload doc path="knowledge/dev/test-gate-pos.md" content="valid test doc" → 200/201
TEST-POS-2: Upload doc path="operations/tasks/test-gate-pos.md" content="valid task" → 200/201
TEST-POS-3: Upload doc path="knowledge/report.md" content="Report mentioning /tmp/foo and /Users/nmhuyen for analysis purposes, with enough text to pass the 500 char threshold... [pad to >500 chars]" → 200/201 (technical report mentioning paths = OK)
Negative tests (phải bị REJECT — 400 hoặc 422)
TEST-NEG-1: Upload doc path="test/should-block.md" content="test data" → REJECTED
TEST-NEG-2: Upload doc path="inline-should-block" content="some content" → REJECTED
TEST-NEG-3: Upload doc path="random-root-doc" content="orphan at root" → REJECTED
TEST-NEG-4: Upload doc path="knowledge/leak.md" content="file:///Users/nmhuyen/.gemini/tmp/session.txt" → REJECTED (bare path, <500 chars)
TEST-NEG-5: Upload doc path="reports/drift.md" content="drifting report" → REJECTED (reports/ not in allowlist)
Cleanup
Xóa TEST-POS-1, TEST-POS-2, TEST-POS-3 ngay sau test pass.
Phase 3 — Deploy
cd /opt/incomex
# Review changes
git status
git diff
# Scoped add — CHỈ files đã sửa
git add <specific-files-changed>
git commit -m "OGV-2C: write gate — block test/*, inline-*, root-level, bare-path content"
# Nếu cần restart container
docker restart <container>
# Verify healthy
curl -s http://localhost:<port>/health | jq .
Rollback plan
Nếu deploy gây lỗi cho legitimate uploads:
git revert HEAD
docker restart <container>
# Verify: upload một doc hợp lệ → success
Phase 4 — Post-deploy verify
Sau deploy, chạy lại negative tests qua API thật (không phải unit test):
# Negative: test/ prefix
curl -s -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
"http://localhost:<port>/api/kb/documents" \
-d '{"path":"test/post-deploy-neg","content":"should block"}' | jq .status_code
# Expected: 400/422
# Positive: knowledge/ prefix
curl -s -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
"http://localhost:<port>/api/kb/documents" \
-d '{"path":"knowledge/dev/post-deploy-pos.md","content":"should work"}' | jq .status_code
# Expected: 200/201
# Cleanup: DELETE knowledge/dev/post-deploy-pos.md
Report phải có
- Discovery: routes, error convention, env config, existing tests
- Code changes: file paths, function names, diff tóm tắt
- 4 rules: implement hay skip (nếu skip, lý do cụ thể)
- 8 test results: 3 positive + 5 negative — PASS/FAIL
- Deploy method: files added, commit hash
- Post-deploy API evidence: curl output negative + positive
- Rollback note: nếu cần hay không
- Xác nhận: "Không cleanup/move/delete KB documents trong phiên này"
Hard boundaries
- Phase 0 read-only, Phase 1 code only, Phase 2 test only, Phase 3 deploy, Phase 4 verify
- Không skip Phase 0
- Không skip cleanup test docs
- Không sửa code ngoài write path validation
- Không dùng
git add -A
OGV-2C R2 | 2026-05-07 | Discovery-first. Framework-native errors. Scoped git. Post-deploy verify. Chờ GPT/User dispatch.