@rulemetric/local 0.12.8 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/meta.json +2 -2
- package/dist/server.mjs +687 -389
- package/dist/supabase/migrations/00213_vendor_guidance_snapshots.sql +52 -0
- package/dist/supabase/migrations/00214_host_suspend_recoveries.sql +54 -0
- package/dist/supabase/migrations/00215_worker_presence_gap.sql +29 -0
- package/dist/supabase/migrations/00216_db_headroom_check_and_worker_connections_fk.sql +142 -0
- package/dist/supabase/migrations/00217_harbor_ab_cadence.sql +46 -0
- package/dist/supabase/migrations/00218_backfill_session_events_model.sql +30 -0
- package/dist/supabase/migrations/00219_weekly_digest.sql +64 -0
- package/dist/supabase/migrations/00220_snapshot_payload_lifecycle.sql +107 -0
- package/dist/supabase/migrations/00221_snapshot_payload_expiry.sql +34 -0
- package/dist/supabase/migrations/00222_memory_experiment_engine.sql +20 -0
- package/dist/supabase/migrations/00223_measurement_preferences.sql +21 -0
- package/dist/supabase/migrations/00224_measurement_job_snapshots.sql +246 -0
- package/dist/web/assets/{docs-KIeJWTb-.js → docs-sROR5bQ8.js} +46 -46
- package/dist/web/assets/index-Cpw-uDNX.css +1 -0
- package/dist/web/assets/{index-MYof2fnF.js → index-D7l_eoTZ.js} +43 -43
- package/dist/web/index.html +3 -3
- package/package.json +4 -3
- package/dist/web/assets/index-CFJatBZ3.css +0 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
-- Immutable selection for NEW jobs only. Existing payloads and all producer
|
|
2
|
+
-- eligibility predicates from 00210 remain unchanged.
|
|
3
|
+
create or replace function public.measurement_execution_for_user(owner_id uuid, workload text)
|
|
4
|
+
returns jsonb
|
|
5
|
+
language plpgsql stable
|
|
6
|
+
set search_path = public
|
|
7
|
+
as $$
|
|
8
|
+
declare preference jsonb;
|
|
9
|
+
begin
|
|
10
|
+
if workload not in ('eval', 'harbor') then
|
|
11
|
+
raise exception 'Unknown measurement workload: %', workload;
|
|
12
|
+
end if;
|
|
13
|
+
select measurement_preferences into preference from public.profiles where id = owner_id;
|
|
14
|
+
if preference is null or preference->>'engine' is null then return null; end if;
|
|
15
|
+
return jsonb_build_object(
|
|
16
|
+
'version', 1,
|
|
17
|
+
'engine', preference->>'engine',
|
|
18
|
+
'model', coalesce(nullif(btrim(preference->>'model'), ''),
|
|
19
|
+
case when workload = 'harbor' then 'claude-haiku-4-5' else null end),
|
|
20
|
+
'source', 'account'
|
|
21
|
+
);
|
|
22
|
+
end;
|
|
23
|
+
$$;
|
|
24
|
+
revoke all on function public.measurement_execution_for_user(uuid, text) from public, anon, authenticated;
|
|
25
|
+
grant execute on function public.measurement_execution_for_user(uuid, text) to service_role;
|
|
26
|
+
|
|
27
|
+
-- Keep a canonical model attached to the engine that supplied its evidence.
|
|
28
|
+
-- Explicit historical model-only pins still mean Claude; inferred GPT judges
|
|
29
|
+
-- must not acquire that legacy default on their second scheduled batch.
|
|
30
|
+
create or replace function public.eval_target_judge_engine(p_target_id uuid)
|
|
31
|
+
returns text
|
|
32
|
+
language sql stable security definer
|
|
33
|
+
set search_path = public
|
|
34
|
+
as $$
|
|
35
|
+
with target as (
|
|
36
|
+
select nullif(btrim(metadata->>'graderModel'), '') as pin,
|
|
37
|
+
coalesce(metadata->>'graderEngine', 'claude') as pin_engine,
|
|
38
|
+
public.eval_target_judge_segment(id) as elected_model
|
|
39
|
+
from eval_targets where id = p_target_id
|
|
40
|
+
), elector as (
|
|
41
|
+
select r.grading->>'judge_model' as model,
|
|
42
|
+
coalesce(r.grading->>'judge_engine', 'claude') as engine, r.created_at,
|
|
43
|
+
(r.grading->>'judge_model_requested' is null
|
|
44
|
+
or r.grading->>'judge_model_requested' = r.grading->>'judge_model') as clean,
|
|
45
|
+
case when jsonb_typeof(r.grading->'expectations') = 'array' then (
|
|
46
|
+
select count(*) from jsonb_array_elements(r.grading->'expectations') e
|
|
47
|
+
where coalesce(e->>'method', 'llm') = 'llm'
|
|
48
|
+
and coalesce(e->>'errored', 'false') <> 'true'
|
|
49
|
+
) else 0 end as llm_total,
|
|
50
|
+
(select count(*) from eval_grade_annotations a
|
|
51
|
+
where a.eval_target_id = p_target_id and a.eval_run_id = r.id
|
|
52
|
+
and a.judge_method = 'llm') as llm_annotated
|
|
53
|
+
from eval_runs r
|
|
54
|
+
where r.eval_target_id = p_target_id and r.status = 'completed'
|
|
55
|
+
and r.configuration in ('with_target', 'without_target')
|
|
56
|
+
and r.grading->>'judge_model' is not null
|
|
57
|
+
), eligible as (
|
|
58
|
+
select e.* from elector e
|
|
59
|
+
where (e.clean or not exists (select 1 from elector where clean))
|
|
60
|
+
and e.model = (select elected_model from target)
|
|
61
|
+
)
|
|
62
|
+
select case when t.pin is not null then t.pin_engine else (
|
|
63
|
+
select engine from eligible group by engine
|
|
64
|
+
order by count(*) filter (where llm_total > 0 and llm_annotated >= llm_total) desc,
|
|
65
|
+
max(created_at) desc, engine desc limit 1
|
|
66
|
+
) end from target t;
|
|
67
|
+
$$;
|
|
68
|
+
revoke all on function public.eval_target_judge_engine(uuid) from public, anon, authenticated;
|
|
69
|
+
grant execute on function public.eval_target_judge_engine(uuid) to service_role;
|
|
70
|
+
|
|
71
|
+
-- ── enqueue_instruction_evolution, health gates now read from the view ───────
|
|
72
|
+
create or replace function public.enqueue_instruction_evolution()
|
|
73
|
+
returns integer
|
|
74
|
+
language plpgsql
|
|
75
|
+
security definer
|
|
76
|
+
set search_path = public
|
|
77
|
+
as $$
|
|
78
|
+
declare
|
|
79
|
+
queued integer;
|
|
80
|
+
begin
|
|
81
|
+
with health_ok as (
|
|
82
|
+
select t.id, t.user_id
|
|
83
|
+
from eval_targets t
|
|
84
|
+
where coalesce(t.metadata->>'autoEvolvePaused', 'false') <> 'true'
|
|
85
|
+
-- Health 2a/2b/2c: ONE definition (00210), shared with eval autorun.
|
|
86
|
+
and exists (
|
|
87
|
+
select 1 from public.healthy_eval_targets h where h.eval_target_id = t.id
|
|
88
|
+
)
|
|
89
|
+
-- Live cases to measure against — at least MIN_LIVE_CASES (3).
|
|
90
|
+
-- `exists` (>= 1) was the bug: see 00183's header.
|
|
91
|
+
and (
|
|
92
|
+
select count(*) from evals ev
|
|
93
|
+
where ev.eval_target_id = t.id and ev.retired_at is null
|
|
94
|
+
) >= 3
|
|
95
|
+
-- Change budget (cheap exclusion; the API is the authority).
|
|
96
|
+
and (
|
|
97
|
+
select count(*)
|
|
98
|
+
from instruction_promotions p
|
|
99
|
+
where p.eval_target_id = t.id
|
|
100
|
+
and p.applied
|
|
101
|
+
and p.created_at > now() - interval '7 days'
|
|
102
|
+
) < 3
|
|
103
|
+
-- One in flight at a time.
|
|
104
|
+
and not exists (
|
|
105
|
+
select 1 from agent_jobs j
|
|
106
|
+
where j.task_kind = 'cron_instruction_evolution'
|
|
107
|
+
and j.status in ('pending', 'claimed', 'running')
|
|
108
|
+
and j.payload->>'evalTargetId' = t.id::text
|
|
109
|
+
)
|
|
110
|
+
),
|
|
111
|
+
manual as (
|
|
112
|
+
-- The hand-picked path, unchanged and uncapped.
|
|
113
|
+
select h.id, h.user_id
|
|
114
|
+
from health_ok h
|
|
115
|
+
join eval_targets t on t.id = h.id
|
|
116
|
+
where coalesce(t.metadata->>'autoEvolveEnabled', 'false') = 'true'
|
|
117
|
+
),
|
|
118
|
+
auto_ranked as (
|
|
119
|
+
-- The stated rule. Round-robin: never-decided first (nulls first), then
|
|
120
|
+
-- least-recently-decided, so the cap rotates through the candidate pool
|
|
121
|
+
-- instead of re-measuring the same winners nightly.
|
|
122
|
+
select h.id, h.user_id,
|
|
123
|
+
row_number() over (
|
|
124
|
+
partition by h.user_id
|
|
125
|
+
order by (
|
|
126
|
+
select max(p.created_at)
|
|
127
|
+
from instruction_promotions p
|
|
128
|
+
where p.eval_target_id = h.id
|
|
129
|
+
) asc nulls first,
|
|
130
|
+
h.id
|
|
131
|
+
) as rn
|
|
132
|
+
from health_ok h
|
|
133
|
+
join eval_targets t on t.id = h.id
|
|
134
|
+
where t.type = 'instruction'
|
|
135
|
+
and coalesce(t.metadata->>'autoEvolveOptOut', 'false') <> 'true'
|
|
136
|
+
-- Not already covered by the manual path.
|
|
137
|
+
and coalesce(t.metadata->>'autoEvolveEnabled', 'false') <> 'true'
|
|
138
|
+
-- ACTIVE (00145's load-bearing gate): a run in the last 30 days.
|
|
139
|
+
and exists (
|
|
140
|
+
select 1 from eval_runs r
|
|
141
|
+
where r.eval_target_id = t.id
|
|
142
|
+
and r.created_at > now() - interval '30 days'
|
|
143
|
+
)
|
|
144
|
+
),
|
|
145
|
+
eligible as (
|
|
146
|
+
select id, user_id from manual
|
|
147
|
+
union
|
|
148
|
+
select id, user_id from auto_ranked where rn <= 3
|
|
149
|
+
),
|
|
150
|
+
ins as (
|
|
151
|
+
insert into agent_jobs (user_id, task_kind, status, payload, dedupe_key)
|
|
152
|
+
select e.user_id,
|
|
153
|
+
'cron_instruction_evolution',
|
|
154
|
+
'pending',
|
|
155
|
+
jsonb_build_object('evalTargetId', e.id::text)
|
|
156
|
+
|| case
|
|
157
|
+
when public.eval_target_judge_segment(e.id) is not null
|
|
158
|
+
then jsonb_build_object(
|
|
159
|
+
'graderModel', public.eval_target_judge_segment(e.id),
|
|
160
|
+
'graderEngine', public.eval_target_judge_engine(e.id))
|
|
161
|
+
else '{}'::jsonb
|
|
162
|
+
end
|
|
163
|
+
|| case when public.measurement_execution_for_user(e.user_id, 'eval') is null
|
|
164
|
+
then '{}'::jsonb
|
|
165
|
+
else jsonb_build_object('measurement', public.measurement_execution_for_user(e.user_id, 'eval')) end,
|
|
166
|
+
'instruction-evolution:' || e.id::text
|
|
167
|
+
from eligible e
|
|
168
|
+
returning 1
|
|
169
|
+
)
|
|
170
|
+
select count(*)::int into queued from ins;
|
|
171
|
+
|
|
172
|
+
return queued;
|
|
173
|
+
end;
|
|
174
|
+
$$;
|
|
175
|
+
|
|
176
|
+
comment on function public.enqueue_instruction_evolution() is
|
|
177
|
+
'Daily producer for cron_instruction_evolution. Health gates 2a/2b/2c come from the healthy_eval_targets view (00210); pause, live-cases floor (>=3, 00183), change budget, round-robin enrolment and in-flight dedupe stay here. Judge segment from eval_target_judge_segment() (00193).';
|
|
178
|
+
|
|
179
|
+
-- ── enqueue_eval_autorun, health gates now read from the view ────────────────
|
|
180
|
+
create or replace function public.enqueue_eval_autorun()
|
|
181
|
+
returns integer
|
|
182
|
+
language plpgsql
|
|
183
|
+
security definer
|
|
184
|
+
set search_path = public
|
|
185
|
+
as $$
|
|
186
|
+
declare
|
|
187
|
+
queued integer;
|
|
188
|
+
begin
|
|
189
|
+
with eligible as (
|
|
190
|
+
select t.id, t.user_id,
|
|
191
|
+
-- Canonical segment (00193). Was an inline "most recent stamped run"
|
|
192
|
+
-- subquery, which is how a credit-exhaustion fallback became the pin.
|
|
193
|
+
public.eval_target_judge_segment(t.id) as current_judge,
|
|
194
|
+
public.eval_target_judge_engine(t.id) as current_judge_engine
|
|
195
|
+
from eval_targets t
|
|
196
|
+
where coalesce(t.metadata->>'autoRunEnabled', 'false') = 'true'
|
|
197
|
+
-- Gate 0 (00190): the target must be anchored to something a promotion
|
|
198
|
+
-- could land on. Without this, a batch is two LLM executions plus a
|
|
199
|
+
-- judged grade spent to rewrite a row nothing reads.
|
|
200
|
+
and (
|
|
201
|
+
t.instruction_id is not null
|
|
202
|
+
or t.project_path is not null
|
|
203
|
+
or t.name like '/%'
|
|
204
|
+
)
|
|
205
|
+
-- Gates 2a/2b/2c: ONE definition (00210), shared with evolution.
|
|
206
|
+
and exists (
|
|
207
|
+
select 1 from public.healthy_eval_targets h where h.eval_target_id = t.id
|
|
208
|
+
)
|
|
209
|
+
-- Gate 3: the target has live cases to actually run.
|
|
210
|
+
and exists (
|
|
211
|
+
select 1 from evals ev
|
|
212
|
+
where ev.eval_target_id = t.id and ev.retired_at is null
|
|
213
|
+
)
|
|
214
|
+
-- One in flight at a time, per the 00083/00086 pattern.
|
|
215
|
+
and not exists (
|
|
216
|
+
select 1 from agent_jobs j
|
|
217
|
+
where j.task_kind = 'cron_eval_autorun'
|
|
218
|
+
and j.status in ('pending', 'claimed', 'running')
|
|
219
|
+
and j.payload->>'evalTargetId' = t.id::text
|
|
220
|
+
)
|
|
221
|
+
), ins as (
|
|
222
|
+
insert into agent_jobs (user_id, task_kind, status, payload, dedupe_key)
|
|
223
|
+
select e.user_id,
|
|
224
|
+
'cron_eval_autorun',
|
|
225
|
+
'pending',
|
|
226
|
+
jsonb_build_object('evalTargetId', e.id::text, 'maxRuns', 12)
|
|
227
|
+
|| case
|
|
228
|
+
when e.current_judge is not null
|
|
229
|
+
then jsonb_build_object('graderModel', e.current_judge, 'graderEngine', e.current_judge_engine)
|
|
230
|
+
else '{}'::jsonb
|
|
231
|
+
end
|
|
232
|
+
|| case when public.measurement_execution_for_user(e.user_id, 'eval') is null
|
|
233
|
+
then '{}'::jsonb
|
|
234
|
+
else jsonb_build_object('measurement', public.measurement_execution_for_user(e.user_id, 'eval')) end,
|
|
235
|
+
'eval-autorun:' || e.id::text
|
|
236
|
+
from eligible e
|
|
237
|
+
returning 1
|
|
238
|
+
)
|
|
239
|
+
select count(*)::int into queued from ins;
|
|
240
|
+
|
|
241
|
+
return queued;
|
|
242
|
+
end;
|
|
243
|
+
$$;
|
|
244
|
+
|
|
245
|
+
comment on function public.enqueue_eval_autorun() is
|
|
246
|
+
'Daily producer for cron_eval_autorun. Health gates 2a/2b/2c come from the healthy_eval_targets view (00210); the anchor gate (00190), live-cases exists, judge segment (00193) and in-flight dedupe stay here.';
|