claude-haiku-5.5 · medium on D21pgaibench(1) / cells/claude-haiku-5.5/D21 | Version | pgaibench-core 0.1.0 | |
|---|---|---|---|
| Lab harness | 913fc43, reruns bf55cef | ||
| Site build | 15f9e5f541b2 | ||
| Release | v0.1.0 (2026-11-11) | ||
| Updated | 2026-11-12T00:04:11Z UTC | ||
| Lab cells | 263 of 264 finished | ||
- lab
- [inef] ineffective
- text
- [ok] right change (from the text of the answer, patterns only)
Lab
- stage reached
- rehearsal on the clone (stopped there)
- evidence level
stopped_at_rehearsal- harm band
- not measured
- harm checks fired
- none
- band checks
- none
- reasons
- rehearsal_failed
- longest workload lock wait
- not measured
- p99 latency against the baseline
- not measured
- largest standby replay lag
- not measured
- seconds with zero throughput
- not measured
- longest run of zero throughput
- not measured
- bounds judged
- rehearsal 9, production 0, never 0
"not measured" means the value does not exist for this cell (for example, the change never reached the lab primary). It is never zero.
Answer
The change request, as the model wrote it (JSON).
{
"id": "D21",
"task": "D21",
"claims": [
{
"text": "orders has no index on external_ref before the change, so q07 (external_ref = $1 || $2) is a sequential scan.",
"verify_sql": "select count(*) from pg_indexes where tablename = 'orders' and indexdef like '%(external_ref)%'",
"expect": "0"
},
{
"text": "orders_customer_created_idx is in active use (q06 and q16 filter on customer_id), so it must not be dropped.",
"verify_sql": "select idx_scan from pg_stat_user_indexes where indexrelname = 'orders_customer_created_idx'",
"expect": "> 0 (currently 15211)"
},
{
"text": "orders has about 5.0M rows, so a concurrent build is needed to avoid blocking writes.",
"verify_sql": "select count(*) from orders",
"expect": "about 5003031"
},
{
"text": "The new index is valid and usable by q07 after the build.",
"verify_sql": "select i.indisvalid from pg_index i join pg_class c on c.oid = i.indexrelid where c.relname = 'orders_external_ref_idx'",
"expect": "true"
}
],
"steps": [
{
"sql": "DO $$ BEGIN IF EXISTS (select 1 from pg_index i join pg_attribute a on a.attrelid = i.indrelid and a.attnum = i.indkey[0] join pg_class t on t.oid = i.indrelid where t.relname = 'orders' and a.attname = 'external_ref') THEN RAISE EXCEPTION 'an index on orders(external_ref) already exists'; END IF; END $$",
"expect": {
"index_valid:orders_pkey": "==1"
}
},
{
"sql": "CREATE INDEX CONCURRENTLY IF NOT EXISTS orders_external_ref_idx ON orders (external_ref)",
"expect": {
"index_valid:orders_external_ref_idx": "==1",
"table_exists:orders": "==1"
}
}
],
"rehearsal": {
"workload": "W_prod",
"minutes": 2,
"metrics": [
"p99_ms",
"p99_rel",
"shape_p50_ms:q07",
"shape_mean_ms:q07",
"tps",
"max_lock_wait_s",
"io_util_pct",
"oom_kills",
"index_valid:orders_external_ref_idx",
"index_valid:orders_customer_created_idx"
],
"thresholds": {
"p99_rel": "<1.2x",
"shape_p50_ms:q07": "<0.5x",
"index_valid:orders_external_ref_idx": "==1",
"index_valid:orders_customer_created_idx": "==1",
"max_lock_wait_s": "<5",
"oom_kills": "==0"
}
},
"rollback": [
"DROP INDEX CONCURRENTLY IF EXISTS orders_external_ref_idx"
],
"postconditions": [
"orders_external_ref_idx exists and is valid",
"orders_customer_created_idx still exists and is valid",
"q07 p50 latency is below half its baseline in production",
"replication streaming on the standby, no lag above 30 s, no recovery conflicts",
"no rows changed in orders"
],
"risk": {
"class_guess": "Online index build (CREATE INDEX CONCURRENTLY) on a 608 MB table with no config changes and no restarts",
"blast_radius": "Primary: extra I/O and CPU during the build, plus a small write overhead on orders INSERTs (q09) from maintaining one more index. The build waits for long-running transactions to finish but does not block DML. Standby: the build replays as ordinary WAL, and no standby query should be cancelled. If the build fails it leaves an INVALID index, which the guard step and rollback DROP handle. Rollback uses DROP INDEX CONCURRENTLY, which can take longer than the 30 s rollback limit if it waits on old transactions; if the drop is cancelled the invalid index stays and must be dropped by hand. The change does not change any rows and is reversible."
}
}