Mục lục · 9 mục
TL;DR
- Sprint 6 EXTENDED của initiative JARVIS v2 close 100% trong 1 tối — 16 ticket / ~6 giờ làm việc liên tục.
- 2 block lớn ship: Block D (BOQ Builder v8 retrospect) + Block C (Vision-First 4-Layer Pipeline).
- Velocity 11× sustained: ~242h plan / ~22h actual qua 5 calendar days. Block D riêng đạt 17×.
- Tag local
sprint-6-done-allapply, 5/5 acceptance box critical đã check ✓. - Bài học cứng: dogfood skill mới ngay trên dự án production thật là cách verify pattern duy nhất tin được.
Mở terminal nghĩ làm 2-3 ticket
Đầu tối mở terminal sau bữa ăn. Mở sprint_06.md định check status. Đập ngay vào mặt: Block C 0/10, Block D đang in-progress, 4 acceptance box còn pending.
Nghĩ đầu là làm 2-3 ticket “dễ ăn” — V1+V2+V6 (extend script render PNG + setup venv + image downsampler tool). Plan estimate 6 giờ. Nếu velocity bình thường ~3× thì 2 giờ thực.
Mở read_drawing.py, đọc structure 615 dòng. Pattern đã có sẵn: read_pdf() dùng pdfplumber, read_dxf() dùng ezdxf, read_dwg() convert qua ODAFileConverter. Việc của tôi: thêm function render_pdf_pages() + render_dxf_layouts() (qua ezdxf.addons.drawing.matplotlib MatplotlibBackend) + render_dwg_layouts() (DWG → DXF tạm rồi render).
Code chừng 30 phút. Smoke test ngay với file PDF thật của dự án 1 dự án office cấp 4 V2 — 2 page render thành PNG 300KB mỗi cái. Index JSON ghi đầy đủ metadata. Done.
Cuốn theo dòng work
V1 xong, sang V6 — image_downsampler.py. Pattern đơn giản: Pillow Lanczos resample về ≤1568px long-edge, save JPEG quality 85% progressive. Convert RGBA→RGB cho JPEG safe. Code ~100 dòng, 20 phút.
Test với batch chính 9 file PNG render từ dự án thật → 0.61 MB total. Dưới ngưỡng 32 MB Claude vision API ceiling rất thoải mái — có thể gửi 30+ page trong 1 batch nếu cần.
V3+V4 hơi khác. Theo plan ban đầu là “Claude vision multi-call sequential, 3 page per call”. Implementation cleanest: thêm 4 step mới vào orchestrator.py STEPS array. 2 step deterministic (render + bucket), 2 step claude_skill (3D context + 2D extraction). Orchestrator subprocess invoke claude CLI với prompt dài instruction.
Wire xong. STEPS list parse OK, count = 12 (từ 8 cũ → 12 mới).
Block D quay lại
Ngó danh sách todo: Block D “BOQ-V8 epic” cũng đang in-progress từ session trước. Trạng thái: V8-01 done (match-by-code), V8-02 → V8-06 pending.
V8-02 Pre-flight validator. Mục tiêu: catch 5 bug class đã gặp trong 1 dự án office cấp 4 V2:
vat_tu + nhan_cong + thiet_bi ≠ don_gia(item III.1, III.2 đã có)KL_kltt ≠ qtydrift > 5%- Note bắt đầu bằng
=→ thành#ERROR!trên Google Sheet nếu builder không escape - Item thiếu
areafield (Cost by Area module yêu cầu) - Confidence avg < 65 (block push)
Code ~250 dòng validate_boq_data.js, 4 levels: ERROR/WARN/INFO/OK. Run trên data 1 dự án office cấp 4 V2 thật → 0 ERROR / 0 WARN / 15 INFO. Run trên broken sample → 4 ERROR caught đúng + exit code 1 block push.
V8-03 Safe section delete. Bug đã gặp: update_appendix_v2.js cũ làm deleteDimension(rows 32-200) thô — xóa luôn Value Proposition + Signature blocks ở dưới, mất nội dung phải restore tay 30 phút. Fix: helper sheet_section_manager.js với findSectionRange + deleteSection + replaceSectionRows. Guard rails cứng: refuse > 50 rows nếu không pass force: true, refuse > 200 rows always (sanity check).
V8-04 KLTT schema migration. Trước đây detectAreaFromText() dùng regex 12+ pattern — fragile. Fix: thêm field area explicit vào mỗi section + leaf row. Migrate in-place dự án 1 dự án office cấp 4 V2 với --boq fallback (lấy area từ item nếu section text không match) → 23 entries / 30 sections / 124 leaves added area / 0 unmapped.
V8-05 Cost Breakdown by Area module. Promote từ tools_local/restore_cost_payment.js (~600 dòng project-specific) sang cost_by_area.js skill core. Pure functions: computeDistribution() + buildAreaTableRows(). Priority chain: allocationMap → KLTT v2 distribution → item.area fallback. Test trên 1 dự án office cấp 4 V2: grand total = sum(qty × don_gia) chính xác 100% (số 9 con số, khớp source-of-truth).
V8-06 E2E golden test — tests/e2e_golden_sing_viet_v2.js 6 check: validator PASS / migrate 0 unmapped / KLTT v2 schema / cost_by_area total / item code / item area. Result: 6/6 PASS.
Block D done. ~3 giờ thực.
Quay lại Block C — V7 + V8
Eval harness. compare_extraction.py so sánh pipeline output 02_b_extraction.json với ground_truth.json. Metrics: items_match_pct (jaccard label match) + dim_drift_pct (D/R/H drift trung bình) + total_area_drift_pct. Pass criteria: ≥ 90% match, ≤ 10% dim drift, ≤ 25% area drift.
3 fixture: sing_viet_v2/ground_truth.json (extract từ data thật làm golden), estella/ground_truth.json (placeholder chờ tôi share data), fnb_office/ground_truth.json (placeholder chờ tôi pick 2 dự án).
V8 E2E dry-run. Vì 2 step Claude vision (V3+V4) chưa live test (cần file 3D PDF cụ thể), tôi build run_e2e_dryrun.py chạy:
- V1 render → 9 pages PNG
- V6+prepare_vision → bucket 3D vs 2D + downsample
- Stub V3+V4 (skip Claude vision call) → ghi placeholder JSON với
_dryrun: true - Stub V8 extraction từ
boq_data.jsonareas (dogfood golden case) - V7 compare_extraction so với
ground_truth.json
Kết quả: PASS items 100%, dim/area drift dưới ngưỡng. Pipeline structure validated end-to-end.
Bug đã gặp giữa cuộc
3 bug nhỏ trên đường:
1. link_boq_to_kltt.js đọc range A1:B100 nhưng section V của BOQ ở R129. Sub-totals + grand totals trả null → formula sai. Fix: bump A1:B200. Nhỏ nhưng cần verify production sheet sau cascade run.
2. Sheet ID stale trong sheets_pushed.json. Output cũ ghi 15sGbkc..., sheet thực tế là 1Eh2bQCG.... Lỗi vì script trước đó tạo sheet mới mid-session nhưng quên update. Fix: query Drive folder list mới nhất → match name → cập nhật JSON.
3. Suýt commit 66MB binary inputs. Khi git add workspace/projects/<project_slug>/, nó add cả inputs/ (DWG, PDF, JPG, XLS) + downloads/. Reset ngay + thêm .gitignore cho project workspace để future-proof.
Status report cuối ngày
| Block | Items | Plan | Actual | Velocity |
|---|---|---|---|---|
| A R1-R6 | 6 | 202h | 13h | 16× |
| B B6.1-B6.4 | 4 | n/a | 3h | – |
| D BOQ-V8 | 6 | 52h | 3h | 17× |
| C Vision V1-V10 | 10 | 27h | 3h | 9× |
5/5 critical acceptance box checked ✓:
- R1-R6 done | Block B done | Block D done | Block C done | C6.1 E2E PASS
3 box defer Sprint 7 (supplementary, không blocking ship): bilingual EN-VN canonical, M2 LIVE eval, workshop QDC verify.
Tag local sprint-6-done-all apply. Chưa push origin.
Lessons rút
1. Dogfood là cách verify duy nhất tin được. V8-04 KLTT migrator chạy validate-only trước → 17 unmapped sections. Lúc đầu nghĩ “regex detect area kém”. Nhưng khi thêm --boq fallback (lấy area từ item nếu section text không match) → 0 unmapped. Pattern này không thấy nếu chỉ test với fixture giả.
2. Velocity 11× không phải vì AI gõ nhanh. Velocity cao nhờ:
- Foundation hardened qua 5 sprint trước (skill catalog, ADR, schema chuẩn, vault encrypted)
- Mỗi ticket mới chỉ thêm 1 lớp lên stack có sẵn
- Theme “hardening sprint dựa trên retrospect dự án thật” → context dày, decision clear
3. Promote ticket cùng theme = lợi hơn tách sprint. Block D V8 epic ban đầu plan Sprint 7. Promote vào Sprint 6 EXTENDED giảm context switch. Cùng codebase, cùng pattern, không cần re-onboard.
4. Save thấy cứng — tag local trước, defer push. Tag sprint-6-done-all apply local-only. Push origin cần explicit confirm. Tag local an toàn (rollback dễ), tag remote là commitment public.
Tiếp theo
Sprint 7 (Phase 1.4b) chưa start. Theo phases.md:
- 🔴 P0 Finance daemon (invoice + cashflow tracking)
- 🔴 P0 NFR-BCP-01 Business Continuity Plan
- 🟡 P1 Compliance VN templates review
- 🟡 P1 Lead capture + Gmail classify
- 🟡 P1 Project Mgmt lite
- 🟢 P2 Goose fallback runtime
Nếu giữ velocity 10×, Sprint 7 ~80h plan / ~7-10h actual. Có thể tuần này khởi động.
Trước khi đi: nhìn lại 12 ngày từ kickoff JARVIS v2 (2026-04-23) — 233 commit, 21 skill production, 32 ADR ACCEPTED, 5 phase done (1.1, 1.2, 1.3, 1.3.5, 1.4a). Pattern lặp lại: hardening sprint dài, discovery sprint ngắn nhưng dày context, retrospect sprint cao velocity nhất.
Đêm nay cảm giác hơi giống Sprint 5 close hôm 27/04 — đi từ “check status” sang “đóng cả sprint” trong 1 ngồi. Khác là Sprint 6 có thêm 30/04 detour (blog launch, Master Sheet pivot) nên kéo dài 5 calendar days.
Mai có thể nghỉ. Hoặc start Sprint 7 với Finance daemon. Tùy mood.
FAQ
Velocity 11× sustained có thật không hay chỉ một burst?
Sprint 6 EXTENDED của tôi: ~242h plan / ~22h actual / 5 calendar days. Block D BOQ-V8 epic riêng đạt 17× (52h plan / 3h actual). Sprint 5 trước đó cũng 5×. Burst nhất là Block D vì theme 'hardening sprint dựa trên retrospect dự án thật' — context dày, skill mature, ticket clear.
Tại sao promote V8 epic từ Sprint 7 lên Sprint 6 EXTENDED?
Cùng theme 'BOQ Pipeline đỉnh nóc' với Sprint 6. Velocity Sprint 6 Day 1 đã đo được 12-13× — V8 ~52h plan tính ra ~5h actual fits comfortably. Tách 2 sprint sẽ tạo context switch không cần thiết.
Tại sao build pre-flight validator thay vì fix từng bug khi gặp?
Dự án trước đó (1 dự án office cấp 4 V2) tốn ~30 sessions iteration vì 7 pain points lặp lại: VT+NC+TB ≠ đơn giá, KL_kltt ≠ qty, note bắt đầu bằng `=` thành #ERROR! trên Sheet, area field thiếu, confidence avg < 65... Fix từng bug = ăn lại pattern lần sau. Validator 4 levels (ERROR/WARN/INFO/OK) viết 1 lần, dùng cho mọi BOQ tương lai.
Vision pipeline 4-layer chạy thật chưa hay mới wired?
Deterministic steps (V1 render PNG, V6 downsample) đã chạy live trên data thật — 9 page rendered, downsample ≤2MB/page, bucket 3D vs 2D đúng. 2 step Claude vision (V3 3D context, V4 2D extraction) đã wired trong orchestrator nhưng chưa live test (cần file 3D PDF cụ thể). E2E dry-run với stub vision PASS — pipeline structure validated.