INV — Search/Vector Hygiene: Context-Pack Duplication Report
INV — Search/Vector Hygiene: Context-Pack Duplication Report
Date: 2026-05-05 | Status: READ-ONLY INVESTIGATION COMPLETE Controlling prompt:
knowledge/dev/laws/dieu44-trien-khai/prompts/inv-search-vector-hygiene-context-pack-prompt.mdrev2 Scope: §0–§4 hard boundaries respected. No mutation, no delete, no deindex, no DOT/§43 patch.
§0. 4-LAYER MAP (per prompt §0)
| Layer | Concrete location | Status today |
|---|---|---|
| 1. Source-of-truth docs | knowledge/dev/laws/, knowledge/dev/architecture/, knowledge/ops/processes/, registries/, official reports |
Active, 1 615 docs under knowledge/, 222 under registries/ |
| 2. Generated snapshots (Đ43) | context-pack/<build_id>/* (root prefix in KB), VPS filesystem /opt/incomex/context-pack/{current,staging}/ |
141 historical builds in KB (1 174 docs); FS mirror unverified read-only this session |
| 3. Search/vector index | Qdrant (Agent Data), embeds every uploaded doc; no per-prefix exclusion | Same Qdrant pool serves both canonical + snapshots |
| 4. Runtime context cache | PG view v_context_pack_latest + manifest tables (context_pack_manifest/_requests/_sections) |
Per Đ43 §5; canonical pointer to "latest" |
"Delete from KB" ≠ "deindex from hot vector" — the upload-time embedding pipeline embeds whatever is uploaded; there is no separate hot/cold tier today.
§1. READ-LIST RESULT
| Doc | Read | Notes |
|---|---|---|
knowledge/dev/laws/dieu43-system-context-law.md |
✅ v1.2 FINAL, 46 384 chars | §5–§8 cover schema/build/8-section output. Đ43 không có TTL / retention / deindex / hot-cold rule. Search cho vector, Qdrant, retrieval, TTL, dedup, rerank, hot, cold → 0 hits có ý nghĩa policy (chỉ 1 hit dedupe_bucket về cron-trigger, không phải vector dedup). |
knowledge/current-state/context-pack/README.md |
✅ 726 chars | Khẳng định: live = overwrite-in-place. "DOT tự overwrite file mỗi build." Mirror FS: /opt/incomex/context-pack/current/. |
knowledge/current-state/context-pack-staging/README.md |
✅ 676 chars | Staging tạm; promote sang live. Mirror FS: /opt/incomex/context-pack/staging/. |
knowledge/dev/dot/dot-context-pack-build.sh |
✅ rev 11, 59 076 chars | Upload code thực tế (L1037, L1067): doc_id="context-pack/${BUILD_ID}/${outname}" — mỗi build tạo path mới, không overwrite, không delete bản cũ. |
Kết luận §1: Không có design canonical về vector hygiene/TTL/retention. README live folder mô tả "overwrite-in-place" nhưng DOT script dùng <build_id>/ accumulation pattern → phân kỳ giữa văn bản luật và hiện thực hệ thống.
§2. CÂU HỎI ĐIỀU TRA
Q1 — Document count theo prefix
| Prefix | Count |
|---|---|
| Toàn KB (root listing) | 3 134 |
context-pack/ (snapshots, root prefix) |
1 174 (≈ 37.5 % toàn KB) |
knowledge/current-state/context-pack/ |
1 (chỉ README placeholder) |
knowledge/current-state/context-pack-staging/ |
1 (chỉ README placeholder) |
knowledge/dev/laws/ |
538 |
knowledge/dev/laws/dieu44-trien-khai/ |
233 |
knowledge/ops/processes/ |
1 (chỉ birth-process-v1.md) |
knowledge/dev/dot/ |
3 |
registries/ |
222 |
knowledge/ (toàn nhánh) |
1 615 |
Khác (operations/, reports/, tham-khao/, test, ...) |
123 |
Cấu trúc 1 174 docs trong context-pack/: 141 build-folders × ~8–9 file/build (PROJECT_MAP.md, LAWS_INDEX.md, DOT_REGISTRY.md, ENTITIES_OVERVIEW.md, DB_MAP.md, RED_ZONES.md, ARCHITECTURE.mmd, PROJECT_MAP.json, …).
Build cadence quan sát: 3 h cron (đúng §8.1 Đ43) — đa số builds đều 9 file. Tuy nhiên 9 build gần nhất (kể từ 2026-05-04 07:00) chỉ có 1 file/build (PROJECT_MAP.md đơn lẻ) → pipeline có thể đang lỗi/partial. Build complete cuối: 20260504-040018-372b48 (9 file).
Q2 — Chunk/vector counts
Qdrant không truy được trực tiếp qua tool MCP hiện có. Ước lượng dựa trên total_chunks quan sát qua search snippet metadata:
| Section | total_chunks (mẫu) |
|---|---|
PROJECT_MAP.md |
6 |
DOT_REGISTRY.md |
13 |
ENTITIES_OVERVIEW.md |
4–8 (chưa truy đủ) |
Ước số học: 1 174 docs × trung bình ~7 chunks ≈ ~8 200 vector chunks thuộc context-pack/ (giả định). Vector của canonical (laws, registries, architecture) tổng cộng ước < 5 000 (1 615 + 222 docs với chunk size nhỏ hơn cho registry record). → Context-pack có khả năng chiếm > 60 % toàn vector pool, dù chỉ là snapshot phái sinh. Cần quyền đọc Qdrant để xác nhận chính xác (đề xuất follow-up).
Q3 — Search pollution test (7 query, limit yêu cầu = 20 nhưng tool trả tối đa 5/query — limitation đã ghi nhận)
| # | Query | Trả về | CP* | Canonical | Top-5 có canonical? | Ghi chú |
|---|---|---|---|---|---|---|
| 1 | birth pipeline QT-001 QT-002 fn_birth_registry_auto | 5 | 0 | 5 | ✅ rank 1–5 | Sạch |
| 2 | DOT-119 birth trigger setup | 5 | 1 | 4 | ✅ canonical chiếm 1–4 | CP rank 5 (chunk 8 DOT_REGISTRY.md) |
| 3 | orphan ghost birth registry | 5 | 0 | 5 | ✅ | Sạch |
| 4 | information_unit unit_version schema | 5 | 0 | 5 | ✅ | Sạch |
| 5 | description_policy structured_exempt | 5 | 5 | 0 | ❌ | 100 % pollution. Top-5 là 5 build-folder khác nhau, cùng chunk 11 DOT_REGISTRY.md, score 0.3996–0.3997 (gần như bằng nhau → search đang trả 5 bản sao của cùng một fact) |
| 6 | Điều 43 context pack lifecycle | 5 | 4 | 1 | ⚠️ canonical duy nhất là README placeholder (knowledge/current-state/context-pack/README.md) — không phải Đ43 luật |
Pollution cao + canonical-yếu |
| 7 | birth-process-v1 QT-002 | 5 | 0 | 5 | ✅ | Sạch |
*CP = context-pack/ snapshot result.
Tổng quan Q3: 6/35 (17 %) results là CP, nhưng 2/7 query (Q5, Q6) bị pollution nghiêm trọng — đặc biệt Q5 là 100 % CP và 5 hits là 5 bản sao gần-trùng-lặp của cùng dữ kiện (giống nhau đến 4 chữ số sau dấu phẩy của score). Đó là tín hiệu rõ rệt near-duplicate flood đang đẩy canonical ra khỏi top-K khi query không khớp tag canonical.
Q4 — Metadata inspection
3 mẫu CP (từ Q3, Q5):
| Field | Giá trị |
|---|---|
tags |
["dieu43","context-pack","build"] (đồng nhất 100 % qua 1 174 docs) |
source |
"dieu43_context_pack_publish" (đồng nhất) |
build_id |
có (vd 20260418-130008-2d77e8) |
title |
pattern "Đ43 context-pack <build_id> section=<section>" |
chunk_index / total_chunks |
có |
is_latest / live flag |
KHÔNG CÓ |
3 mẫu canonical:
| Doc | Tags |
|---|---|
knowledge/dev/architecture/birth-registry-law.md |
["architecture","birth-registry","S157","inspection","universal-counter","law"] |
registries/meta_catalog/CAT-023 |
rỗng list (metadata.tags = []), nhưng có code, source="directus", entity_type, layer, record_count |
knowledge/dev/laws/dieu44-trien-khai/reports/p2b-inv-birth-pipeline-inventory-report.md |
["birth-pipeline","inventory","investigation","read-only","p2b-inv","report"] |
Kết luận Q4:
- ✅ Đủ metadata để filter CP ra khỏi search mặc định bằng 1 trong các predicate sau (bất kỳ cũng đủ):
path startswith 'context-pack/',metadata.source = 'dieu43_context_pack_publish','context-pack' in tags AND 'build' in tags. Tag set CP rất nhất quán. - ❌ Không có metadata flag phân biệt latest-snapshot vs historical-snapshot. Phải lookup
v_context_pack_latestở PG hoặc so sánhbuild_idlexicographic (yyyymmdd-hhmmss-…) — không phải native filter. - ✅ Canonical tags đa dạng theo chủ đề; không nhất quán nhưng không cần thiết phải nhất quán cho mục đích này.
Q5 — Context-pack lifecycle theo Đ43
- Là gì: Snapshot 8 section (
project_map,laws_index,dot_registry,entities_overview,db_map,red_zones,architecture_mmd,project_map_json) — được build định kỳ để cung cấp ngữ cảnh hệ thống cho agent (§4, §6, §7). - Chu kỳ: cron 3 h (§8.1).
- Live vs staging: Đ43 §6 Bước 7a: build vào staging → verify → 7d promote sang live. README live (
knowledge/current-state/context-pack/) khẳng định semantics overwrite-in-place. - Realtime gap: DOT script ghi sang
context-pack/<build_id>/(root-level), KHÔNG vàoknowledge/current-state/context-pack/, KHÔNG có bước delete bản cũ. README placeholder cho live folder vẫn nguyên 1 file duy nhất từ phase 3 (2026-04-17). - TTL / retention / deindex: không tồn tại trong Đ43. Ngầm: filesystem
/opt/incomex/context-pack/current/được overwrite (1 bản), KB-side accumulating (141 bản và đang tăng).
Q6 — Storage pattern hiện tại
| Storage | Bản chất | Lượng | Ghi chú |
|---|---|---|---|
KB Agent Data (context-pack/<bid>/...) |
Vector + doc store | 1 174 docs / 141 builds | Chứa toàn bộ lịch sử từ 2026-04-18 đến 2026-05-05. Đây là nguồn pollution chính. |
KB live folder (knowledge/current-state/context-pack/) |
Theo design = nơi đọc cho agent | 1 doc (README placeholder phase 3, 2026-04-17) | Trống dữ liệu thật → không khớp design Đ43. |
Filesystem VPS /opt/incomex/context-pack/{current,staging}/ |
Mirror FS | Không kiểm tra read-only session này (boundary: không SSH inspect ngoài scope) | Theo README sẽ là 1 bản latest + staging tạm. |
PG context_pack_requests / _manifest / _sections (Đ43 §5) |
Audit + binding | Không kiểm tra count session này | v_context_pack_latest view → canonical pointer "latest". |
→ Tridundancy 3 lớp (KB lịch sử + KB live folder design-only + FS + PG manifest). Lớp KB lịch sử là chỉ phần ngoài kế hoạch.
Q7 — Duplicate / near-duplicate evidence
3 mẫu PROJECT_MAP.md lấy từ 3 build cách nhau ~16 ngày:
| build_id | Ngày | content_length | Header |
|---|---|---|---|
20260418-023221-0bfb97 |
2026-04-18 | 6 072 | enacted laws=38, DOTs=256/272, entities=43 641 |
20260426-040009-7c31ea |
2026-04-26 | 20 490 | enacted laws=41, DOTs=270/288, entities=61 419 |
20260504-040018-372b48 |
2026-05-04 | 21 713 | enacted laws=41, DOTs=289/307, entities=72 670 |
Quan sát so sánh 500 ký tự đầu:
- Volatile-header block giống hệt schema (
generated_at / build_id / git_commit / trigger_source). - Heading bố cục giống hệt (
# PROJECT MAP,## System Snapshot,## Active Databases). - Số liệu cuối-từng-dòng khác nhau (laws/DOTs/entities tăng dần).
- Ước similarity cấu trúc ≈ 90 %, similarity nội dung ≈ 30–60 % giữa 2 build cách nhau ~1 tuần (vì entity counts thay đổi). Giữa 2 build cách nhau 3 h gần 100 % — bằng chứng gián tiếp Q5 query trả 5 chunk score = 0.3996…0.3997 (gần như bằng nhau).
→ Confirmed: cron 3 h tạo ra near-duplicate streams. Không có dedup.
Q8 — Latest-only detection
- Latest build_id (theo timestamp lexicographic):
20260505-070008-4860b7(1 file — partial). - Latest build_id COMPLETE (9 files):
20260504-040018-372b48(2026-05-04 04:00). - 9 build gần nhất (kể từ 2026-05-04 07:00) chỉ có 1 file — flag pipeline degradation cần điều tra ngoài scope.
- Stable live/latest path KB: ❌ không có.
knowledge/current-state/context-pack/rỗng dữ liệu thật. - Latest pointer thực sự: PG view
v_context_pack_latest(Đ43 §5.5). - Native metadata field xác định latest: ❌ không có. Phải so
build_idstrings hoặc query PG.
Q9 — Industry-aligned options A–H
| Option | Feasibility | Rủi ro | Cần DDL/tooling? | Phù hợp Đ43? | Ảnh hưởng Agent runtime |
|---|---|---|---|---|---|
A Exclude context-pack/<build_id>/ khỏi search mặc định |
Cao — 1 metadata filter ở search layer | Thấp; vẫn searchable nếu query opt-in | Sửa search wrapper (Agent Data API) | Không sửa luật; bổ sung phụ lục retrieval policy | Agent ít noise hơn; cần biết khi nào opt-in |
| B Chỉ giữ latest CP trong hot vector | Trung — cần viết promote/demote pipeline | Mất audit trail nếu xoá; phải định nghĩa "latest" | Có (job/promote logic) | Phù hợp tinh thần README live=overwrite | Best signal/noise; latest-by-design |
| C Snapshots ở cold storage / FS / manifest, không vector hot | Trung-cao — đã có FS mirror | Mất khả năng full-text search lịch sử | Có (cold-tier infra) | Phù hợp Đ43 §5 manifest | Latency tăng cho query lịch sử (hiếm) |
| D Metadata filter mặc định: exclude CP trừ khi query yêu cầu | Cao — chỉ search-side change | Hành vi mặc định khác trước → cần thông báo | Sửa Agent Data search default | Không sửa luật | Agent phải biết flag opt-in include_context_pack=true |
| E Dedup/near-dedup trước embedding | Trung — cần MinHash/SimHash hoặc semantic | Có thể bỏ sót diff nhỏ quan trọng | Có (pre-embed pipeline) | Phù hợp; không xung đột Đ43 | Vector pool nhỏ hơn nhiều |
| F TTL/retention: giữ N builds gần nhất | Cao — cron job xoá theo build_id |
Mất history sau N | Có (TTL job) | Cần phụ lục Đ43 quy định N | Pool cap; predictable |
| G Hybrid retrieval: canonical first, CP fallback | Cao — rerank logic | Logic phức tạp; cần feature flag/test | Có (retrieval orchestrator) | Không sửa luật | Tốt cho UX; nhưng vẫn embed all |
| H (User/Opus đề xuất) Delete bản cũ khỏi KB sau khi upload bản mới; giữ 7 ngày FS audit | Cao — DOT build script thêm 1 lệnh delete sau 7d | An toàn vì FS giữ 7 ngày = đủ audit; cần đảm bảo PG manifest không FK orphan | Sửa DOT (dot-context-pack-build.sh) + cron cleanup |
Phù hợp tinh thần "live overwrite" của README | Vector pool gọn nhất; giảm pollution gốc-rễ |
Đánh giá ngang hàng A–H:
- H giải quyết gốc-rễ (không upload accumulating), gọn vận hành, nhưng động vào DOT (cần APR + Đ43 phụ lục TTL).
- D là quick-win 0-rủi-ro (search-side default), nên triển khai song song trong khi H phát triển.
- B + F chồng lấp với H (B = "giữ 1 latest"; F = "giữ N"); H là special case của F với N=1 + FS audit.
- A = phiên bản đơn giản hơn của D; thực chất giống nhau.
- C không cần thiết nếu H/F áp dụng (FS + PG đã là cold).
- E trị triệu chứng (dedup), không trị gốc; nên dành cho công việc khác.
- G trị triệu chứng (rerank); chỉ giúp khi vẫn giữ snapshots — kém ưu tiên nếu chọn H/F.
Kết hợp khuyến nghị: D + H (D ngay lập tức, H là long-term fix). Tuỳ chọn bổ sung G nếu muốn agent có lựa chọn fallback khi opt-in.
Q10 — Retrieval policy recommendation
- Default include:
knowledge/,registries/,operations/,reports/. - Default exclude:
context-pack/<build_id>/(filtermetadata.source != 'dieu43_context_pack_publish'). - Khi nào include CP: query opt-in (
include_context_pack=true) HOẶC query có chứa tokenbuild_id/context-packHOẶC khi caller là agent ngữ-cảnh-bootstrap đọc latest manifest qua PG view. - Canonical-first hay snapshot-first: canonical-first (luật + registry + report là SSOT, snapshot là phái sinh).
- Metadata filters cần thiết (search layer): predicate trên
metadata.source,metadata.tags, hoặc path-prefix. - Dedup/rerank: chưa cần ngay nếu D+H triển khai. Sau D+H mà vẫn thấy near-dup trong canonical (hiện tại không có evidence) thì mới bật dedup.
Q11 — Risk note
- Xoá CP docs khỏi KB có thể phá audit/history chỉ khi không có cold copy. Hiện: FS mirror
/opt/incomex/context-pack/current/chỉ giữ 1 latest; FS lịch sử không xác nhận → rủi ro mất history nếu xoá ngay mà không backup 7 ngày. - Deindex khỏi hot vector (giữ doc trong KB nhưng filter ra search) an toàn hơn delete — reversible, không mất audit.
- Cold/archive (FS, PG manifest) đủ cho audit miễn FS giữ tối thiểu 7 ngày + manifest PG bất biến (Đ43 §5.3 đã có
manifest_id+ checksum). - Filesystem VPS hiện tại đủ chưa: chưa rõ — README nói
/opt/incomex/context-pack/current/là 1 bản (không lịch sử). Đề xuất: trước khi bật H, kiểm tra/opt/incomex/context-pack/có đủ 7 ngày retention thật sự không.
Q12 — Direct recommendation (8 câu)
- Có nên xoá historical CP khỏi KB không? → Có, nhưng chậm — chỉ sau khi (a) FS retention ≥ 7 ngày confirmed, (b) PG manifest bất biến, (c) Đ43 phụ lục TTL ban hành. Trong giai đoạn quá độ: deindex (D) trước, delete (H) sau.
- Có nên deindex historical CP khỏi vector không? → Có, ngay lập tức ở search layer (D). Reversible, 0-rủi-ro mất dữ liệu.
- Có nên giữ latest CP trong hot index không? → Có — agent cần snapshot context khi cần. Nhưng phải có flag
is_latest=true(mới) hoặc dùng PG viewv_context_pack_latestđể rerank. - Cần cold index riêng không, hay FS đủ? → FS + PG manifest đủ nếu retention ≥ 7 ngày + checksum verifiable. Không cần cold-index riêng.
- Metadata filter mặc định nên là gì? →
metadata.source != 'dieu43_context_pack_publish'(đơn giản, đã đồng nhất 100 %). Tương đương path filterNOT startswith('context-pack/'). - Cần sửa luật Đ43, DOT build, hay search layer? → Cả 3: Search layer (D, ngay), DOT build (H, mid-term), Đ43 phụ lục TTL/retention/deindex policy (formalize). APR cần thiết cho H + Đ43.
- Cần dọn ngay hay staged migration? → Staged: Stage 1 = D (search-side default exclude, không xoá gì). Stage 2 = phụ lục Đ43 + DOT script H. Stage 3 = backfill xoá historical builds đã > 7 ngày.
- Option khuyến nghị + kết hợp: D (Stage 1) + H (Stage 2) + G (optional Stage 3). F/B là biểu hiện đặc biệt của H; E không cần thiết; A là tập con D; C không cần thiết.
Q13 — Success metrics
Sau Stage 1 (D):
- CP share trong top-20 canonical queries: từ baseline (Q3 đo: 17 % bulk, 100 % cho query Q5) → mục tiêu ≤ 5 % (chỉ khi opt-in).
- Canonical xuất hiện top-5 cho 7 known queries: từ 6/7 hiện tại → 7/7.
- Latest CP vẫn tìm được: query opt-in (
build_id=…hoặcinclude_context_pack=true) phải trả ≥ 1 result đúng latest.
Sau Stage 2 (H):
- Vector pool tổng giảm ≥ 50 % (loại ~8 200 chunks CP lịch sử).
- Số doc CP trong KB ≤ 9 + 9 (latest + staging) thay vì 1 174.
- 0 near-duplicate giữa các build cách nhau 3 h.
Sau Stage 3 / lifecycle:
- Mỗi cron 3 h: KB net-zero growth từ CP (upload mới = delete cũ).
- FS retention ≥ 7 ngày verifiable bằng
ls /opt/incomex/context-pack/.
§3. ASSUMPTIONS / LIMITATIONS
- Search tool trả tối đa 5 kết quả/query dù
limit=20được set. Không thể đo top-20 trực tiếp; pollution thực có thể cao hơn ở rank 6–20. - Không có quyền đọc Qdrant trực tiếp từ tool MCP hiện có; vector counts là ước lượng từ
total_chunksquan sát. - Không SSH/đọc filesystem VPS trong session này (boundary read-only KB-side); FS retention thực tế của
/opt/incomex/context-pack/chưa xác nhận. - PG manifest tables (
context_pack_manifest/_requests/_sections) không inspect trong session này; counts/state chưa kiểm tra. - 9 build gần nhất chỉ có 1 file — tín hiệu pipeline degradation độc lập với scope investigation, nên flag riêng để team Đ43 xử lý.
§4. HARD BOUNDARIES — VERIFIED
- ✅ NO deleteDocument
- ✅ NO deindex
- ✅ NO patch DOT scripts
- ✅ NO patch Đ43
- ✅ NO sửa vector config
- ✅ NO mutate DB
- ✅ NO cleanup
- ✅ Chỉ report hiện trạng + options
INV Search/Vector Hygiene Report | 2026-05-05 | rev 1 — read-only investigation hoàn tất, đáp 13 câu hỏi của prompt rev2.