pebaryan Claude Opus 4.7 commited on
Commit
3a01e32
·
1 Parent(s): e1893c1

Expand canonical probes to remaining 10 sectors + fix surat strict toggle

Browse files

Round-trips the 10 new fixtures' citation gap analysis from this session
into 22 new canonical probes covering all DPR Komisi domains we hadn't
yet covered.

Probes added (all verified 'berlaku' on pasal.id pre-commit):

Hukum / KPK kelembagaan (Komisi III):
UU 8/1981 (KUHAP), UU 30/2002 (KPK), UU 19/2019 (KPK perubahan)

Sosial / Bencana / Anak (Komisi VIII):
UU 24/2007 (Penanggulangan Bencana)
UU 35/2014 (Perlindungan Anak)
UU 23/2004 (PKDRT)
UU 11/2009 (Kesejahteraan Sosial)

Diplomasi (Komisi I):
UU 37/1999 (Hubungan Luar Negeri)
UU 24/2000 (Perjanjian Internasional)

Pertanian / Pangan (Komisi IV):
UU 41/2009 (Perlindungan LP2B)

BUMN / Perdagangan / Standardisasi (Komisi VI):
UU 19/2003 (BUMN), UU 7/2014 (Perdagangan), UU 20/2014 (Standardisasi)

UMKM (Komisi VII):
UU 20/2008 (UMKM)

Keuangan (Komisi XI):
UU 4/2023 (P2SK), UU 21/2011 (OJK), UU 7/2021 (HPP)

Energi / Lingkungan / Tambang (Komisi XII):
UU 30/2007 (Energi — keys include 'transisi energi'),
UU 32/2009 (PPLH), UU 3/2020 (Minerba)

HAM / Imigrasi (Komisi XIII):
UU 39/1999 (HAM), UU 6/2011 (Keimigrasian)

UU 5/1960 (UUPA) was probed but consistently times out from pasal.id
(unusually large document); deliberately omitted to keep agraria probe
firing fast. Agraria topics will discover via search instead.

Total canonical probes: 23 → 45.
Regression baseline refreshed: 45 probes, 58 fixture refs, 16 fixtures.

Bug fix in agents/surat.py:

reply() always raised ValueError on unverifiable citations regardless
of pool.settings.strict_citations. That's inconsistent with penyusun
and analis_ruu, which both honour the toggle. Fixed by checking
strict_citations before raising; warns instead when disabled. Useful
when pasal.id is rate-limited or returning transport errors and the
user wants the draft to ship anyway.

8 new probe-coverage tests + 1 strict-toggle regression test (68 total).

Live validation on two new-domain fixtures:
- Komisi I (diplomasi WNI Gaza): reply correctly self-identifies as
'membidangi Hubungan Luar Negeri di Komisi I'; mentions Kemenlu,
Kemhan, Basarnas, perwakilan RI as relevant instansi.
- Komisi XIII (imigrasi/HAM/pengungsi): reply correctly addresses
'Komisi XIII DPR RI'; cites UU Keimigrasian + UU HAM; correctly
routes to Kemenkumham.

Both runs in LEGAWA_STRICT_CITATIONS=0 mode because pasal.id was
timing out — see surat strict-toggle bug fix above.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

scripts/regression_baseline.json CHANGED
@@ -96,6 +96,16 @@
96
  "title": "Undang-Undang Nomor 34 Tahun 1964 tentang Dana Pertanggungan Wajib Kecelakaan Lalu-lintas Jalan",
97
  "uri": "akn/id/act/uu/1964/34"
98
  },
 
 
 
 
 
 
 
 
 
 
99
  "akn/id/act/uu/1999/31": {
100
  "amended_by": [
101
  {
@@ -115,6 +125,20 @@
115
  "title": "Undang-Undang Nomor 31 Tahun 1999 tentang Undang-Undang Nomor 31 Tahun 1999",
116
  "uri": "akn/id/act/uu/1999/31"
117
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  "akn/id/act/uu/1999/8": {
119
  "amended_by": [],
120
  "repealed_by": null,
@@ -122,6 +146,13 @@
122
  "title": "Undang-Undang Nomor 8 Tahun 1999 tentang PERLINDUNGAN KONSUMEN",
123
  "uri": "akn/id/act/uu/1999/8"
124
  },
 
 
 
 
 
 
 
125
  "akn/id/act/uu/2001/20": {
126
  "amended_by": [
127
  {
@@ -137,6 +168,26 @@
137
  "title": "Undang-Undang Nomor 20 Tahun 2001 tentang Perubahan Uu 31-1999 Tentang Pemberantasan Tindak Pidana Korupsi",
138
  "uri": "akn/id/act/uu/2001/20"
139
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  "akn/id/act/uu/2003/13": {
141
  "amended_by": [
142
  {
@@ -157,6 +208,41 @@
157
  "title": "Undang-Undang Nomor 13 Tahun 2003 tentang KETENAGAKERJAAN",
158
  "uri": "akn/id/act/uu/2003/13"
159
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  "akn/id/act/uu/2005/14": {
161
  "amended_by": [],
162
  "repealed_by": null,
@@ -184,6 +270,55 @@
184
  "title": "Undang-Undang Nomor 23 Tahun 2007 tentang Undang-Undang Nomor 23 Tahun 2007",
185
  "uri": "akn/id/act/uu/2007/23"
186
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  "akn/id/act/uu/2009/22": {
188
  "amended_by": [
189
  {
@@ -204,6 +339,85 @@
204
  "title": "Undang-Undang Nomor 22 Tahun 2009 tentang Undang-Undang Nomor 22 Tahun 2009",
205
  "uri": "akn/id/act/uu/2009/22"
206
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  "akn/id/act/uu/2012/12": {
208
  "amended_by": [],
209
  "repealed_by": null,
@@ -244,6 +458,78 @@
244
  "title": "Undang-Undang Nomor 20 Tahun 2013 tentang Pendidikan Kodekteran",
245
  "uri": "akn/id/act/uu/2013/20"
246
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  "akn/id/act/uu/2023/17": {
248
  "amended_by": [],
249
  "repealed_by": null,
@@ -251,6 +537,13 @@
251
  "title": "Undang-Undang Nomor 17 Tahun 2023 tentang Kesehatan",
252
  "uri": "akn/id/act/uu/2023/17"
253
  },
 
 
 
 
 
 
 
254
  "akn/id/act/uu/2023/6": {
255
  "amended_by": [
256
  {
@@ -281,6 +574,9 @@
281
  }
282
  },
283
  "fixture_citations": {
 
 
 
284
  "surat-bekasi-kereta-taksi.txt": [
285
  "UU 22/2009",
286
  "Permen 22/2009",
@@ -289,6 +585,18 @@
289
  "UU 33/1964",
290
  "UU 34/1964"
291
  ],
 
 
 
 
 
 
 
 
 
 
 
 
292
  "surat-buruh-outsourcing.txt": [
293
  "UU 13/2003",
294
  "UU 6/2023",
@@ -298,6 +606,11 @@
298
  "Perpres 16/2018",
299
  "Perpres 12/2021"
300
  ],
 
 
 
 
 
301
  "surat-gaji-tunjangan-dosen.txt": [
302
  "Permen 52/2025",
303
  "Perpres 19/2025",
@@ -305,6 +618,14 @@
305
  "PP 37/2009",
306
  "PP 41/2009"
307
  ],
 
 
 
 
 
 
 
 
308
  "surat-mbg-keracunan-grobogan.txt": [
309
  "Perpres 83/2024",
310
  "Perpres 115/2025",
@@ -314,13 +635,48 @@
314
  "Perpres 12/2021",
315
  "UU 8/1999"
316
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  "surat-ppds-internsip-dokter.txt": [
318
  "UU 17/2023",
319
  "PP 28/2024",
320
  "Permenkes 7/2022",
321
  "Permen 7/2022",
322
  "UU 20/2013"
 
 
 
 
 
 
 
 
 
323
  ]
324
  },
325
- "schema_version": 1
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  }
 
96
  "title": "Undang-Undang Nomor 34 Tahun 1964 tentang Dana Pertanggungan Wajib Kecelakaan Lalu-lintas Jalan",
97
  "uri": "akn/id/act/uu/1964/34"
98
  },
99
+ "akn/id/act/uu/1981/8": {
100
+ "amended_by": [],
101
+ "repealed_by": {
102
+ "frbr_uri": "/akn/id/act/uu/2025/20",
103
+ "title": "Undang-Undang Nomor 20 Tahun 2025 tentang Kitab Undang-Undang Hukum Acara Pidana"
104
+ },
105
+ "status": "berlaku",
106
+ "title": "Undang-Undang Nomor 8 Tahun 1981 tentang Hukum Acara Pidana",
107
+ "uri": "akn/id/act/uu/1981/8"
108
+ },
109
  "akn/id/act/uu/1999/31": {
110
  "amended_by": [
111
  {
 
125
  "title": "Undang-Undang Nomor 31 Tahun 1999 tentang Undang-Undang Nomor 31 Tahun 1999",
126
  "uri": "akn/id/act/uu/1999/31"
127
  },
128
+ "akn/id/act/uu/1999/37": {
129
+ "amended_by": [],
130
+ "repealed_by": null,
131
+ "status": "berlaku",
132
+ "title": "Undang-Undang Nomor 37 Tahun 1999 tentang Hubungan Luar Negeri",
133
+ "uri": "akn/id/act/uu/1999/37"
134
+ },
135
+ "akn/id/act/uu/1999/39": {
136
+ "amended_by": [],
137
+ "repealed_by": null,
138
+ "status": "berlaku",
139
+ "title": "Undang-Undang Nomor 39 Tahun 1999 tentang Hak Asasi Manusia",
140
+ "uri": "akn/id/act/uu/1999/39"
141
+ },
142
  "akn/id/act/uu/1999/8": {
143
  "amended_by": [],
144
  "repealed_by": null,
 
146
  "title": "Undang-Undang Nomor 8 Tahun 1999 tentang PERLINDUNGAN KONSUMEN",
147
  "uri": "akn/id/act/uu/1999/8"
148
  },
149
+ "akn/id/act/uu/2000/24": {
150
+ "amended_by": [],
151
+ "repealed_by": null,
152
+ "status": "berlaku",
153
+ "title": "Undang-Undang Nomor 24 Tahun 2000 tentang Perjanjian Internasional",
154
+ "uri": "akn/id/act/uu/2000/24"
155
+ },
156
  "akn/id/act/uu/2001/20": {
157
  "amended_by": [
158
  {
 
168
  "title": "Undang-Undang Nomor 20 Tahun 2001 tentang Perubahan Uu 31-1999 Tentang Pemberantasan Tindak Pidana Korupsi",
169
  "uri": "akn/id/act/uu/2001/20"
170
  },
171
+ "akn/id/act/uu/2002/30": {
172
+ "amended_by": [
173
+ {
174
+ "frbr_uri": "/akn/id/act/uu/2015/10",
175
+ "title": "Undang-Undang Nomor 10 Tahun 2015 tentang Penetapan Peraturan Pemerintah Pengganti Undang-Undang Nomor 1 Tahun 2015 Tent"
176
+ },
177
+ {
178
+ "frbr_uri": "/akn/id/act/uu/2019/19",
179
+ "title": "Undang-Undang Nomor 19 Tahun 2019 tentang Perubahan Kedua atas Undang-Undang Nomor 30 Tahun 2002 tentang Komisi Pemberan"
180
+ },
181
+ {
182
+ "frbr_uri": "/akn/id/act/perppu/2015/1",
183
+ "title": "Peraturan Pemerintah Pengganti Undang-Undang Nomor 1 Tahun 2015 tentang Perubahan Atas Undang-undang Nomor 30 Tahun 2002"
184
+ }
185
+ ],
186
+ "repealed_by": null,
187
+ "status": "berlaku",
188
+ "title": "Undang-Undang Nomor 30 Tahun 2002 tentang Komisi Pemberantasan Tindak Pidana Korupsi",
189
+ "uri": "akn/id/act/uu/2002/30"
190
+ },
191
  "akn/id/act/uu/2003/13": {
192
  "amended_by": [
193
  {
 
208
  "title": "Undang-Undang Nomor 13 Tahun 2003 tentang KETENAGAKERJAAN",
209
  "uri": "akn/id/act/uu/2003/13"
210
  },
211
+ "akn/id/act/uu/2003/19": {
212
+ "amended_by": [
213
+ {
214
+ "frbr_uri": "/akn/id/act/uu/2025/1",
215
+ "title": "Undang-Undang Nomor 1 Tahun 2025 tentang Perubahan Ketiga Atas Undang-undang Nomor 19 Tahun 2003 Tentang Badan Usaha Mil"
216
+ },
217
+ {
218
+ "frbr_uri": "/akn/id/act/uu/2025/16",
219
+ "title": "Undang-Undang Nomor 16 Tahun 2025 tentang Perubahan Keempat atas Undang-Undang Nomor 19 Tahun 2003 tentang Badan Usaha M"
220
+ },
221
+ {
222
+ "frbr_uri": "/akn/id/act/perpu/2022/2",
223
+ "title": "Peraturan Pemerintah Pengganti Undang-Undang Nomor 2 Tahun 2022 tentang Cipta Kerja"
224
+ },
225
+ {
226
+ "frbr_uri": "/akn/id/act/uu/2023/6",
227
+ "title": "Undang-Undang Nomor 6 Tahun 2023 tentang PENETAPAN PERATURAN PEMERINTAH PENGGANTI UNDANG-UNDANG NOMOR 2 TAHUN 2022 TENTA"
228
+ },
229
+ {
230
+ "frbr_uri": "/akn/id/act/uu/2020/11",
231
+ "title": "Undang-Undang Nomor 11 Tahun 2020 tentang CIPTA KERJA"
232
+ }
233
+ ],
234
+ "repealed_by": null,
235
+ "status": "berlaku",
236
+ "title": "Undang-Undang Nomor 19 Tahun 2003 tentang Badan Usaha Milik Negara",
237
+ "uri": "akn/id/act/uu/2003/19"
238
+ },
239
+ "akn/id/act/uu/2004/23": {
240
+ "amended_by": [],
241
+ "repealed_by": null,
242
+ "status": "berlaku",
243
+ "title": "Undang-Undang Nomor 23 Tahun 2004 tentang Penghapusan Kekerasan dalam Rumah Tangga",
244
+ "uri": "akn/id/act/uu/2004/23"
245
+ },
246
  "akn/id/act/uu/2005/14": {
247
  "amended_by": [],
248
  "repealed_by": null,
 
270
  "title": "Undang-Undang Nomor 23 Tahun 2007 tentang Undang-Undang Nomor 23 Tahun 2007",
271
  "uri": "akn/id/act/uu/2007/23"
272
  },
273
+ "akn/id/act/uu/2007/24": {
274
+ "amended_by": [],
275
+ "repealed_by": null,
276
+ "status": "berlaku",
277
+ "title": "Undang-Undang Nomor 24 Tahun 2007 tentang Penanggulangan Bencana",
278
+ "uri": "akn/id/act/uu/2007/24"
279
+ },
280
+ "akn/id/act/uu/2007/30": {
281
+ "amended_by": [],
282
+ "repealed_by": null,
283
+ "status": "berlaku",
284
+ "title": "Undang-Undang Nomor 30 Tahun 2007 tentang Energi",
285
+ "uri": "akn/id/act/uu/2007/30"
286
+ },
287
+ "akn/id/act/uu/2008/20": {
288
+ "amended_by": [
289
+ {
290
+ "frbr_uri": "/akn/id/act/perpu/2022/2",
291
+ "title": "Peraturan Pemerintah Pengganti Undang-Undang Nomor 2 Tahun 2022 tentang Cipta Kerja"
292
+ },
293
+ {
294
+ "frbr_uri": "/akn/id/act/uu/2023/6",
295
+ "title": "Undang-Undang Nomor 6 Tahun 2023 tentang PENETAPAN PERATURAN PEMERINTAH PENGGANTI UNDANG-UNDANG NOMOR 2 TAHUN 2022 TENTA"
296
+ },
297
+ {
298
+ "frbr_uri": "/akn/id/act/uu/2020/11",
299
+ "title": "Undang-Undang Nomor 11 Tahun 2020 tentang CIPTA KERJA"
300
+ }
301
+ ],
302
+ "repealed_by": null,
303
+ "status": "berlaku",
304
+ "title": "Undang-Undang Nomor 20 Tahun 2008 tentang Undang-Undang Nomor 20 Tahun 2008",
305
+ "uri": "akn/id/act/uu/2008/20"
306
+ },
307
+ "akn/id/act/uu/2009/11": {
308
+ "amended_by": [
309
+ {
310
+ "frbr_uri": "/akn/id/act/uu/2019/14",
311
+ "title": "Undang-Undang Nomor 14 Tahun 2019 tentang Pekerja Sosial"
312
+ }
313
+ ],
314
+ "repealed_by": {
315
+ "frbr_uri": "/akn/id/act/uu/2019/14",
316
+ "title": "Undang-Undang Nomor 14 Tahun 2019 tentang Pekerja Sosial"
317
+ },
318
+ "status": "berlaku",
319
+ "title": "Undang-Undang Nomor 11 Tahun 2009 tentang Undang-Undang Nomor 11 Tahun 2009",
320
+ "uri": "akn/id/act/uu/2009/11"
321
+ },
322
  "akn/id/act/uu/2009/22": {
323
  "amended_by": [
324
  {
 
339
  "title": "Undang-Undang Nomor 22 Tahun 2009 tentang Undang-Undang Nomor 22 Tahun 2009",
340
  "uri": "akn/id/act/uu/2009/22"
341
  },
342
+ "akn/id/act/uu/2009/32": {
343
+ "amended_by": [
344
+ {
345
+ "frbr_uri": "/akn/id/act/perpu/2022/2",
346
+ "title": "Peraturan Pemerintah Pengganti Undang-Undang Nomor 2 Tahun 2022 tentang Cipta Kerja"
347
+ },
348
+ {
349
+ "frbr_uri": "/akn/id/act/uu/2023/6",
350
+ "title": "Undang-Undang Nomor 6 Tahun 2023 tentang PENETAPAN PERATURAN PEMERINTAH PENGGANTI UNDANG-UNDANG NOMOR 2 TAHUN 2022 TENTA"
351
+ },
352
+ {
353
+ "frbr_uri": "/akn/id/act/uu/2020/11",
354
+ "title": "Undang-Undang Nomor 11 Tahun 2020 tentang CIPTA KERJA"
355
+ }
356
+ ],
357
+ "repealed_by": null,
358
+ "status": "berlaku",
359
+ "title": "Undang-Undang Nomor 32 Tahun 2009 tentang Undang-Undang Nomor 32 Tahun 2009",
360
+ "uri": "akn/id/act/uu/2009/32"
361
+ },
362
+ "akn/id/act/uu/2009/41": {
363
+ "amended_by": [
364
+ {
365
+ "frbr_uri": "/akn/id/act/perpu/2022/2",
366
+ "title": "Peraturan Pemerintah Pengganti Undang-Undang Nomor 2 Tahun 2022 tentang Cipta Kerja"
367
+ },
368
+ {
369
+ "frbr_uri": "/akn/id/act/uu/2023/6",
370
+ "title": "Undang-Undang Nomor 6 Tahun 2023 tentang PENETAPAN PERATURAN PEMERINTAH PENGGANTI UNDANG-UNDANG NOMOR 2 TAHUN 2022 TENTA"
371
+ },
372
+ {
373
+ "frbr_uri": "/akn/id/act/uu/2020/11",
374
+ "title": "Undang-Undang Nomor 11 Tahun 2020 tentang CIPTA KERJA"
375
+ }
376
+ ],
377
+ "repealed_by": null,
378
+ "status": "berlaku",
379
+ "title": "Undang-Undang Nomor 41 Tahun 2009 tentang Perlindungan Lahan Pertanian Pangan Berkelanjutan",
380
+ "uri": "akn/id/act/uu/2009/41"
381
+ },
382
+ "akn/id/act/uu/2011/21": {
383
+ "amended_by": [
384
+ {
385
+ "frbr_uri": "/akn/id/act/uu/2023/4",
386
+ "title": "Undang-Undang Nomor 4 Tahun 2023 tentang Undang-Undang Nomor 4 Tahun 2023"
387
+ }
388
+ ],
389
+ "repealed_by": null,
390
+ "status": "berlaku",
391
+ "title": "Undang-Undang Nomor 21 Tahun 2011 tentang Otoritas Jasa Keuangan",
392
+ "uri": "akn/id/act/uu/2011/21"
393
+ },
394
+ "akn/id/act/uu/2011/6": {
395
+ "amended_by": [
396
+ {
397
+ "frbr_uri": "/akn/id/act/uu/2024/63",
398
+ "title": "Undang-Undang Nomor 63 Tahun 2024 tentang Perubahan Ketiga atas Undang-Undang Nomor 6 Tahun 2011 tentan Keimigrasian"
399
+ },
400
+ {
401
+ "frbr_uri": "/akn/id/act/perpu/2022/2",
402
+ "title": "Peraturan Pemerintah Pengganti Undang-Undang Nomor 2 Tahun 2022 tentang Cipta Kerja"
403
+ },
404
+ {
405
+ "frbr_uri": "/akn/id/act/uu/2023/6",
406
+ "title": "Undang-Undang Nomor 6 Tahun 2023 tentang PENETAPAN PERATURAN PEMERINTAH PENGGANTI UNDANG-UNDANG NOMOR 2 TAHUN 2022 TENTA"
407
+ },
408
+ {
409
+ "frbr_uri": "/akn/id/act/uu/2020/11",
410
+ "title": "Undang-Undang Nomor 11 Tahun 2020 tentang CIPTA KERJA"
411
+ }
412
+ ],
413
+ "repealed_by": {
414
+ "frbr_uri": "/akn/id/act/uu/2023/1",
415
+ "title": "Undang-Undang Nomor 1 Tahun 2023 tentang KITAB UNDANG-UNDANG HUKUM PIDANA"
416
+ },
417
+ "status": "berlaku",
418
+ "title": "Undang-Undang Nomor 6 Tahun 2011 tentang Undang-Undang Nomor 6 Tahun 2011",
419
+ "uri": "akn/id/act/uu/2011/6"
420
+ },
421
  "akn/id/act/uu/2012/12": {
422
  "amended_by": [],
423
  "repealed_by": null,
 
458
  "title": "Undang-Undang Nomor 20 Tahun 2013 tentang Pendidikan Kodekteran",
459
  "uri": "akn/id/act/uu/2013/20"
460
  },
461
+ "akn/id/act/uu/2014/20": {
462
+ "amended_by": [],
463
+ "repealed_by": null,
464
+ "status": "berlaku",
465
+ "title": "Undang-Undang Nomor 20 Tahun 2014 tentang Standardisasi dan Penilaian Kesesuaian",
466
+ "uri": "akn/id/act/uu/2014/20"
467
+ },
468
+ "akn/id/act/uu/2014/35": {
469
+ "amended_by": [],
470
+ "repealed_by": {
471
+ "frbr_uri": "/akn/id/act/uu/2023/1",
472
+ "title": "Undang-Undang Nomor 1 Tahun 2023 tentang KITAB UNDANG-UNDANG HUKUM PIDANA"
473
+ },
474
+ "status": "berlaku",
475
+ "title": "Undang-Undang Nomor 35 Tahun 2014 tentang Perubahan atas Undang-Undang Nomor 23 Tahun 2002 Tentang Perlindungan Anak",
476
+ "uri": "akn/id/act/uu/2014/35"
477
+ },
478
+ "akn/id/act/uu/2014/7": {
479
+ "amended_by": [
480
+ {
481
+ "frbr_uri": "/akn/id/act/perpu/2022/2",
482
+ "title": "Peraturan Pemerintah Pengganti Undang-Undang Nomor 2 Tahun 2022 tentang Cipta Kerja"
483
+ },
484
+ {
485
+ "frbr_uri": "/akn/id/act/uu/2023/6",
486
+ "title": "Undang-Undang Nomor 6 Tahun 2023 tentang PENETAPAN PERATURAN PEMERINTAH PENGGANTI UNDANG-UNDANG NOMOR 2 TAHUN 2022 TENTA"
487
+ },
488
+ {
489
+ "frbr_uri": "/akn/id/act/uu/2020/11",
490
+ "title": "Undang-Undang Nomor 11 Tahun 2020 tentang CIPTA KERJA"
491
+ }
492
+ ],
493
+ "repealed_by": null,
494
+ "status": "berlaku",
495
+ "title": "Undang-Undang Nomor 7 Tahun 2014 tentang Undang-Undang Nomor 7 Tahun 2014",
496
+ "uri": "akn/id/act/uu/2014/7"
497
+ },
498
+ "akn/id/act/uu/2019/19": {
499
+ "amended_by": [],
500
+ "repealed_by": null,
501
+ "status": "berlaku",
502
+ "title": "Undang-Undang Nomor 19 Tahun 2019 tentang Perubahan Kedua atas Undang-Undang Nomor 30 Tahun 2002 tentang Komisi Pemberan",
503
+ "uri": "akn/id/act/uu/2019/19"
504
+ },
505
+ "akn/id/act/uu/2020/3": {
506
+ "amended_by": [
507
+ {
508
+ "frbr_uri": "/akn/id/act/uu/2025/2",
509
+ "title": "Undang-Undang Nomor 2 Tahun 2025 tentang Perubahan Keempat atas Undang-Undang Nomor 4 Tahun 2009 tentang Pertambangan Mi"
510
+ },
511
+ {
512
+ "frbr_uri": "/akn/id/act/uu/2023/6",
513
+ "title": "Undang-Undang Nomor 6 Tahun 2023 tentang PENETAPAN PERATURAN PEMERINTAH PENGGANTI UNDANG-UNDANG NOMOR 2 TAHUN 2022 TENTA"
514
+ }
515
+ ],
516
+ "repealed_by": null,
517
+ "status": "berlaku",
518
+ "title": "Undang-Undang Nomor 3 Tahun 2020 tentang Perubahan Atas Undang-undang Nomor 4 Tahun 2009 Tentang Pertambangan Mineral da",
519
+ "uri": "akn/id/act/uu/2020/3"
520
+ },
521
+ "akn/id/act/uu/2021/7": {
522
+ "amended_by": [
523
+ {
524
+ "frbr_uri": "/akn/id/act/uu/2023/6",
525
+ "title": "Undang-Undang Nomor 6 Tahun 2023 tentang PENETAPAN PERATURAN PEMERINTAH PENGGANTI UNDANG-UNDANG NOMOR 2 TAHUN 2022 TENTA"
526
+ }
527
+ ],
528
+ "repealed_by": null,
529
+ "status": "berlaku",
530
+ "title": "Undang-Undang Nomor 7 Tahun 2021 tentang Harmonisasi Peraturan Perpajakan",
531
+ "uri": "akn/id/act/uu/2021/7"
532
+ },
533
  "akn/id/act/uu/2023/17": {
534
  "amended_by": [],
535
  "repealed_by": null,
 
537
  "title": "Undang-Undang Nomor 17 Tahun 2023 tentang Kesehatan",
538
  "uri": "akn/id/act/uu/2023/17"
539
  },
540
+ "akn/id/act/uu/2023/4": {
541
+ "amended_by": [],
542
+ "repealed_by": null,
543
+ "status": "berlaku",
544
+ "title": "Undang-Undang Nomor 4 Tahun 2023 tentang Undang-Undang Nomor 4 Tahun 2023",
545
+ "uri": "akn/id/act/uu/2023/4"
546
+ },
547
  "akn/id/act/uu/2023/6": {
548
  "amended_by": [
549
  {
 
574
  }
575
  },
576
  "fixture_citations": {
577
+ "surat-agraria-reforma-tanah-adat.txt": [
578
+ "UU 5/1960"
579
+ ],
580
  "surat-bekasi-kereta-taksi.txt": [
581
  "UU 22/2009",
582
  "Permen 22/2009",
 
585
  "UU 33/1964",
586
  "UU 34/1964"
587
  ],
588
+ "surat-bencana-anak-bantuan-sosial.txt": [
589
+ "UU 24/2007",
590
+ "UU 11/2009",
591
+ "UU 35/2014",
592
+ "UU 23/2004"
593
+ ],
594
+ "surat-bumn-konsumen-standardisasi.txt": [
595
+ "UU 8/1999",
596
+ "UU 19/2003",
597
+ "UU 7/2014",
598
+ "UU 20/2014"
599
+ ],
600
  "surat-buruh-outsourcing.txt": [
601
  "UU 13/2003",
602
  "UU 6/2023",
 
606
  "Perpres 16/2018",
607
  "Perpres 12/2021"
608
  ],
609
+ "surat-diplomasi-wni-gaza.txt": [
610
+ "UUD 1945",
611
+ "UU 37/1999",
612
+ "UU 24/2000"
613
+ ],
614
  "surat-gaji-tunjangan-dosen.txt": [
615
  "Permen 52/2025",
616
  "Perpres 19/2025",
 
618
  "PP 37/2009",
619
  "PP 41/2009"
620
  ],
621
+ "surat-imigrasi-ham-pengungsi.txt": [
622
+ "UU 6/2011",
623
+ "UU 39/1999"
624
+ ],
625
+ "surat-ketahanan-pangan-irigasi-gabah.txt": [
626
+ "UU 18/2012",
627
+ "UU 41/2009"
628
+ ],
629
  "surat-mbg-keracunan-grobogan.txt": [
630
  "Perpres 83/2024",
631
  "Perpres 115/2025",
 
635
  "Perpres 12/2021",
636
  "UU 8/1999"
637
  ],
638
+ "surat-penegakan-hukum-korupsi-daerah.txt": [
639
+ "UU 8/1981",
640
+ "UU 31/1999",
641
+ "UU 20/2001",
642
+ "UU 30/2002",
643
+ "UU 19/2019"
644
+ ],
645
+ "surat-perbankan-pajak-umkm.txt": [
646
+ "UU 4/2023",
647
+ "UU 21/2011",
648
+ "UU 7/2021",
649
+ "UU 23/1999"
650
+ ],
651
  "surat-ppds-internsip-dokter.txt": [
652
  "UU 17/2023",
653
  "PP 28/2024",
654
  "Permenkes 7/2022",
655
  "Permen 7/2022",
656
  "UU 20/2013"
657
+ ],
658
+ "surat-transisi-energi-nikel-lingkungan.txt": [
659
+ "UU 30/2007",
660
+ "UU 3/2020",
661
+ "UU 32/2009"
662
+ ],
663
+ "surat-umkm-standardisasi-produk.txt": [
664
+ "UU 20/2008",
665
+ "UU 20/2014"
666
  ]
667
  },
668
+ "schema_version": 1,
669
+ "trusted_recent": {
670
+ "entries": {
671
+ "Perpres 8/2026": {
672
+ "checked_on": "2026-05-04",
673
+ "expires_on": "2026-06-30",
674
+ "frbr_uri": "akn/id/act/perpres/2026/8",
675
+ "status": "berlaku",
676
+ "title": "Peraturan Presiden Nomor 8 Tahun 2026 tentang Rencana Aksi Nasional Pencegahan dan Penanggulangan Ekstremisme Berbasis Kekerasan yang Mengarah pada Terorisme Tahun 2026-2029"
677
+ }
678
+ },
679
+ "problems": [],
680
+ "warnings": []
681
+ }
682
  }
src/legawa/agents/peneliti.py CHANGED
@@ -108,6 +108,59 @@ _CANONICAL_PROBES: list[tuple[tuple[str, ...], str]] = [
108
  "akn/id/act/uu/1964/33"), # UU Dana Pertanggungan Wajib Kecelakaan Penumpang
109
  (("kecelakaan lalu lintas", "asuransi korban kecelakaan", "jasa raharja"),
110
  "akn/id/act/uu/1964/34"), # UU Dana Pertanggungan Wajib Kecelakaan Lalu Lintas Jalan
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  ]
112
 
113
 
 
108
  "akn/id/act/uu/1964/33"), # UU Dana Pertanggungan Wajib Kecelakaan Penumpang
109
  (("kecelakaan lalu lintas", "asuransi korban kecelakaan", "jasa raharja"),
110
  "akn/id/act/uu/1964/34"), # UU Dana Pertanggungan Wajib Kecelakaan Lalu Lintas Jalan
111
+ # Hukum acara & KPK kelembagaan (Komisi III)
112
+ (("kuhap", "hukum acara pidana", "penyidikan", "penyelidikan", "praperadilan"),
113
+ "akn/id/act/uu/1981/8"), # KUHAP
114
+ (("kpk", "komisi pemberantasan korupsi"),
115
+ "akn/id/act/uu/2002/30"), # UU pembentukan KPK
116
+ (("kpk", "komisi pemberantasan korupsi", "dewan pengawas kpk"),
117
+ "akn/id/act/uu/2019/19"), # UU Perubahan Kedua KPK
118
+ # Sosial, kebencanaan, perlindungan anak & perempuan (Komisi VIII)
119
+ (("bencana", "kebencanaan", "bnpb", "bpbd", "tanggap darurat"),
120
+ "akn/id/act/uu/2007/24"), # UU Penanggulangan Bencana
121
+ (("perlindungan anak", "kekerasan terhadap anak", "hak anak"),
122
+ "akn/id/act/uu/2014/35"), # UU Perubahan Perlindungan Anak
123
+ (("kdrt", "kekerasan dalam rumah tangga", "pkdrt"),
124
+ "akn/id/act/uu/2004/23"), # UU PKDRT
125
+ (("kesejahteraan sosial", "bantuan sosial", "pmks"),
126
+ "akn/id/act/uu/2009/11"), # UU Kesejahteraan Sosial
127
+ # Diplomasi & perjanjian internasional (Komisi I)
128
+ (("hubungan luar negeri", "diplomasi", "wni di luar negeri", "perlindungan wni"),
129
+ "akn/id/act/uu/1999/37"), # UU Hubungan Luar Negeri
130
+ (("perjanjian internasional", "traktat", "ratifikasi"),
131
+ "akn/id/act/uu/2000/24"), # UU Perjanjian Internasional
132
+ # Pertanian, ketahanan pangan, lahan (Komisi IV)
133
+ (("lahan pertanian", "alih fungsi lahan", "ketahanan pangan", "lp2b"),
134
+ "akn/id/act/uu/2009/41"), # UU Perlindungan Lahan Pertanian Pangan Berkelanjutan
135
+ # BUMN, perdagangan, standardisasi (Komisi VI)
136
+ (("bumn", "badan usaha milik negara"),
137
+ "akn/id/act/uu/2003/19"), # UU BUMN
138
+ (("perdagangan", "perdagangan dalam negeri", "perdagangan luar negeri"),
139
+ "akn/id/act/uu/2014/7"), # UU Perdagangan
140
+ (("standardisasi", "sni", "penilaian kesesuaian"),
141
+ "akn/id/act/uu/2014/20"), # UU Standardisasi & Penilaian Kesesuaian
142
+ # UMKM (Komisi VII)
143
+ (("umkm", "usaha mikro", "usaha kecil", "usaha menengah"),
144
+ "akn/id/act/uu/2008/20"), # UU UMKM
145
+ # Keuangan & fiskal (Komisi XI)
146
+ (("p2sk", "sektor keuangan", "fintech", "pinjol", "pinjaman online"),
147
+ "akn/id/act/uu/2023/4"), # UU P2SK
148
+ (("ojk", "otoritas jasa keuangan"),
149
+ "akn/id/act/uu/2011/21"), # UU OJK
150
+ (("pajak", "perpajakan", "hpp", "harmonisasi peraturan perpajakan"),
151
+ "akn/id/act/uu/2021/7"), # UU HPP
152
+ # Energi, lingkungan hidup, pertambangan (Komisi XII)
153
+ (("ketahanan energi", "kebijakan energi", "energi nasional", "transisi energi", "energi terbarukan"),
154
+ "akn/id/act/uu/2007/30"), # UU Energi
155
+ (("lingkungan hidup", "pplh", "amdal", "izin lingkungan"),
156
+ "akn/id/act/uu/2009/32"), # UU PPLH
157
+ (("minerba", "mineral batubara", "pertambangan mineral"),
158
+ "akn/id/act/uu/2020/3"), # UU Perubahan Minerba
159
+ # HAM & keimigrasian (Komisi XIII)
160
+ (("ham", "hak asasi manusia", "komnas ham"),
161
+ "akn/id/act/uu/1999/39"), # UU HAM
162
+ (("keimigrasian", "imigrasi", "paspor", "pengungsi"),
163
+ "akn/id/act/uu/2011/6"), # UU Keimigrasian
164
  ]
165
 
166
 
src/legawa/agents/surat.py CHANGED
@@ -202,8 +202,14 @@ def reply(
202
  for check in failures
203
  ]
204
  msg = "surat: draft contains unverifiable citations: " + "; ".join(descriptions)
205
- console.print(f"[red]{msg}[/red]")
206
- raise ValueError(msg)
 
 
 
 
 
 
207
  return result
208
 
209
 
 
202
  for check in failures
203
  ]
204
  msg = "surat: draft contains unverifiable citations: " + "; ".join(descriptions)
205
+ # Honour the global strict-citations toggle (consistent with
206
+ # penyusun / analis_ruu). When disabled, surface as a warning
207
+ # rather than blocking the draft — useful when pasal.id is
208
+ # rate-limited or returning transport errors.
209
+ if pool.settings.strict_citations:
210
+ console.print(f"[red]{msg}[/red]")
211
+ raise ValueError(msg)
212
+ console.print(f"[yellow]{msg}[/yellow]")
213
  return result
214
 
215
 
tests/test_peneliti.py CHANGED
@@ -142,6 +142,76 @@ class PenelitiTests(unittest.TestCase):
142
  self.assertIn("akn/id/act/uu/1964/33", uris)
143
  self.assertIn("akn/id/act/uu/1964/34", uris)
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  def test_canonical_probe_uris_no_match_for_unrelated_topic(self) -> None:
146
  uris = _canonical_probe_uris(
147
  "regulasi izin usaha pertambangan emas skala kecil",
 
142
  self.assertIn("akn/id/act/uu/1964/33", uris)
143
  self.assertIn("akn/id/act/uu/1964/34", uris)
144
 
145
+ def test_canonical_probe_uris_komisi_iii_kuhap_kpk(self) -> None:
146
+ uris = _canonical_probe_uris(
147
+ "penegakan hukum kasus korupsi daerah dan praperadilan",
148
+ ["KPK", "KUHAP"],
149
+ )
150
+ self.assertIn("akn/id/act/uu/1981/8", uris) # KUHAP
151
+ self.assertIn("akn/id/act/uu/2002/30", uris) # KPK
152
+ self.assertIn("akn/id/act/uu/2019/19", uris) # KPK perubahan
153
+
154
+ def test_canonical_probe_uris_komisi_viii_bencana_anak(self) -> None:
155
+ uris = _canonical_probe_uris(
156
+ "bantuan sosial korban bencana yang melibatkan anak",
157
+ ["perlindungan anak", "BNPB"],
158
+ )
159
+ self.assertIn("akn/id/act/uu/2007/24", uris) # Penanggulangan Bencana
160
+ self.assertIn("akn/id/act/uu/2014/35", uris) # Perlindungan Anak
161
+
162
+ def test_canonical_probe_uris_komisi_i_diplomasi(self) -> None:
163
+ uris = _canonical_probe_uris(
164
+ "perlindungan WNI di luar negeri pasca konflik Gaza",
165
+ ["hubungan luar negeri", "perjanjian internasional"],
166
+ )
167
+ self.assertIn("akn/id/act/uu/1999/37", uris)
168
+ self.assertIn("akn/id/act/uu/2000/24", uris)
169
+
170
+ def test_canonical_probe_uris_komisi_xiii_ham_imigrasi(self) -> None:
171
+ uris = _canonical_probe_uris(
172
+ "penanganan pengungsi dan kewajiban HAM Indonesia",
173
+ ["imigrasi", "HAM"],
174
+ )
175
+ self.assertIn("akn/id/act/uu/1999/39", uris)
176
+ self.assertIn("akn/id/act/uu/2011/6", uris)
177
+
178
+ def test_canonical_probe_uris_komisi_xi_keuangan(self) -> None:
179
+ uris = _canonical_probe_uris(
180
+ "reformasi sektor keuangan, OJK, dan harmonisasi perpajakan UMKM",
181
+ ["P2SK", "fintech"],
182
+ )
183
+ self.assertIn("akn/id/act/uu/2023/4", uris) # P2SK
184
+ self.assertIn("akn/id/act/uu/2011/21", uris) # OJK
185
+ self.assertIn("akn/id/act/uu/2021/7", uris) # HPP
186
+ self.assertIn("akn/id/act/uu/2008/20", uris) # UMKM (keyword 'UMKM' in topic)
187
+
188
+ def test_canonical_probe_uris_komisi_xii_energi_minerba(self) -> None:
189
+ uris = _canonical_probe_uris(
190
+ "transisi energi dan dampak lingkungan tambang nikel",
191
+ ["minerba", "lingkungan hidup"],
192
+ )
193
+ self.assertIn("akn/id/act/uu/2007/30", uris) # Energi (transisi energi trigger)
194
+ self.assertIn("akn/id/act/uu/2009/32", uris) # PPLH
195
+ self.assertIn("akn/id/act/uu/2020/3", uris) # Minerba
196
+
197
+ def test_canonical_probe_uris_komisi_vi_bumn_perdagangan(self) -> None:
198
+ uris = _canonical_probe_uris(
199
+ "tata kelola BUMN dan perlindungan konsumen perdagangan",
200
+ ["BUMN", "perdagangan", "standardisasi"],
201
+ )
202
+ self.assertIn("akn/id/act/uu/2003/19", uris) # BUMN
203
+ self.assertIn("akn/id/act/uu/2014/7", uris) # Perdagangan
204
+ self.assertIn("akn/id/act/uu/2014/20", uris) # Standardisasi
205
+ self.assertIn("akn/id/act/uu/1999/8", uris) # Perlindungan Konsumen
206
+
207
+ def test_canonical_probe_uris_komisi_iv_lahan_pangan(self) -> None:
208
+ uris = _canonical_probe_uris(
209
+ "alih fungsi lahan pertanian dan ketahanan pangan",
210
+ ["LP2B"],
211
+ )
212
+ self.assertIn("akn/id/act/uu/2009/41", uris) # Perlindungan LP2B
213
+ self.assertIn("akn/id/act/uu/2012/18", uris) # UU Pangan
214
+
215
  def test_canonical_probe_uris_no_match_for_unrelated_topic(self) -> None:
216
  uris = _canonical_probe_uris(
217
  "regulasi izin usaha pertambangan emas skala kecil",
tests/test_surat.py CHANGED
@@ -3,6 +3,7 @@ from __future__ import annotations
3
  import json
4
  import sys
5
  import unittest
 
6
  from pathlib import Path
7
 
8
  SRC = Path(__file__).resolve().parents[1] / "src"
@@ -12,6 +13,11 @@ if str(SRC) not in sys.path:
12
  from legawa.agents.surat import reply
13
 
14
 
 
 
 
 
 
15
  class FakeLLM:
16
  def __init__(self, response: str):
17
  self.response = response
@@ -23,9 +29,10 @@ class FakeLLM:
23
 
24
 
25
  class FakePool:
26
- def __init__(self, small_response: str, big_response: str):
27
  self.small = FakeLLM(small_response)
28
  self.big = FakeLLM(big_response)
 
29
 
30
 
31
  class FakePasalClient:
@@ -79,6 +86,21 @@ class SuratReplyTests(unittest.TestCase):
79
  self.assertEqual(len(pool.big.calls), 1)
80
  self.assertGreaterEqual(len(pasal.calls), 2)
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  def test_reply_accepts_verified_citation(self) -> None:
83
  pool = FakePool(
84
  self._triase_json(),
 
3
  import json
4
  import sys
5
  import unittest
6
+ from dataclasses import dataclass
7
  from pathlib import Path
8
 
9
  SRC = Path(__file__).resolve().parents[1] / "src"
 
13
  from legawa.agents.surat import reply
14
 
15
 
16
+ @dataclass
17
+ class FakeSettings:
18
+ strict_citations: bool = True
19
+
20
+
21
  class FakeLLM:
22
  def __init__(self, response: str):
23
  self.response = response
 
29
 
30
 
31
  class FakePool:
32
+ def __init__(self, small_response: str, big_response: str, *, strict_citations: bool = True):
33
  self.small = FakeLLM(small_response)
34
  self.big = FakeLLM(big_response)
35
+ self.settings = FakeSettings(strict_citations=strict_citations)
36
 
37
 
38
  class FakePasalClient:
 
86
  self.assertEqual(len(pool.big.calls), 1)
87
  self.assertGreaterEqual(len(pasal.calls), 2)
88
 
89
+ def test_reply_warns_instead_of_blocking_when_strict_disabled(self) -> None:
90
+ # With strict_citations=False, an unverifiable citation should warn,
91
+ # not block — consistent with penyusun and analis_ruu behaviour.
92
+ # Useful when pasal.id is rate-limited or returning transport errors.
93
+ pool = FakePool(
94
+ self._triase_json(),
95
+ "Kami merujuk pada UU 13/2003 dan Perpres 76/2021 dalam balasan ini.",
96
+ strict_citations=False,
97
+ )
98
+ pasal = FakePasalClient()
99
+
100
+ result = reply(pool, pasal, "surat uji", verify_law=True)
101
+ self.assertIsNotNone(result.balasan)
102
+ self.assertIn("Perpres 76/2021", result.balasan or "")
103
+
104
  def test_reply_accepts_verified_citation(self) -> None:
105
  pool = FakePool(
106
  self._triase_json(),