Đ43 Stage D2 report (8 section full + 6 edge case + 4 lỗ fix)
Đ43 Phase 4a Stage D2 — Generic Renderer Full + Edge Cases
Date: 2026-04-17 UTC+7 Agent: Claude Code CLI Scope: Stage D2 — chạy 8 section đầy đủ + 6 edge case test + đóng 4 lỗ hổng. Status: DONE — 8/8 section OK, 6/6 edge case PASS, 4 lỗ hổng đóng.
1. Extended helper (cp-render-section.py)
Bổ sung 4 capability (đóng 4 lỗ hổng):
| # | Capability | Mechanism |
|---|---|---|
| 1 | Engine dispatch (placeholder_style) | render_with_engine(tpl, data, style, code): mustache → chevron (default), jinja → jinja2. Key lạ → FAIL-FAST |
| 2 | Lỗ 2 — template body rỗng | if not template.strip(): raise ValueError('template body rỗng/whitespace-only (Lỗ 2 guard)'). KHÔNG sinh file rỗng |
| 3 | Lỗ 3 — SQL 0 row | run_query output empty → log(WARN 0 rows) + return {} (KHÔNG fail), helper tiếp tục render với data dict chỉ có 4 runtime fields |
| 4 | Lỗ 4 — data_source chưa support | ds in ('filesystem_scan', 'custom') → log(WARN SKIP) + sys.exit(77). Build.sh map exit 77 → skip=+1 (KHÔNG fail, KHÔNG crash) |
Helper exit codes: 0 OK · 1 FAIL · 77 SKIP.
2. Build.sh generate() updated
Thêm counter skip + branch rc_code -eq 77. Summary line: ok=N warn=N skip=N fail=N total=N.
3. dot_config.context_pack_python_deps
UPDATE dot_config SET value='["chevron","jinja2"]' WHERE key='context_pack_python_deps';
PRECHECK 1.9 verify import — jinja2 có sẵn qua apt python3-jinja2 3.1.2, không phải pip install.
4. Full 8-section run (dry-run as incomex)
Command:
cd /tmp && sudo -u incomex -H \
/opt/incomex/dot/bin/dot-context-pack-build.sh --dry-run --trigger-source=on_demand
Build output: /opt/incomex/context-pack.tmp/20260417-145705-2beef4/
| Section | Filename | Size (bytes) | Min | Max | Status |
|---|---|---|---|---|---|
| project_map | PROJECT_MAP.md | 6604 | 3000 | 20000 | OK |
| laws_index | LAWS_INDEX.md | 36329 | 1000 | 15000 | OK (size WARN > max) |
| dot_registry | DOT_REGISTRY.md | 44764 | 2000 | 30000 | OK (size WARN > max) |
| entities_overview | ENTITIES_OVERVIEW.md | 3090 | 500 | 10000 | OK |
| db_map | DB_MAP.md | 582 | 1000 | 15000 | OK (size WARN < min) |
| red_zones | RED_ZONES.md | 1332 | 500 | 8000 | OK (static, no query) |
| architecture_mmd | ARCHITECTURE.mmd | 915 | 500 | 15000 | OK |
| project_map_json | project-map.json | 44979 | 200 | 5000 | OK (size WARN > max) |
Summary: ok=8 warn=4 skip=0 fail=0 total=8.
Tất cả 8 file sinh ra thành công. 4 WARN chỉ là size ngưỡng seed v1.1 chưa calibrate với data thực tế sau S115 migration — không phải render fail. File vẫn viết đầy đủ.
Head 5 dòng kiểu markdown/mermaid (tất cả 7 section non-json):
<!-- VOLATILE HEADER -->
generated_at: 2026-04-17T14:57:06Z
build_id: 20260417-145705-2beef4
git_commit: unknown
trigger_source: on_demand
Head 5 dòng project-map.json (format json):
{
"_volatile_header": {
"generated_at": "2026-04-17T14:57:06Z",
"build_id": "20260417-145705-2beef4",
"git_commit": "unknown",
5. 6 Edge case test evidence
Setup: INSERT 6 fake section rows (_dot_origin='d2_test_ephemeral', order_index 100-105) + upload 4 fixture KB docs. Run each qua ONLY_SECTION=<code> filter. DELETE 6 fake rows sau test. Fixture KB docs giữ để replay.
(a) Engine dispatch placeholder_style='jinja' — PASS
Section: test_jinja, template = jinja syntax {% for db in databases %}...{% endfor %}, query = db_map.sql.
[OK] generate[test_jinja] size=446 (min=50 max=5000)
Output TEST_JINJA.md:
# Jinja Dispatch Test
Engine: jinja2
## Scan Mode (via jinja {% %} loops)
mode = catalog
## Databases
- directus | warehouse | 300 MB
- incomex_metadata | brain-store | 51 MB
- postgres | cluster-admin | 7519 kB
- workflow | engine | 7591 kB
## Summary
Total databases: 4
{% for %} iteration + | length filter → jinja2 rendering xác nhận (chevron không hiểu {% %}).
(b) Lỗ 2 — empty template body — PASS (fail-fast)
Section: test_empty_tpl, template_kb_path = empty body (2 bytes \n\n).
[ERR] generate[test_empty_tpl] FAIL rc=1
Render log:
[render] template loaded: knowledge/current-state/templates/test_empty.md.tmpl (2 bytes)
[render] FATAL section=test_empty_tpl: ValueError: template body rỗng/whitespace-only (Lỗ 2 guard)
KHÔNG sinh file rỗng.
(c) Lỗ 3 — SQL 0 row — PASS (WARN + minimal file)
Section: test_zero_row, SQL SELECT 1 WHERE 1=0, template minimal.
[OK] generate[test_zero_row] size=199 (min=50 max=5000)
Render log:
[render] WARN psql returned 0 rows — proceeding với data dict rỗng
[render] query returned 0 keys
[render] wrote TEST_ZERO.md (199 bytes)
File TEST_ZERO.md (tối thiểu, không fail):
<!-- VOLATILE HEADER -->
generated_at: ... <4 fields> ...
<!-- /VOLATILE HEADER -->
# Minimal Test
empty-if-no-rows
Mustache {{#items}}...{{/items}} section correctly bỏ qua (list không có trong data dict).
(d) render_config key lạ — PASS (fail-fast)
Section: test_bogus_key, render_config = {"bogus":"x"}.
[ERR] generate[test_bogus_key] FAIL rc=1
Render log:
[render] FATAL section=test_bogus_key: ValueError: §5.7 P9 render_config key ngoài whitelist (section=test_bogus_key): ['bogus']
(e) template_kb_path NULL — PASS (fail-fast rev 4)
Section: test_null_tpl, template_kb_path = NULL.
[ERR] generate[test_null_tpl] FAIL rc=1
Render log:
[render] FATAL section=test_null_tpl: ValueError: template_kb_path NULL (Đ43 rev 4 CẤM built-in fallback) section=test_null_tpl
(f) Lỗ 4 — data_source='filesystem_scan' — PASS (SKIP exit 77)
Section: test_fs_scan, data_source=filesystem_scan, target_db=NULL (khớp rev 6 chk_target_db_consistency).
[WARN] generate[test_fs_scan] SKIP data_source chưa support (exit 77)
[INFO] generate summary: ok=0 warn=0 skip=1 fail=0 total=1
[OK] generate DONE
Render log:
[render] WARN data_source='filesystem_scan' not supported in Stage D2 — SKIP section=test_fs_scan
KHÔNG crash, KHÔNG sinh file, build tiếp tục bình thường. Out_dir rỗng xác nhận không có stub file.
6. Evidence summary
| Test | Expected | Actual | 4 Lỗ |
|---|---|---|---|
| a. jinja dispatch | OK + jinja2 syntax rendered | ok=1 size=446, {% for %} iteration + ` |
length` filter PASS |
| b. empty tpl | FAIL + no file | fail=1, FATAL "Lỗ 2 guard" | Lỗ 2 ĐÓNG |
| c. zero row | OK + WARN + minimal file | ok=1 size=199, WARN "0 rows", file đầy đủ volatile header | Lỗ 3 ĐÓNG |
| d. bogus key | FAIL | fail=1, FATAL "§5.7 P9 key ngoài whitelist" | existing guard |
| e. null tpl | FAIL | fail=1, FATAL "rev 4 CẤM built-in fallback" | existing guard |
| f. filesystem_scan | SKIP, no crash | skip=1, WARN "SKIP exit 77", out_dir rỗng | Lỗ 4 ĐÓNG |
7. Cleanup
DELETE FROM context_pack_section_definitions WHERE _dot_origin='d2_test_ephemeral';
-- DELETE 6
-- remaining: 0
-- total_active: 8 (seed)
4 KB fixture giữ tại:
knowledge/current-state/templates/test_{jinja,empty,minimal}.md.tmplknowledge/current-state/queries/test_zero_row.sql
Giữ để replay test (tag ephemeral + stage-d2-test trong metadata). Desktop quyết cleanup nếu muốn.
8. TD mới
| ID | Mô tả | Priority |
|---|---|---|
| TD-S178-26 | Size ngưỡng seed v1.1 (min_size_bytes / max_size_bytes trong §5.7) chưa calibrate với data production post-S115 migration. 4/8 section báo WARN (laws_index/dot_registry/project_map_json > max; db_map < min). Stage Phase 4b validate sẽ quyết: (a) UPDATE ngưỡng bảng §5.7, (b) trim SQL output, (c) amend luật ngưỡng. |
Medium — Phase 4b |
9. Artifacts uploaded KB
knowledge/dev/dot/cp-render-section.pyrev=2 (+engine dispatch, +3 lỗ fix)knowledge/dev/dot/dot-context-pack-build.shrev=4 (+skip counter)knowledge/dev/laws/dieu43-migrations/report-stage-d2.mdrev=1
Sẵn sàng Stage E (Bước 6 VALIDATE) / Phase 4b sau Desktop gate.
D2 Report | Claude Code CLI | 2026-04-17 S178 Fix 12 post-D1 gate | Đ43 v1.2 rev 6 generic renderer + 6 edge cases + 4 lỗ hổng ĐÓNG