think
16px
820px

Gap Analysis — PLAN-fix-berakhirnya-status-pt.md vs. actual base branch

Produced: 2026-07-15 · By: implementation agent, before touching any code.
Branch: fix/berakhirnya-status-badan-hukum (sits exactly at base tip fa5f3bb9 — no commits yet).
Base: refactor/tidyup-foundation.
Verdict: the plan is stale. The berakhirnya flow is already built AND launched on the
base branch. Only the plan's 2026‑07‑15 sample‑inspection refinements remain. No code was
changed
— this document is the hand‑back for revising the plan.


TL;DR

The plan's premise — "Fitur berakhirnya status PT belum dibangun" — no longer holds. The feature
was ported and shipped in:

  • 89415f52feat(pt): port PEMBUBARAN_PT + BERAKHIRNYA_STATUS_PT from frozen feat/pt-flows-registry (D1+D2)
  • 6e66ad08feat(review): smoke-revision batch 3 — berakhirnya fixes …

The launch switch the plan reserves for its final commit is already flipped
(akta-txn-classifier.ts:44"berakhirnya", // LAUNCH SWITCH — BERAKHIRNYA_STATUS_PT shipped (D2 port)),
inferSubmissionType already routes BERAKHIRNYA_PACKAGE → BERAKHIRNYA_STATUS_PT, and there are 5
berakhirnya test files already in flow-engine/__tests__/.

flowchart LR subgraph SHIPPED["✅ Already shipped on base branch"] T1["Tahap 1: mapToDocumentType\nexplicit mappings + order"] T2["Tahap 2: berakhirnya rule set\n(different names than plan)"] T3["Tahap 3: enum, flow, board,\nextractors, TITLE_RULES, classifier"] LS["Launch switch\nBUILT_AKTA_TXN_TYPES += berakhirnya"] end subgraph CONFLICT["⚠️ Plan contradicts shipped code"] CL["Tahap 3.7 company lookup\nplan: allowedStatusTransaksi:[3]\ncode: status=1 + REGISTRY_STATE gate\n(2026-07-03 erratum)"] end subgraph RESIDUAL["🔨 Genuinely new — NOT in code (2026-07-15 findings)"] R1["Axis 149 +PAILIT|KURATOR|PUTUSAN|KEBERATAN|TAGIHAN"] R2["Axis 152 +HASIL AKHIR"] R3["SIRKULER → BERITA_ACARA_RUPS aliasing"] R4["Laporan variant PERNYATAAN..HASIL AKHIR..LIKUIDASI"] R5["PT-name anchoring for koran clippings (window scan)"] R6["bukti-pengumuman-extract per-pasal (still Ps.127(2)) + recoverDocNumberViaLlm wiring"] end

1. Already shipped (plan says "build", code already has it)

Plan item Status Evidence (file:line)
Tahap 1 — kill silent AKTA fallback; map SURAT_PERMOHONAN, LAPORAN_LIKUIDASI, BUKTI_PENGUMUMAN(_149/_152); getProcessingOrder non‑0 ✅ Done submission-type-inference.ts:38-70note mapToDocumentType was refactored OUT of submissions.ts; the plan's submissions.ts:34-59 refs are stale
Tahap 3.1 — enum BERAKHIRNYA_STATUS_PT ✅ Done contract/enums.gen.ts; used throughout
Tahap 3.2flows/berakhirnya-status-pt.ts (requiredDocs, sections, focusedPasses, hooks) ✅ Done full 92‑line flow; multi‑role doc allowance handled via BSBHP_REQUIRED_DOCS over fine labels
Tahap 3.3 — board BERAKHIRNYA_DOC_TYPES + LABEL_MAP (koran maxCount:2) ✅ Done klasifikasi.ts:300
Tahap 3.4 — keyword axis 149/152 (base) ⚠️ Partial supporting-doc-classifier.ts:31-48 — base axes exist; expansions missing (see §3)
Tahap 3.5 — extractors surat-permohonan, laporan-likuidasi, bukti-pengumuman, akta‑pembubaran‑ref ⚠️ Partial files exist + wired in FOCUSED_PASS_HANDLERS; but bukti‑pengumuman not parametrized per pasal + recoverDocNumberViaLlm not wired (see §3)
Tahap 3.6TITLE_RULES AKTA BERAKHIRNYA; AKTA_SUBTYPE_MAP / resolveAktaSubtype ✅ Done akta-txn-classifier.ts:69; overrideByClassifiedType:{AKTA_BERAKHIRNYA:"perubahan"} in flow
Tahap 3.8 / Launch switchBUILT_AKTA_TXN_TYPES += "berakhirnya" + inferSubmissionType returns type Already flipped akta-txn-classifier.ts:44; submission-type-inference.ts:88-93

Tahap 2 (date rules) — built, but not under the plan's names

Plan rule Shipped as Notes
BSBHP_AKTA_RECENCY (akta ∈ [today−30, today]) Shared wrapped AKTA_DATE_WINDOW in BERAKHIRNYA_SHARED_RULE_CODES (rules/berakhirnya/index.ts:336) — recency IS enforced, just not as a berakhirnya‑specific rule
BSBHP_PENGUMUMAN_ORDER (149 precedes RUPS) BSBHP_PENGUMUMAN_ORDER rules/berakhirnya/index.ts:184 (WARNING, cites Ps.147(1)/152(3))
BSBHP_PENGUMUMAN_152_WINDOW (152 ∈ [RUPS, RUPS+30]) Not built only ordering + BSBHP_DOC_DATE_SANITY exist — the explicit 152 window rule is absent

The shipped rule set is richer than the plan (BSBHP_REGISTRY_STATE, BSBHP_PEMBUBARAN_PREREQ,
BSBHP_LIKUIDATOR_CONSISTENCY, BSBHP_DOC_DATE_SANITY, BSBHP_PEMBUBARAN_REF,
BSBHP_SISA_KEKAYAAN_PRESENT, BSBHP_NAMA_PT_DOCS) — so the matrix is more complete than Tahap 2
described, minus the specific 152 window.


2. Direct conflict — Tahap 3.7 company lookup (DECIDED: keep shipped code)

  • Plan (§Tahap 3.7 / spec §4.6): dissolved PT is invisible at status_transaksi=1; add
    allowedStatusTransaksi and set [3] from the berakhirnya flow.
  • Shipped code: deliberately reversed via a 2026‑07‑03 erratum
    (flows/berakhirnya-status-pt.ts:16-22,39-43) — keeps companyLookup: true (default status=1)
    because "an approved pembubaran row sits at status 1", and gates the prerequisite at
    BSBHP_REGISTRY_STATE (rules/berakhirnya/index.ts:97 → "status 1 — prasyarat berakhirnya
    terpenuhi"). The allowedStatusTransaksi seam stays intentionally unused.

Resolution (user, 2026‑07‑15): keep the shipped code. The plan's §4.6 premise is outdated;
do NOT apply allowedStatusTransaksi:[3]. The plan should delete/annotate Tahap 3.7.


3. Genuinely-new residual work (the only shippable items — 2026-07-15 sample findings)

These postdate the port and are absent from the code. If/when the plan is revised, this is the
real scope:

  1. Axis 149 keyword expansionsupporting-doc-classifier.ts:36 has only KREDITOR|PEMBUBARAN.
    Add PAILIT|KURATOR|PUTUSAN|KEBERATAN|TAGIHAN (pengakhiran pailit via putusan pengadilan).
  2. Axis 152 keyword — add HASIL AKHIR alongside HASIL LIKUIDASI|PERTANGGUNGJAWABAN (:34).
  3. SIRKULER → BERITA_ACARA_RUPS aliasingKEPUTUSAN SIRKULER|SIRKULER PARA PEMEGANG SAHAM
    + pembubaran/likuidasi context should suggest BERITA_ACARA_RUPS. Not present in the supporting
    classifier (SIRKULER only appears in an akta-txn-classifier test today).
  4. Laporan‑likuidasi variant — current regex (:40) misses PERNYATAAN .* HASIL AKHIR .* LIKUIDASI; add it (1‑page bermeterai / bilingual / "surat pernyataan dan neraca" forms).
  5. PT‑name anchoring for koran clippings — classifier scans the whole rawText; koran samples are
    full newspaper pages with many unrelated PT boxes. Anchor the semantic scan to a window around the
    applicant PT name (calibrated from a Tahap‑0 baseline of PaddleOCR fragmentation).
  6. bukti-pengumuman-extract.ts — prompt still hardcodes "Pasal 127(2)" (:31); parametrize per
    pasal (149 = pembubaran + panggilan kreditor; 152 = hasil akhir likuidasi). Wire
    recoverDocNumberViaLlm (in apostille-generic-extract.ts) for nomor_pengumuman — currently
    unwired.

Plus Tahap 0 (baseline) — analysis only, still valid and useful: run the 30 sample PDFs through
POST /classify, record label+confidence+rawText, calibrate the regex axes above. Not a code change.


Recommended plan revision (for your edit)

  • Drop: Tahap 1, Tahap 2 (except the missing BSBHP_PENGUMUMAN_152_WINDOW if wanted), all of
    Tahap 3 except 3.4/3.5 refinements, and the launch‑switch commit — all already shipped.
  • Delete: Tahap 3.7 (contradicts the erratum; decided).
  • Keep as the real scope: Tahap 0 baseline + the six residual items in §3, optionally the
    explicit 152‑window rule.
  • Re‑point stale line refs: mapToDocumentType/inferSubmissionType/getProcessingOrder now
    live in backend/src/services/submission-type-inference.ts, not routes/submissions.ts.

Awaiting your revised plan before implementing anything.