Laporan — Perbaikan Klasifikasi Paket Berakhirnya Status Badan Hukum PT (Hybrid BSBHP)
Tanggal: 2026-07-16 · Branch:
fix/berakhirnya-status-badan-hukum(di origin, push biasa)
Arah: HYBRID — formulir template BSBHP-03..06 jadi jalur utama untuk dokumen yang
dibuat pemohon; classifier tetap sebagai fallback format-bebas dengan scope dipangkas.
Commit sesi ini (di atas41eab6d4):6c00e7d2(axis literal-pasal) →9a986f89
(FASE 1 template BSBHP) →e0f0271f(FASE 2 fallback re-scope).
Ringkasan hasil
| Jalur | Hasil e2e (UI nyata, saya jalankan sendiri) |
|---|---|
| Formulir BSBHP (jalur utama) | 6/6 AUTO-mendarat pada transaksi sintetis (4 formulir terisi + akta + BA RUPS). Roundtrip generator→OCR→kenali→adopsi terbukti 4/4. |
| Sample-1 (MAJA JAYA) | 6/6 benar (5 di UI + 1 diverifikasi via API — lihat limitation OCR #1) |
| Sample-2 (KAYU ARUM) | 5/6 (1 koran _152 → tie axis undefined, operator menetapkan) |
| Sample-3 (PORTAL BURSA) | 4/6 (2 mentok GPU/akta-path — bukan bug logic) |
| Sample-4 (BUKIT LENTERA, dwifungsi) | 5/5 benar (BAR diterima sebagai laporan; slot BA RUPS terpenuhi dwifungsi) |
| Sample-5 (BOGA) | 6/6 benar |
| Path "Tambah Dokumen" | koran ditambah pasca-board → chip BUKTI_PENGUMUMAN_149 benar ✅ |
Semua diverifikasi terhadap SAMPLES.md. Kriteria "benar" = file mendarat di lane yang benar
ATAU ber-chip saran yang benar (sesuai DoD). Angka apa adanya — tidak ada klaim "auto" untuk
yang tidak saya lihat sendiri mendarat.
FASE 1 — Jalur template BSBHP (jalur utama)
Yang dibangun:
- backend/templates/bsbhp-0{3,4,5,6}-*.docx (dibuat oleh scripts/build-bsbhp-templates.ts):
BSBHP-03 Surat Permohonan · BSBHP-04 Laporan Akhir Likuidasi · BSBHP-05/06 lembar sampul
Bukti Pengumuman Ps.149/152. Baris judul konstan FORMULIR SABH BSBHP-0N — … + footer kode.
- matchBsbhpFormCode() + rule paling atas di suggestByKeyword: judul → lane langsung,
confidence 0.98, autoAcceptable: true. Prefix "FORMULIR SABH BSBHP" hanya ada di judul, jadi
daftar lampiran BSBHP-03 (yang menyebut BSBHP-04/05/06) tidak salah-cocok; footer = fallback OCR.
- refineSupportingLabel: formulir yang GPU-nya salah-yakin BERITA_ACARA_RUPS (baseline: BSBHP-04/06
di-skor BA @0.99) di-override ke lane sendiri — memakai OCR cabang itu (tanpa OCR tambahan; BA RUPS
asli tak pernah memuat kode BSBHP → flow lain aman).
- bsbhp-form-generator.ts + routes/bsbhp-form.ts (GET blank / POST terisi → PDF), meniru
sp-pendirian-pp-generator (docxtemplater + libreoffice). Stateless (belum ada model v1).
- FE: tombol "Unduh template" di lane kosong kelengkapan-checklist — hanya untuk flow berakhirnya.
Bukti roundtrip (src/scripts/bsbhp-roundtrip-diag.ts, generate→PaddleOCR→kenali→adopsi):
| Formulir | Dikenali | GPU coarse | Board mendarat |
|---|---|---|---|
| BSBHP-03 | SURAT_PERMOHONAN | BERITA_ACARA_RUPS@~0.05–0.14 | SURAT_PERMOHONAN ✅ |
| BSBHP-04 | LAPORAN_LIKUIDASI | BERITA_ACARA_RUPS@0.999 | LAPORAN_LIKUIDASI ✅ |
| BSBHP-05 | BUKTI_PENGUMUMAN_149 | OTHER / BUKTI_TRANSFER-NERACA@~0 | BUKTI_PENGUMUMAN_149 ✅ |
| BSBHP-06 | BUKTI_PENGUMUMAN_152 | BERITA_ACARA_RUPS@0.95 | BUKTI_PENGUMUMAN_152 ✅ |
e2e UI sintetis: 6/6 auto — semua 6 lane Kelengkapan hijau (screenshot bsbhp-synthetic.png).
Catatan: BSBHP-03/05 GPU confidence rendah → UI menandai "perlu ditinjau", tetapi rawClassification
sudah = lane yang benar dan checklist lane hijau (jadi tetap mendarat, hanya ditandai untuk review).
FASE 2 — Fallback classifier (re-scope §5)
| Tahap | Perubahan | Status |
|---|---|---|
| Tahap 1 | BUKTI_TRANSFER-SURAT_PERNYATAAN_SETOR_LEGACY (label GPU nyata varian laporan "surat pernyataan", sample-1 @0.998) masuk CONFIDENTLY_WRONG_SUPPORTING_LABELS. No-op untuk setor pendirian asli (tanpa frasa LIKUID — dibuktikan test). |
✅ |
| Tahap 3 | Axis koran: literal PASAL 149/152 menang mutlak; HASIL LIKUIDASI dibuang dari axis-152 (bentrok "sisa hasil likuidasi" khas Ps.149); RENCANA PEMBAGIAN masuk axis-149; seri → undefined (bukan default _152). |
✅ |
| Tahap 3 (chip) | Chip tidak menawarkan lane yang tak ada di label set aktif (bare BUKTI_PENGUMUMAN → Tidak Dikenali di berakhirnya). Guard di FE, digate pada label set flow → pembubaran/peleburan/penggabungan (yang punya lane bare) tak berubah. |
✅ |
| Tahap 4 | Regex permohonan: +PEMBERITAHUAN di alternation + jarak {0,30}→{0,60} → judul nyata "Permohonan Pemberitahuan Berakhirnya Status Badan Hukum" cocok. |
✅ |
| Tahap 2 (anchoring pass-2) | TIDAK dikerjakan (turun ke nice-to-have; chip koran sudah benar-arah). | — |
| Tahap 4 (scan per-halaman) | TIDAK dikerjakan (sampul BSBHP menyelesaikan kasus utamanya). | — |
Matriks classifier axis koran — sebelum vs sesudah (matriks PaddleOCR, 30 file)
Axis koran ber-anchor nama PT pemohon:
Sebelum sesi (41eab6d4) |
Sesudah | |
|---|---|---|
| 149 benar | 4/5 (1 salah-nudge ke _152) | 5/5 |
| 152 benar | 4/5 (1 salah-nudge ke _149) | 4/5 + 1 → undefined (operator menetapkan, bukan nudge salah) |
| Salah-arah (nudge ke lane keliru) | 2 | 0 |
Perbaikan inti: dua salah-nudge (MAJA "Iklan Koran II" → _152; PT BIS → _149) hilang berkat rule
literal-pasal. Satu koran (Kayu Arum "2025-11-26-4") kini undefined (seri, tanpa literal pasal) →
chip ditahan, operator menetapkan — sengaja, dan di dunia hybrid sampul BSBHP-06 adalah jalur utamanya.
FASE 3 — Hasil e2e per file (Playwright, saya jalankan)
Format: file → hasil board (raw = rawClassification, chip = suggestion). ✅ benar / ❌ mentok.
Sample-1 MAJA JAYA — 6/6 (sebelumnya di plan §0: 4 dari 6 gagal)
- AKTA_BERAKHIRNYA → raw=AKTA_BERAKHIRNYA ✅ · BERITA_ACARA_RUPS → raw=BERITA_ACARA_RUPS ✅
- SURAT_PERMOHONAN → chip SURAT_PERMOHONAN ✅ (Gap E lama) · LAPORAN_LIKUIDASI → chip LAPORAN_LIKUIDASI ✅ (Gap A lama)
- _149 (Iklan Koran II) → chip _149 ✅ (Gap C/D lama) · _152 (IKLAN KORAN III) → chip _152 ✅ (diverifikasi via API; limitation OCR #1)
Sample-2 KAYU ARUM — 5/6
- AKTA ✅ · BA RUPS ✅ · SURAT_PERMOHONAN → chip ✅ · LAPORAN → chip LAPORAN_LIKUIDASI ✅
- _149 → chip _149 ✅ · _152 (2025-11-26-4) → raw=OTHER, tanpa chip ❌ (seri axis → undefined; limitation #2)
Sample-3 PORTAL BURSA — 4/6
- AKTA ✅ · SURAT_PERMOHONAN → chip ✅ · LAPORAN (bilingual) → raw=LAPORAN_LIKUIDASI ✅ · _152 → chip _152 ✅
- BERITA_ACARA_RUPS (14 Feb "Akta PKR") → raw=AKTA_BERAKHIRNYA ❌ (dokumen memang akta PKR; jalur akta; limitation #4)
- _149 (Appendix 17) → raw=BERITA_ACARA_RUPS@0.9996 ❌ (GPU salah-yakin BA RUPS; limitation #3)
Sample-4 BUKIT LENTERA (dwifungsi) — 5/5
- AKTA ✅ · BAR (dwifungsi) → raw=LAPORAN_LIKUIDASI ✅ (memenuhi slot laporan; slot BA RUPS lewat aturan dwifungsi simetris BSBHP_REQUIRED_DOCS)
- SURAT_PERMOHONAN → chip ✅ · _149 → chip _149 ✅ · _152 → chip _152 ✅
Sample-5 BOGA — 6/6
- AKTA ✅ · BA RUPS ✅ · SURAT_PERMOHONAN → chip ✅ · LAPORAN → raw=LAPORAN_LIKUIDASI ✅ · _149 → chip _149 ✅ · _152 → chip _152 ✅
Tambah Dokumen: koran _149 ditambah pasca-board → raw=OTHER, chip BUKTI_PENGUMUMAN_149 ✅
Screenshot: .pw-scratch/{sample-1..5,bsbhp-synthetic,tambah-dokumen}.png.
FASE 4 — Audit commit (setelah 41eab6d4) + working tree
| Perubahan | Keputusan | Alasan |
|---|---|---|
6c00e7d2 axis literal-pasal |
KEEP | Inti Tahap 3; komentar tie→_152-nya di-tulis-ulang oleh e0f0271f (tie→undefined) — konsisten. |
9a986f89 jalur template BSBHP |
KEEP | Fitur utama; tergate pada kode formulir; flow lain tak tersentuh. |
e0f0271f fallback re-scope |
KEEP | Tahap 1/3/4; semua tergate berakhirnya atau suggest-only. |
| Hardcode nama PT / nomor txn / notaris di kode produksi | TIDAK ADA | Scan otomatis 8 file produksi: 0 hit logic. Satu-satunya sebutan sample ("PT BIS", "Koran II") ada di komentar WHY-baseline — sesuai konvensi codebase, bukan logic. |
| Angka ajaib | KEEP | 0.98 (conf formulir), 800/400/300 (jendela head/footer) berkomentar; radius/threshold lain warisan. |
| Dead code / kode setengah-jadi | TIDAK ADA | tsc bersih (menangkap import/lokal tak terpakai); semua fungsi baru terpakai. |
| Perubahan perilaku flow non-berakhirnya | TIDAK ADA (tak perlu revert) | BSBHP rule hanya nyala pada string "BSBHP"; axis tie→undefined + FE guard justru netral-positif bagi pembubaran/peleburan/penggabungan (test 20/0 hijau); Tahap 1 no-op untuk setor pendirian. |
Karena semua KEEP, tak ada perubahan kode cleanup → tak ada e2e yang perlu diulang.
Verifikasi akhir (DoD):
- backend bunx tsc --noEmit: bersih untuk file saya. (Ada 31 error apostille pra-ada — drift Prisma
jalurPermohonan/unregisteredAck/specimenFile, BUKAN dari sesi ini; identik di HEAD bersih.)
- backend bun test: 40 fail — semua pra-ada (cluster apostille Prisma + MinIO-off + config-env +
gateway). Nol net-new; tak ada test flow lain yang ekspektasinya diubah.
- frontend bunx tsc --noEmit: bersih. FE test board/checklist/file-card: 22/22 hijau.
Limitation OCR/GPU (didokumentasikan jujur — batas, bukan disembunyikan)
- IKLAN KORAN III (sample-1, _152) — halaman koran penuh 1.85 MB. Pada satu run e2e, OCR
pass-pertama melampaui jendela klasifikasi berurutan UI (tak ada respons). Via API langsung
(OCR hangat) mendarat benar:OTHER→ chipBUKTI_PENGUMUMAN_152. Batas latensi OCR, bukan bug logic. - Kayu Arum "2025-11-26-4" (sample-2, _152) — jendela ber-anchor seri (kreditor/tagihan vs
pemberesan) tanpa literal pasal →undefined(by design tie→undefined). Chip ditahan, operator
menetapkan. Box axis pemohon memang ambigu di teks OCR. - Appendix 17 (sample-3, _149) — GPU salah-yakin
BERITA_ACARA_RUPS@0.9996. Tidak di-re-examine
(guardrail: jangan me-rescue BA RUPS sembarang, agar BA RUPS asli flow lain aman). Batas GPU. - "14 Feb Akta PKR" (sample-3, BA RUPS) — dokumen ini memang akta PKR; jalur
refineAktaLabel
(di luar sentuhan, guardrail) mengklasifikasiAKTA_BERAKHIRNYA. GT melabeli BA RUPS (PKR bisa
berperan sebagai risalah RUPS) — ambiguitas dokumen, bukan kegagalan seam. - Box iklan grafis — sebagian box pemohon di koran adalah grafis kecil yang tak menghasilkan teks
PaddleOCR. Jawaban desain = lembar sampul BSBHP-05/06 (pasal dideklarasikan pemohon, bukan ditebak OCR).
Kesimpulan: limitation 1–5 adalah plafon jalur fallback format-bebas — persis alasan hybrid
dipilih. Jalur template BSBHP (utama) melewati semuanya: 6/6 auto untuk pengguna baru.