think
16px
820px

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 atas 41eab6d4): 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)

  1. 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 → chip BUKTI_PENGUMUMAN_152. Batas latensi OCR, bukan bug logic.
  2. 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.
  3. 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.
  4. "14 Feb Akta PKR" (sample-3, BA RUPS) — dokumen ini memang akta PKR; jalur refineAktaLabel
    (di luar sentuhan, guardrail) mengklasifikasi AKTA_BERAKHIRNYA. GT melabeli BA RUPS (PKR bisa
    berperan sebagai risalah RUPS) — ambiguitas dokumen, bukan kegagalan seam.
  5. 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.