KB-38D5

Đ43 Stage D2 report (8 section full + 6 edge case + 4 lỗ fix)

9 min read Revision 1
dieu43stage-d2rev6

Đ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.tmpl
  • knowledge/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.py rev=2 (+engine dispatch, +3 lỗ fix)
  • knowledge/dev/dot/dot-context-pack-build.sh rev=4 (+skip counter)
  • knowledge/dev/laws/dieu43-migrations/report-stage-d2.md rev=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