@@ -326,3 +326,71 @@ INSERT INTO verisimdb.proof_attempts VALUES
326326 ' Guard rule prevents invalid transitions' , ' safety' , ' z3' , ' success' , 342 , 0 .99 , NULL ,
327327 ' gnn-guided' , now() - INTERVAL 30 MINUTE, now() - INTERVAL 30 MINUTE + INTERVAL 342 MILLISECOND,
328328 ' unsat (proved, no counterexample).' , NULL );
329+
330+ -- ---------------------------------------------------------------------------
331+ -- V4: Certificate policy + views (2026-04-05)
332+ -- See docs/design/DESIGN-2026-04-05-V4-proof-attempts-vqldt.adoc
333+ -- ---------------------------------------------------------------------------
334+
335+ CREATE TABLE IF NOT EXISTS verisimdb .proof_attempts_cert_policy
336+ (
337+ policy_id String DEFAULT ' default' ,
338+ tau_proven Float32,
339+ n_proven UInt64,
340+ k_sanctify UInt32,
341+ n_sanctify UInt64,
342+ updated_at DateTime64(3 ) DEFAULT now64(3 )
343+ )
344+ ENGINE = ReplacingMergeTree(updated_at)
345+ ORDER BY policy_id;
346+
347+ INSERT INTO verisimdb .proof_attempts_cert_policy
348+ (policy_id, tau_proven, n_proven, k_sanctify, n_sanctify)
349+ VALUES (' default' , 0 .80 , 20 , 2 , 50 );
350+
351+ CREATE VIEW IF NOT EXISTS verisimdb .mv_proven_certificates AS
352+ SELECT
353+ m .obligation_class , m .prover_used ,
354+ sum (m .success_count ) AS success_count,
355+ sum (m .total_attempts ) AS total_attempts,
356+ sum (m .total_duration_ms ) AS total_duration_ms,
357+ sum (m .success_count ) / sum (m .total_attempts ) AS success_rate,
358+ sum (m .total_duration_ms ) / sum (m .total_attempts ) AS avg_duration_ms,
359+ p .tau_proven , p .n_proven ,
360+ if(sum (m .success_count ) / sum (m .total_attempts ) >= p .tau_proven
361+ AND sum (m .total_attempts ) >= p .n_proven , ' proven' , ' pending' ) AS status,
362+ cityHash64(concat(' proven|' , toString(m .obligation_class ), ' |' , toString(m .prover_used ))) AS cert_id
363+ FROM verisimdb .mv_prover_success_by_class AS m
364+ CROSS JOIN (
365+ SELECT argMax(tau_proven, updated_at) AS tau_proven,
366+ argMax(n_proven, updated_at) AS n_proven
367+ FROM verisimdb .proof_attempts_cert_policy WHERE policy_id = ' default'
368+ ) AS p
369+ GROUP BY m .obligation_class , m .prover_used , p .tau_proven , p .n_proven ;
370+
371+ CREATE VIEW IF NOT EXISTS verisimdb .mv_sanctify_certificates AS
372+ SELECT
373+ pc .obligation_class ,
374+ count (DISTINCT pc .prover_used ) AS proven_provers,
375+ groupArray(pc .prover_used ) AS provers,
376+ sum (pc .total_attempts ) AS combined_attempts,
377+ p .k_sanctify , p .n_sanctify ,
378+ if(count (DISTINCT pc .prover_used ) >= p .k_sanctify
379+ AND sum (pc .total_attempts ) >= p .n_sanctify , ' sanctified' , ' pending' ) AS status,
380+ cityHash64(concat(' sanctify|' , toString(pc .obligation_class ))) AS cert_id
381+ FROM verisimdb .mv_proven_certificates AS pc
382+ CROSS JOIN (
383+ SELECT argMax(k_sanctify, updated_at) AS k_sanctify,
384+ argMax(n_sanctify, updated_at) AS n_sanctify
385+ FROM verisimdb .proof_attempts_cert_policy WHERE policy_id = ' default'
386+ ) AS p
387+ WHERE pc .status = ' proven'
388+ GROUP BY pc .obligation_class , p .k_sanctify , p .n_sanctify ;
389+
390+ CREATE VIEW IF NOT EXISTS verisimdb .mv_cert_evidence AS
391+ SELECT
392+ cityHash64(concat(' proven|' , toString(pa .obligation_class ), ' |' , toString(pa .prover_used ))) AS cert_id,
393+ ' proven' AS cert_type,
394+ pa .obligation_class , pa .prover_used , pa .attempt_id , pa .obligation_id ,
395+ pa .outcome , pa .duration_ms , pa .confidence , pa .started_at , pa .repo , pa .file
396+ FROM verisimdb .proof_attempts AS pa;
0 commit comments