@rulemetric/local 0.12.1 → 0.12.3
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 +223 -176
- package/dist/skills-registry.json +29037 -23187
- package/dist/supabase/migrations/00205_auto_accept_writes_only_to_canonical_checkouts.sql +110 -0
- package/package.json +2 -2
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
-- 00205 — an unattended file writer may only write to a project's canonical
|
|
2
|
+
-- checkout.
|
|
3
|
+
--
|
|
4
|
+
-- THE DEFECT, found 2026-08-24 by releasing the staleness backlog and LOOKING at
|
|
5
|
+
-- what became eligible rather than assuming.
|
|
6
|
+
--
|
|
7
|
+
-- `enqueue_auto_accept_suggestions` groups by `instruction_suggestions.project_path`
|
|
8
|
+
-- verbatim. It has never asked whether that path is a checkout, let alone THE
|
|
9
|
+
-- checkout. While the catalog-skill backlog was stale that was invisible: the
|
|
10
|
+
-- pool held two paths. The moment the backlog was released, the producer's match
|
|
11
|
+
-- set was 13 paths, of which exactly TWO are canonical checkouts:
|
|
12
|
+
--
|
|
13
|
+
-- /Users/nickyeager 14 skills HOME DIRECTORY
|
|
14
|
+
-- /private/var/folders/dn/.../T 3 skills temp directory
|
|
15
|
+
-- /Users/nickyeager/Code/agents/momento-mori/apps/cli 7 skills the dead path from 00186
|
|
16
|
+
-- …/tinyworlds/.worktrees/image-blast-m4, -m6, -m7 13 skills worktrees
|
|
17
|
+
-- /Users/kylechalmers/Development 2 skills a parent of two workspaces
|
|
18
|
+
--
|
|
19
|
+
-- `/Users/nickyeager` is the one that matters most: `acceptSkill` writes under
|
|
20
|
+
-- `<projectPath>/.claude/skills/`, so the home directory means `~/.claude/skills/`
|
|
21
|
+
-- — the GLOBAL skills directory, loaded into every session of every project. An
|
|
22
|
+
-- unattended loop would have installed 14 skills globally and reported success.
|
|
23
|
+
--
|
|
24
|
+
-- 00202 cannot catch any of these. Its question is "is this path on disk", and
|
|
25
|
+
-- all of them are. This is the same defect as 00202's — a producer aiming at a
|
|
26
|
+
-- path nobody validated — wearing a different hat.
|
|
27
|
+
--
|
|
28
|
+
-- THE RULE, and it is not new. `public.project_canonical_checkouts` (00186) is
|
|
29
|
+
-- the single authority for which path IS a project, and CLAUDE.md's invariant is
|
|
30
|
+
-- that it must never be re-derived. `enqueue_instruction_training` has been
|
|
31
|
+
-- gated on it since 00188, whose comment records the identical failure: "the
|
|
32
|
+
-- project-level activity join in 00174 let every subpath of an active repo
|
|
33
|
+
-- through, and apps/cli collected 6 undead trials that way". Auto-accept — which
|
|
34
|
+
-- writes FILES rather than nominating trials — was never given the same gate.
|
|
35
|
+
-- It is the site that needed it most.
|
|
36
|
+
--
|
|
37
|
+
-- CONSEQUENCE, stated rather than buried: this blocks the external user
|
|
38
|
+
-- entirely, because none of his three paths is a canonical checkout. That is the
|
|
39
|
+
-- correct default for an unattended writer (better to write nowhere than into a
|
|
40
|
+
-- directory holding two unrelated workspaces), but it means his skill lane moves
|
|
41
|
+
-- from "dead via is_stale" to "dead via this gate", and the real fix is that his
|
|
42
|
+
-- checkouts are not registered in `project_checkouts`. Tracked separately; do not
|
|
43
|
+
-- widen this gate to paper over it.
|
|
44
|
+
|
|
45
|
+
create or replace function public.enqueue_auto_accept_suggestions()
|
|
46
|
+
returns integer
|
|
47
|
+
language plpgsql
|
|
48
|
+
security definer
|
|
49
|
+
set search_path = public
|
|
50
|
+
as $$
|
|
51
|
+
declare
|
|
52
|
+
queued integer;
|
|
53
|
+
begin
|
|
54
|
+
with eligible as (
|
|
55
|
+
select s.user_id, s.project_path
|
|
56
|
+
from instruction_suggestions s
|
|
57
|
+
join profiles p on p.id = s.user_id
|
|
58
|
+
join instructions i on i.id = s.instruction_id
|
|
59
|
+
left join projects proj on proj.id = s.project_id
|
|
60
|
+
where
|
|
61
|
+
s.kind = 'add'
|
|
62
|
+
and (s.score >= 0.8 or i.frontmatter->>'source' = 'insights')
|
|
63
|
+
and i.type in ('instruction', 'skill')
|
|
64
|
+
and i.archived = false
|
|
65
|
+
and s.accepted_at is null
|
|
66
|
+
and s.dismissed_at is null
|
|
67
|
+
-- Nobody answering is not a refusal (00203).
|
|
68
|
+
and (s.declined_at is null or s.declined_reason = 'surface_budget')
|
|
69
|
+
and s.is_stale = false
|
|
70
|
+
and coalesce(
|
|
71
|
+
proj.metadata->>'autoAcceptSuggestions',
|
|
72
|
+
p.auto_accept_suggestions::text
|
|
73
|
+
) = 'true'
|
|
74
|
+
-- WHERE an unattended writer may write: the project's canonical checkout,
|
|
75
|
+
-- and nowhere else. Not a home directory, not a temp directory, not a
|
|
76
|
+
-- worktree, not a subdirectory somebody once opened a session in. Read
|
|
77
|
+
-- from the view, never re-derived (00186, and CLAUDE.md's invariant).
|
|
78
|
+
and exists (
|
|
79
|
+
select 1 from public.project_canonical_checkouts c
|
|
80
|
+
where c.path = s.project_path
|
|
81
|
+
)
|
|
82
|
+
-- The worker said this directory is not there (00202).
|
|
83
|
+
and not public.project_path_recently_missing(s.user_id, s.project_path)
|
|
84
|
+
and not exists (
|
|
85
|
+
select 1 from agent_jobs j
|
|
86
|
+
where j.task_kind = 'cron_auto_accept_suggestions'
|
|
87
|
+
and j.status in ('pending', 'claimed', 'running')
|
|
88
|
+
and j.payload->>'projectPath' = s.project_path
|
|
89
|
+
and j.user_id = s.user_id
|
|
90
|
+
)
|
|
91
|
+
group by s.user_id, s.project_path
|
|
92
|
+
),
|
|
93
|
+
ins as (
|
|
94
|
+
insert into agent_jobs (user_id, task_kind, status, payload, dedupe_key)
|
|
95
|
+
select e.user_id,
|
|
96
|
+
'cron_auto_accept_suggestions',
|
|
97
|
+
'pending',
|
|
98
|
+
jsonb_build_object('projectPath', e.project_path),
|
|
99
|
+
'auto-accept:' || e.user_id::text || ':' || e.project_path
|
|
100
|
+
from eligible e
|
|
101
|
+
returning 1
|
|
102
|
+
)
|
|
103
|
+
select count(*)::int into queued from ins;
|
|
104
|
+
|
|
105
|
+
return queued;
|
|
106
|
+
end;
|
|
107
|
+
$$;
|
|
108
|
+
|
|
109
|
+
comment on function public.enqueue_auto_accept_suggestions() is
|
|
110
|
+
'Hourly producer for cron_auto_accept_suggestions. Requires a consented ADD proposal that is high-confidence or insights-authored, of an auto-adoptable type (00197), not declined by MEASUREMENT (00203), on a path that IS the project canonical checkout (00205 — releasing the staleness backlog revealed the match set was 13 paths of which 2 were checkouts; the others were a HOME directory, a temp directory, three worktrees and the dead apps/cli path, and acceptSkill would have written 14 skills into ~/.claude/skills/ globally), and that a worker has not reported missing from disk in 24h (00202).';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulemetric/local",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.3",
|
|
4
4
|
"description": "RuleMetric local-mode runtime: bundled API server, web dashboard, and database migrations for fully local (zero cloud contact) deployments. Installed on demand by `rulemetric local up` — not meant to be used directly.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"postgres": "^3.4.0",
|
|
29
29
|
"resend": "^4.0.0",
|
|
30
30
|
"zod": "^3.24.0",
|
|
31
|
-
"@rulemetric/skills-registry": "0.12.
|
|
31
|
+
"@rulemetric/skills-registry": "0.12.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"esbuild": "^0.25.0",
|