@automagik/genie 4.260429.10 → 4.260429.12
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automagik/genie",
|
|
3
|
-
"version": "4.260429.
|
|
3
|
+
"version": "4.260429.12",
|
|
4
4
|
"description": "Collaborative terminal toolkit for human + AI workflows. NOTE: the npm distribution is being soft-deprecated — the canonical install is `curl -fsSL https://get.automagik.dev/genie | bash` (cosign + SLSA verified). See https://automagik.dev/genie/security/distribution-sovereignty",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genie",
|
|
3
|
-
"version": "4.260429.
|
|
3
|
+
"version": "4.260429.12",
|
|
4
4
|
"description": "Human-AI partnership for Claude Code. Share a terminal, orchestrate workers, evolve together. Brainstorm ideas, turn them into wishes, execute with /work, validate with /review, and ship as one team.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Namastex Labs"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
-- 057_hook_perf_baseline_view_filter_fix.sql — fix #1494 residual
|
|
2
|
+
--
|
|
3
|
+
-- Background: #1492 (the schema fix) accepts the new `event` key emitted by
|
|
4
|
+
-- runHandler post-#1485, so hook.delivery spans now insert into
|
|
5
|
+
-- genie_runtime_events without rejection. But dog-fooder-11eb's verdict
|
|
6
|
+
-- (state/evidence/followups-1490-1491-1493/REPORT.md) flagged a SECOND
|
|
7
|
+
-- bug: the hook_perf_baseline view created by migration 056 filters
|
|
8
|
+
-- `WHERE kind = 'hook.delivery'`, but the actual emitted row carries:
|
|
9
|
+
--
|
|
10
|
+
-- subject = 'hook.delivery' ← what we want to filter on
|
|
11
|
+
-- kind = 'system' ← what the view incorrectly filters on
|
|
12
|
+
-- data->>'_kind' = 'span' ← span marker
|
|
13
|
+
--
|
|
14
|
+
-- Net effect: rows accepted into the table never appear in the view, so
|
|
15
|
+
-- `genie doctor --perf` and `hook_perf_baseline` queries always returned
|
|
16
|
+
-- empty. The hookify-perf-foundation telemetry value (#1485) stayed inert.
|
|
17
|
+
--
|
|
18
|
+
-- Fix: replace the view to filter on `subject='hook.delivery'` AND require
|
|
19
|
+
-- `data->>'_kind' = 'span'` (so we only count completed spans, not other
|
|
20
|
+
-- runtime events that might happen to share the subject).
|
|
21
|
+
|
|
22
|
+
CREATE OR REPLACE VIEW hook_perf_baseline AS
|
|
23
|
+
WITH spans AS (
|
|
24
|
+
SELECT
|
|
25
|
+
COALESCE(data->>'event', '<unknown>') AS event_name,
|
|
26
|
+
COALESCE(data->>'tool', '<none>') AS tool_name,
|
|
27
|
+
COALESCE(data->>'hook_name', '<unknown>') AS handler_name,
|
|
28
|
+
NULLIF(data->>'duration_ms', '')::numeric AS duration_ms,
|
|
29
|
+
created_at
|
|
30
|
+
FROM genie_runtime_events
|
|
31
|
+
WHERE subject = 'hook.delivery'
|
|
32
|
+
AND data->>'_kind' = 'span'
|
|
33
|
+
AND data ? 'duration_ms'
|
|
34
|
+
)
|
|
35
|
+
SELECT
|
|
36
|
+
event_name,
|
|
37
|
+
tool_name,
|
|
38
|
+
handler_name,
|
|
39
|
+
PERCENTILE_CONT(0.5)
|
|
40
|
+
WITHIN GROUP (ORDER BY duration_ms)
|
|
41
|
+
FILTER (WHERE created_at >= now() - interval '1 hour') AS p50_1h,
|
|
42
|
+
PERCENTILE_CONT(0.99)
|
|
43
|
+
WITHIN GROUP (ORDER BY duration_ms)
|
|
44
|
+
FILTER (WHERE created_at >= now() - interval '1 hour') AS p99_1h,
|
|
45
|
+
PERCENTILE_CONT(0.5)
|
|
46
|
+
WITHIN GROUP (ORDER BY duration_ms)
|
|
47
|
+
FILTER (WHERE created_at >= now() - interval '24 hours') AS p50_24h,
|
|
48
|
+
PERCENTILE_CONT(0.99)
|
|
49
|
+
WITHIN GROUP (ORDER BY duration_ms)
|
|
50
|
+
FILTER (WHERE created_at >= now() - interval '24 hours') AS p99_24h,
|
|
51
|
+
PERCENTILE_CONT(0.5)
|
|
52
|
+
WITHIN GROUP (ORDER BY duration_ms)
|
|
53
|
+
FILTER (WHERE created_at >= now() - interval '7 days') AS p50_7d,
|
|
54
|
+
PERCENTILE_CONT(0.99)
|
|
55
|
+
WITHIN GROUP (ORDER BY duration_ms)
|
|
56
|
+
FILTER (WHERE created_at >= now() - interval '7 days') AS p99_7d,
|
|
57
|
+
COUNT(*) FILTER (WHERE created_at >= now() - interval '24 hours')::bigint AS sample_count_24h
|
|
58
|
+
FROM spans
|
|
59
|
+
WHERE duration_ms IS NOT NULL
|
|
60
|
+
GROUP BY event_name, tool_name, handler_name;
|
|
61
|
+
|
|
62
|
+
COMMENT ON VIEW hook_perf_baseline IS
|
|
63
|
+
'Rolling P50/P99 per (event, tool, handler) over 1h/24h/7d windows. Source: hook.delivery spans in genie_runtime_events (filtered by subject + data._kind=span). Fixed in #1494 residual / migration 057 — original migration 056 filtered the wrong column.';
|
|
@@ -48,7 +48,7 @@ describe.skipIf(!DB_AVAILABLE)('hook_perf_baseline view', () => {
|
|
|
48
48
|
test('empty source data → view returns no rows (no error)', async () => {
|
|
49
49
|
const sql = await getConnection();
|
|
50
50
|
// Wipe any rows the migration runner might have left.
|
|
51
|
-
await sql`DELETE FROM genie_runtime_events WHERE kind = 'hook.delivery'`;
|
|
51
|
+
await sql`DELETE FROM genie_runtime_events WHERE subject = 'hook.delivery' OR kind = 'hook.delivery'`;
|
|
52
52
|
const rows = (await sql`SELECT * FROM hook_perf_baseline`) as unknown[];
|
|
53
53
|
expect(rows.length).toBe(0);
|
|
54
54
|
});
|
|
@@ -58,11 +58,12 @@ describe.skipIf(!DB_AVAILABLE)('hook_perf_baseline view', () => {
|
|
|
58
58
|
// Wipe and seed a known distribution: durations 1..101 ms for one
|
|
59
59
|
// (event, tool, handler) tuple. Created 5 minutes ago so they fall
|
|
60
60
|
// inside the 1h, 24h, AND 7d windows.
|
|
61
|
-
await sql`DELETE FROM genie_runtime_events WHERE kind = 'hook.delivery'`;
|
|
61
|
+
await sql`DELETE FROM genie_runtime_events WHERE subject = 'hook.delivery' OR kind = 'hook.delivery'`;
|
|
62
62
|
|
|
63
63
|
const fiveMinAgo = new Date(Date.now() - 5 * 60_000);
|
|
64
64
|
for (let i = 1; i <= 101; i++) {
|
|
65
65
|
const data = sql.json({
|
|
66
|
+
_kind: 'span',
|
|
66
67
|
event: 'PreToolUse',
|
|
67
68
|
tool: 'Bash',
|
|
68
69
|
hook_name: 'branch-guard',
|
|
@@ -70,9 +71,9 @@ describe.skipIf(!DB_AVAILABLE)('hook_perf_baseline view', () => {
|
|
|
70
71
|
});
|
|
71
72
|
await sql`
|
|
72
73
|
INSERT INTO genie_runtime_events
|
|
73
|
-
(repo_path, kind, source, agent, text, data, created_at)
|
|
74
|
+
(repo_path, subject, kind, source, agent, text, data, created_at)
|
|
74
75
|
VALUES
|
|
75
|
-
('test', 'hook.delivery', 'hooks', 'test', '', ${data}, ${fiveMinAgo})
|
|
76
|
+
('test', 'hook.delivery', 'system', 'hooks', 'test', '', ${data}, ${fiveMinAgo})
|
|
76
77
|
`;
|
|
77
78
|
}
|
|
78
79
|
|
|
@@ -120,7 +121,7 @@ describe.skipIf(!DB_AVAILABLE)('hook_perf_baseline view', () => {
|
|
|
120
121
|
|
|
121
122
|
test('rolling windows correctly partition rows by created_at', async () => {
|
|
122
123
|
const sql = await getConnection();
|
|
123
|
-
await sql`DELETE FROM genie_runtime_events WHERE kind = 'hook.delivery'`;
|
|
124
|
+
await sql`DELETE FROM genie_runtime_events WHERE subject = 'hook.delivery' OR kind = 'hook.delivery'`;
|
|
124
125
|
|
|
125
126
|
// Two cohorts:
|
|
126
127
|
// - 50 rows at 30 minutes ago, duration 10ms → falls in 1h, 24h, 7d
|
|
@@ -130,6 +131,7 @@ describe.skipIf(!DB_AVAILABLE)('hook_perf_baseline view', () => {
|
|
|
130
131
|
|
|
131
132
|
for (let i = 0; i < 50; i++) {
|
|
132
133
|
const data = sql.json({
|
|
134
|
+
_kind: 'span',
|
|
133
135
|
event: 'PreToolUse',
|
|
134
136
|
tool: 'Read',
|
|
135
137
|
hook_name: 'freshness',
|
|
@@ -137,13 +139,14 @@ describe.skipIf(!DB_AVAILABLE)('hook_perf_baseline view', () => {
|
|
|
137
139
|
});
|
|
138
140
|
await sql`
|
|
139
141
|
INSERT INTO genie_runtime_events
|
|
140
|
-
(repo_path, kind, source, agent, text, data, created_at)
|
|
142
|
+
(repo_path, subject, kind, source, agent, text, data, created_at)
|
|
141
143
|
VALUES
|
|
142
|
-
('test', 'hook.delivery', 'hooks', 'test', '', ${data}, ${thirtyMinAgo})
|
|
144
|
+
('test', 'hook.delivery', 'system', 'hooks', 'test', '', ${data}, ${thirtyMinAgo})
|
|
143
145
|
`;
|
|
144
146
|
}
|
|
145
147
|
for (let i = 0; i < 50; i++) {
|
|
146
148
|
const data = sql.json({
|
|
149
|
+
_kind: 'span',
|
|
147
150
|
event: 'PreToolUse',
|
|
148
151
|
tool: 'Read',
|
|
149
152
|
hook_name: 'freshness',
|
|
@@ -151,9 +154,9 @@ describe.skipIf(!DB_AVAILABLE)('hook_perf_baseline view', () => {
|
|
|
151
154
|
});
|
|
152
155
|
await sql`
|
|
153
156
|
INSERT INTO genie_runtime_events
|
|
154
|
-
(repo_path, kind, source, agent, text, data, created_at)
|
|
157
|
+
(repo_path, subject, kind, source, agent, text, data, created_at)
|
|
155
158
|
VALUES
|
|
156
|
-
('test', 'hook.delivery', 'hooks', 'test', '', ${data}, ${fiveDaysAgo})
|
|
159
|
+
('test', 'hook.delivery', 'system', 'hooks', 'test', '', ${data}, ${fiveDaysAgo})
|
|
157
160
|
`;
|
|
158
161
|
}
|
|
159
162
|
|
|
@@ -186,27 +189,29 @@ describe.skipIf(!DB_AVAILABLE)('hook_perf_baseline view', () => {
|
|
|
186
189
|
|
|
187
190
|
test('rows missing data.duration_ms are filtered out', async () => {
|
|
188
191
|
const sql = await getConnection();
|
|
189
|
-
await sql`DELETE FROM genie_runtime_events WHERE kind = 'hook.delivery'`;
|
|
192
|
+
await sql`DELETE FROM genie_runtime_events WHERE subject = 'hook.delivery' OR kind = 'hook.delivery'`;
|
|
190
193
|
|
|
191
194
|
// One valid row + one row missing duration_ms.
|
|
192
195
|
const fiveMinAgo = new Date(Date.now() - 5 * 60_000);
|
|
193
196
|
const validData = sql.json({
|
|
197
|
+
_kind: 'span',
|
|
194
198
|
event: 'Stop',
|
|
195
199
|
tool: '<none>',
|
|
196
200
|
hook_name: 'runtime-emit-assistant-response',
|
|
197
201
|
duration_ms: 42,
|
|
198
202
|
});
|
|
199
203
|
const missingDurData = sql.json({
|
|
204
|
+
_kind: 'span',
|
|
200
205
|
event: 'Stop',
|
|
201
206
|
tool: '<none>',
|
|
202
207
|
hook_name: 'runtime-emit-assistant-response',
|
|
203
208
|
});
|
|
204
209
|
await sql`
|
|
205
210
|
INSERT INTO genie_runtime_events
|
|
206
|
-
(repo_path, kind, source, agent, text, data, created_at)
|
|
211
|
+
(repo_path, subject, kind, source, agent, text, data, created_at)
|
|
207
212
|
VALUES
|
|
208
|
-
('test', 'hook.delivery', 'hooks', 'test', '', ${validData}, ${fiveMinAgo}),
|
|
209
|
-
('test', 'hook.delivery', 'hooks', 'test', '', ${missingDurData}, ${fiveMinAgo})
|
|
213
|
+
('test', 'hook.delivery', 'system', 'hooks', 'test', '', ${validData}, ${fiveMinAgo}),
|
|
214
|
+
('test', 'hook.delivery', 'system', 'hooks', 'test', '', ${missingDurData}, ${fiveMinAgo})
|
|
210
215
|
`;
|
|
211
216
|
|
|
212
217
|
const rows = (await sql`
|