KB-77E6

OGV-2C R2 — Write Gate + Test Teardown Agent Prompt

8 min read Revision 1
ogv-2cr2write-gatetest-teardownagent-promptvector-hygiene2026-05-07

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 add files đã 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_MODE và 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ó

  1. Discovery: routes, error convention, env config, existing tests
  2. Code changes: file paths, function names, diff tóm tắt
  3. 4 rules: implement hay skip (nếu skip, lý do cụ thể)
  4. 8 test results: 3 positive + 5 negative — PASS/FAIL
  5. Deploy method: files added, commit hash
  6. Post-deploy API evidence: curl output negative + positive
  7. Rollback note: nếu cần hay không
  8. 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.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/prompts/ogv-2c-r2-write-gate-and-test-teardown-agent-prompt-2026-05-07.md