@plazmodium/odin 0.3.2-beta
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/README.md +306 -0
- package/dist/adapters/archive/supabase.d.ts +19 -0
- package/dist/adapters/archive/supabase.d.ts.map +1 -0
- package/dist/adapters/archive/supabase.js +121 -0
- package/dist/adapters/archive/supabase.js.map +1 -0
- package/dist/adapters/archive/types.d.ts +26 -0
- package/dist/adapters/archive/types.d.ts.map +1 -0
- package/dist/adapters/archive/types.js +6 -0
- package/dist/adapters/archive/types.js.map +1 -0
- package/dist/adapters/formal-verification/tla-precheck.d.ts +22 -0
- package/dist/adapters/formal-verification/tla-precheck.d.ts.map +1 -0
- package/dist/adapters/formal-verification/tla-precheck.js +270 -0
- package/dist/adapters/formal-verification/tla-precheck.js.map +1 -0
- package/dist/adapters/formal-verification/types.d.ts +37 -0
- package/dist/adapters/formal-verification/types.d.ts.map +1 -0
- package/dist/adapters/formal-verification/types.js +6 -0
- package/dist/adapters/formal-verification/types.js.map +1 -0
- package/dist/adapters/review/semgrep.d.ts +12 -0
- package/dist/adapters/review/semgrep.d.ts.map +1 -0
- package/dist/adapters/review/semgrep.js +175 -0
- package/dist/adapters/review/semgrep.js.map +1 -0
- package/dist/adapters/review/types.d.ts +14 -0
- package/dist/adapters/review/types.d.ts.map +1 -0
- package/dist/adapters/review/types.js +6 -0
- package/dist/adapters/review/types.js.map +1 -0
- package/dist/adapters/skills/filesystem.d.ts +18 -0
- package/dist/adapters/skills/filesystem.d.ts.map +1 -0
- package/dist/adapters/skills/filesystem.js +398 -0
- package/dist/adapters/skills/filesystem.js.map +1 -0
- package/dist/adapters/skills/types.d.ts +19 -0
- package/dist/adapters/skills/types.d.ts.map +1 -0
- package/dist/adapters/skills/types.js +6 -0
- package/dist/adapters/skills/types.js.map +1 -0
- package/dist/adapters/sql-executor/direct-postgres.d.ts +15 -0
- package/dist/adapters/sql-executor/direct-postgres.d.ts.map +1 -0
- package/dist/adapters/sql-executor/direct-postgres.js +33 -0
- package/dist/adapters/sql-executor/direct-postgres.js.map +1 -0
- package/dist/adapters/sql-executor/supabase-management-api.d.ts +17 -0
- package/dist/adapters/sql-executor/supabase-management-api.d.ts.map +1 -0
- package/dist/adapters/sql-executor/supabase-management-api.js +40 -0
- package/dist/adapters/sql-executor/supabase-management-api.js.map +1 -0
- package/dist/adapters/sql-executor/types.d.ts +15 -0
- package/dist/adapters/sql-executor/types.d.ts.map +1 -0
- package/dist/adapters/sql-executor/types.js +6 -0
- package/dist/adapters/sql-executor/types.js.map +1 -0
- package/dist/adapters/workflow-state/in-memory.d.ts +69 -0
- package/dist/adapters/workflow-state/in-memory.d.ts.map +1 -0
- package/dist/adapters/workflow-state/in-memory.js +444 -0
- package/dist/adapters/workflow-state/in-memory.js.map +1 -0
- package/dist/adapters/workflow-state/supabase.d.ts +55 -0
- package/dist/adapters/workflow-state/supabase.d.ts.map +1 -0
- package/dist/adapters/workflow-state/supabase.js +823 -0
- package/dist/adapters/workflow-state/supabase.js.map +1 -0
- package/dist/adapters/workflow-state/types.d.ts +55 -0
- package/dist/adapters/workflow-state/types.d.ts.map +1 -0
- package/dist/adapters/workflow-state/types.js +6 -0
- package/dist/adapters/workflow-state/types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +52 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +115 -0
- package/dist/config.js.map +1 -0
- package/dist/domain/actors.d.ts +10 -0
- package/dist/domain/actors.d.ts.map +1 -0
- package/dist/domain/actors.js +60 -0
- package/dist/domain/actors.js.map +1 -0
- package/dist/domain/development-evals.d.ts +9 -0
- package/dist/domain/development-evals.d.ts.map +1 -0
- package/dist/domain/development-evals.js +164 -0
- package/dist/domain/development-evals.js.map +1 -0
- package/dist/domain/matching.d.ts +8 -0
- package/dist/domain/matching.d.ts.map +1 -0
- package/dist/domain/matching.js +24 -0
- package/dist/domain/matching.js.map +1 -0
- package/dist/domain/phases.d.ts +10 -0
- package/dist/domain/phases.d.ts.map +1 -0
- package/dist/domain/phases.js +165 -0
- package/dist/domain/phases.js.map +1 -0
- package/dist/domain/quality-gates.d.ts +7 -0
- package/dist/domain/quality-gates.d.ts.map +1 -0
- package/dist/domain/quality-gates.js +8 -0
- package/dist/domain/quality-gates.js.map +1 -0
- package/dist/domain/resonance.d.ts +33 -0
- package/dist/domain/resonance.d.ts.map +1 -0
- package/dist/domain/resonance.js +100 -0
- package/dist/domain/resonance.js.map +1 -0
- package/dist/domain/tasks.d.ts +9 -0
- package/dist/domain/tasks.d.ts.map +1 -0
- package/dist/domain/tasks.js +57 -0
- package/dist/domain/tasks.js.map +1 -0
- package/dist/init.d.ts +7 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +387 -0
- package/dist/init.js.map +1 -0
- package/dist/schemas.d.ts +366 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +184 -0
- package/dist/schemas.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +243 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/apply-migrations.d.ts +21 -0
- package/dist/tools/apply-migrations.d.ts.map +1 -0
- package/dist/tools/apply-migrations.js +286 -0
- package/dist/tools/apply-migrations.js.map +1 -0
- package/dist/tools/archive-feature-release.d.ts +13 -0
- package/dist/tools/archive-feature-release.d.ts.map +1 -0
- package/dist/tools/archive-feature-release.js +182 -0
- package/dist/tools/archive-feature-release.js.map +1 -0
- package/dist/tools/capture-learning.d.ts +9 -0
- package/dist/tools/capture-learning.d.ts.map +1 -0
- package/dist/tools/capture-learning.js +53 -0
- package/dist/tools/capture-learning.js.map +1 -0
- package/dist/tools/explore-knowledge.d.ts +9 -0
- package/dist/tools/explore-knowledge.d.ts.map +1 -0
- package/dist/tools/explore-knowledge.js +142 -0
- package/dist/tools/explore-knowledge.js.map +1 -0
- package/dist/tools/get-claims-needing-review.d.ts +8 -0
- package/dist/tools/get-claims-needing-review.d.ts.map +1 -0
- package/dist/tools/get-claims-needing-review.js +21 -0
- package/dist/tools/get-claims-needing-review.js.map +1 -0
- package/dist/tools/get-development-eval-status.d.ts +8 -0
- package/dist/tools/get-development-eval-status.d.ts.map +1 -0
- package/dist/tools/get-development-eval-status.js +49 -0
- package/dist/tools/get-development-eval-status.js.map +1 -0
- package/dist/tools/get-feature-status.d.ts +8 -0
- package/dist/tools/get-feature-status.d.ts.map +1 -0
- package/dist/tools/get-feature-status.js +68 -0
- package/dist/tools/get-feature-status.js.map +1 -0
- package/dist/tools/get-next-phase.d.ts +8 -0
- package/dist/tools/get-next-phase.d.ts.map +1 -0
- package/dist/tools/get-next-phase.js +26 -0
- package/dist/tools/get-next-phase.js.map +1 -0
- package/dist/tools/prepare-phase-context.d.ts +9 -0
- package/dist/tools/prepare-phase-context.d.ts.map +1 -0
- package/dist/tools/prepare-phase-context.js +151 -0
- package/dist/tools/prepare-phase-context.js.map +1 -0
- package/dist/tools/record-commit.d.ts +8 -0
- package/dist/tools/record-commit.d.ts.map +1 -0
- package/dist/tools/record-commit.js +28 -0
- package/dist/tools/record-commit.js.map +1 -0
- package/dist/tools/record-eval-plan.d.ts +8 -0
- package/dist/tools/record-eval-plan.d.ts.map +1 -0
- package/dist/tools/record-eval-plan.js +40 -0
- package/dist/tools/record-eval-plan.js.map +1 -0
- package/dist/tools/record-eval-run.d.ts +8 -0
- package/dist/tools/record-eval-run.d.ts.map +1 -0
- package/dist/tools/record-eval-run.js +42 -0
- package/dist/tools/record-eval-run.js.map +1 -0
- package/dist/tools/record-merge.d.ts +8 -0
- package/dist/tools/record-merge.d.ts.map +1 -0
- package/dist/tools/record-merge.js +16 -0
- package/dist/tools/record-merge.js.map +1 -0
- package/dist/tools/record-phase-artifact.d.ts +8 -0
- package/dist/tools/record-phase-artifact.d.ts.map +1 -0
- package/dist/tools/record-phase-artifact.js +26 -0
- package/dist/tools/record-phase-artifact.js.map +1 -0
- package/dist/tools/record-phase-result.d.ts +9 -0
- package/dist/tools/record-phase-result.d.ts.map +1 -0
- package/dist/tools/record-phase-result.js +122 -0
- package/dist/tools/record-phase-result.js.map +1 -0
- package/dist/tools/record-pull-request.d.ts +8 -0
- package/dist/tools/record-pull-request.d.ts.map +1 -0
- package/dist/tools/record-pull-request.js +16 -0
- package/dist/tools/record-pull-request.js.map +1 -0
- package/dist/tools/record-quality-gate.d.ts +8 -0
- package/dist/tools/record-quality-gate.d.ts.map +1 -0
- package/dist/tools/record-quality-gate.js +26 -0
- package/dist/tools/record-quality-gate.js.map +1 -0
- package/dist/tools/record-watcher-review.d.ts +8 -0
- package/dist/tools/record-watcher-review.d.ts.map +1 -0
- package/dist/tools/record-watcher-review.js +18 -0
- package/dist/tools/record-watcher-review.js.map +1 -0
- package/dist/tools/run-policy-checks.d.ts +8 -0
- package/dist/tools/run-policy-checks.d.ts.map +1 -0
- package/dist/tools/run-policy-checks.js +38 -0
- package/dist/tools/run-policy-checks.js.map +1 -0
- package/dist/tools/run-review-checks.d.ts +9 -0
- package/dist/tools/run-review-checks.d.ts.map +1 -0
- package/dist/tools/run-review-checks.js +45 -0
- package/dist/tools/run-review-checks.js.map +1 -0
- package/dist/tools/start-feature.d.ts +8 -0
- package/dist/tools/start-feature.d.ts.map +1 -0
- package/dist/tools/start-feature.js +33 -0
- package/dist/tools/start-feature.js.map +1 -0
- package/dist/tools/submit-claim.d.ts +8 -0
- package/dist/tools/submit-claim.d.ts.map +1 -0
- package/dist/tools/submit-claim.js +45 -0
- package/dist/tools/submit-claim.js.map +1 -0
- package/dist/tools/verify-claims.d.ts +8 -0
- package/dist/tools/verify-claims.d.ts.map +1 -0
- package/dist/tools/verify-claims.js +39 -0
- package/dist/tools/verify-claims.js.map +1 -0
- package/dist/tools/verify-design.d.ts +8 -0
- package/dist/tools/verify-design.d.ts.map +1 -0
- package/dist/tools/verify-design.js +31 -0
- package/dist/tools/verify-design.js.map +1 -0
- package/dist/types.d.ts +333 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +52 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +24 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +50 -0
- package/dist/utils.js.map +1 -0
- package/migrations/001_schema.sql +795 -0
- package/migrations/002_functions.sql +2126 -0
- package/migrations/003_views.sql +599 -0
- package/migrations/004_seed.sql +106 -0
- package/migrations/005_odin_v2_schema.sql +217 -0
- package/migrations/006_odin_v2_functions.sql +671 -0
- package/migrations/007_odin_v2_phase_alignment.sql +554 -0
- package/migrations/008_related_learnings.sql +80 -0
- package/migrations/README.md +23 -0
- package/package.json +63 -0
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- Odin SDD Framework - Consolidated Views
|
|
3
|
+
-- Version: 1.1.0
|
|
4
|
+
-- Created: 2026-02-16
|
|
5
|
+
-- Updated: 2026-02-16 (reconciled with live Supabase DB)
|
|
6
|
+
-- Description: All database views for Odin. Run after 002_functions.sql.
|
|
7
|
+
-- All views use security_invoker = true to prevent SECURITY DEFINER bypasses.
|
|
8
|
+
-- ============================================================================
|
|
9
|
+
|
|
10
|
+
-- ============================================================================
|
|
11
|
+
-- FEATURE VIEWS
|
|
12
|
+
-- ============================================================================
|
|
13
|
+
|
|
14
|
+
-- Active features with duration tracking
|
|
15
|
+
CREATE OR REPLACE VIEW v_active_features WITH (security_invoker = true) AS
|
|
16
|
+
SELECT
|
|
17
|
+
f.id,
|
|
18
|
+
f.name,
|
|
19
|
+
f.complexity_level,
|
|
20
|
+
f.severity,
|
|
21
|
+
f.current_phase,
|
|
22
|
+
f.status,
|
|
23
|
+
f.epic_id,
|
|
24
|
+
f.parent_feature_id,
|
|
25
|
+
f.created_at,
|
|
26
|
+
f.updated_at,
|
|
27
|
+
f.completed_at,
|
|
28
|
+
f.requirements_path,
|
|
29
|
+
f.spec_path,
|
|
30
|
+
f.assigned_agent,
|
|
31
|
+
COUNT(DISTINCT pt.id) AS phase_transition_count,
|
|
32
|
+
COUNT(DISTINCT b.id) FILTER (WHERE b.status = 'OPEN') AS open_blockers,
|
|
33
|
+
COALESCE(SUM(ai.duration_ms) FILTER (WHERE ai.ended_at IS NOT NULL), 0) AS total_duration_ms,
|
|
34
|
+
COUNT(DISTINCT ai.id) AS invocation_count,
|
|
35
|
+
MAX(COALESCE(ai.ended_at, ai.started_at)) AS last_activity
|
|
36
|
+
FROM features f
|
|
37
|
+
LEFT JOIN phase_transitions pt ON f.id = pt.feature_id
|
|
38
|
+
LEFT JOIN blockers b ON f.id = b.feature_id
|
|
39
|
+
LEFT JOIN agent_invocations ai ON f.id = ai.feature_id
|
|
40
|
+
WHERE f.status = 'IN_PROGRESS'
|
|
41
|
+
GROUP BY f.id;
|
|
42
|
+
|
|
43
|
+
COMMENT ON VIEW v_active_features IS 'Active features with aggregated metrics';
|
|
44
|
+
|
|
45
|
+
-- All features summary with health scores (matches live DB column names)
|
|
46
|
+
CREATE OR REPLACE VIEW all_features_summary WITH (security_invoker = true) AS
|
|
47
|
+
SELECT
|
|
48
|
+
f.id AS feature_id,
|
|
49
|
+
f.name AS feature_name,
|
|
50
|
+
f.status AS feature_status,
|
|
51
|
+
f.current_phase,
|
|
52
|
+
f.complexity_level,
|
|
53
|
+
f.severity,
|
|
54
|
+
f.created_at,
|
|
55
|
+
f.completed_at,
|
|
56
|
+
f.branch_name,
|
|
57
|
+
f.pr_url,
|
|
58
|
+
f.pr_number,
|
|
59
|
+
f.merged_at,
|
|
60
|
+
f.author,
|
|
61
|
+
e.computed_at AS last_eval_at,
|
|
62
|
+
e.overall_score,
|
|
63
|
+
e.health_status,
|
|
64
|
+
e.efficiency_score,
|
|
65
|
+
e.quality_score,
|
|
66
|
+
COALESCE(
|
|
67
|
+
(SELECT sum(ai.duration_ms) FROM agent_invocations ai WHERE ai.feature_id = f.id AND ai.ended_at IS NOT NULL),
|
|
68
|
+
0
|
|
69
|
+
)::BIGINT AS total_duration_ms,
|
|
70
|
+
(SELECT count(*) FROM eval_alerts a WHERE a.feature_id = f.id AND a.resolved_at IS NULL) AS active_alerts
|
|
71
|
+
FROM features f
|
|
72
|
+
LEFT JOIN LATERAL (
|
|
73
|
+
SELECT fe.computed_at, fe.overall_score, fe.health_status, fe.efficiency_score, fe.quality_score
|
|
74
|
+
FROM feature_evals fe
|
|
75
|
+
WHERE fe.feature_id = f.id
|
|
76
|
+
ORDER BY fe.computed_at DESC
|
|
77
|
+
LIMIT 1
|
|
78
|
+
) e ON true
|
|
79
|
+
ORDER BY
|
|
80
|
+
CASE f.status
|
|
81
|
+
WHEN 'IN_PROGRESS' THEN 0
|
|
82
|
+
WHEN 'BLOCKED' THEN 1
|
|
83
|
+
WHEN 'COMPLETED' THEN 2
|
|
84
|
+
WHEN 'CANCELLED' THEN 3
|
|
85
|
+
END,
|
|
86
|
+
f.created_at DESC;
|
|
87
|
+
|
|
88
|
+
COMMENT ON VIEW all_features_summary IS 'Summary of all features with latest health scores';
|
|
89
|
+
|
|
90
|
+
-- Feature health overview (for dashboard)
|
|
91
|
+
CREATE OR REPLACE VIEW feature_health_overview WITH (security_invoker = true) AS
|
|
92
|
+
SELECT
|
|
93
|
+
f.id AS feature_id,
|
|
94
|
+
f.name AS feature_name,
|
|
95
|
+
f.status AS feature_status,
|
|
96
|
+
f.current_phase,
|
|
97
|
+
f.complexity_level,
|
|
98
|
+
e.computed_at AS last_eval_at,
|
|
99
|
+
e.overall_score,
|
|
100
|
+
e.health_status,
|
|
101
|
+
e.efficiency_score,
|
|
102
|
+
e.quality_score,
|
|
103
|
+
COALESCE((SELECT SUM(ai.duration_ms) FROM agent_invocations ai WHERE ai.feature_id = f.id AND ai.ended_at IS NOT NULL), 0) AS total_duration_ms,
|
|
104
|
+
(SELECT COUNT(*) FROM eval_alerts a WHERE a.feature_id = f.id AND a.resolved_at IS NULL) AS active_alerts
|
|
105
|
+
FROM features f
|
|
106
|
+
LEFT JOIN LATERAL (
|
|
107
|
+
SELECT fe.* FROM feature_evals fe
|
|
108
|
+
WHERE fe.feature_id = f.id
|
|
109
|
+
ORDER BY fe.computed_at DESC LIMIT 1
|
|
110
|
+
) e ON true
|
|
111
|
+
WHERE f.status IN ('IN_PROGRESS', 'BLOCKED')
|
|
112
|
+
ORDER BY
|
|
113
|
+
CASE
|
|
114
|
+
WHEN e.health_status = 'CRITICAL' THEN 0
|
|
115
|
+
WHEN e.health_status = 'CONCERNING' THEN 1
|
|
116
|
+
ELSE 2
|
|
117
|
+
END,
|
|
118
|
+
f.updated_at DESC;
|
|
119
|
+
|
|
120
|
+
COMMENT ON VIEW feature_health_overview IS 'Feature health overview prioritized by health status';
|
|
121
|
+
|
|
122
|
+
-- Pending quality gates
|
|
123
|
+
CREATE OR REPLACE VIEW v_pending_gates WITH (security_invoker = true) AS
|
|
124
|
+
SELECT
|
|
125
|
+
qg.id,
|
|
126
|
+
qg.feature_id,
|
|
127
|
+
qg.gate_name,
|
|
128
|
+
qg.phase,
|
|
129
|
+
qg.status,
|
|
130
|
+
qg.approver,
|
|
131
|
+
qg.approved_at,
|
|
132
|
+
qg.approval_notes,
|
|
133
|
+
qg.decision_log,
|
|
134
|
+
f.name AS feature_name,
|
|
135
|
+
f.complexity_level,
|
|
136
|
+
f.assigned_agent
|
|
137
|
+
FROM quality_gates qg
|
|
138
|
+
JOIN features f ON qg.feature_id = f.id
|
|
139
|
+
WHERE qg.status = 'PENDING';
|
|
140
|
+
|
|
141
|
+
COMMENT ON VIEW v_pending_gates IS 'Quality gates awaiting approval';
|
|
142
|
+
|
|
143
|
+
-- ============================================================================
|
|
144
|
+
-- LEARNING VIEWS
|
|
145
|
+
-- ============================================================================
|
|
146
|
+
|
|
147
|
+
-- Active learnings with propagation status (derived from relational tables)
|
|
148
|
+
CREATE OR REPLACE VIEW active_learnings WITH (security_invoker = true) AS
|
|
149
|
+
SELECT
|
|
150
|
+
l.id,
|
|
151
|
+
l.predecessor_id,
|
|
152
|
+
l.iteration_number,
|
|
153
|
+
l.feature_id,
|
|
154
|
+
f.name AS feature_name,
|
|
155
|
+
l.task_id,
|
|
156
|
+
l.category,
|
|
157
|
+
l.title,
|
|
158
|
+
l.content,
|
|
159
|
+
l.delta_summary,
|
|
160
|
+
l.confidence_score,
|
|
161
|
+
l.validation_count,
|
|
162
|
+
l.last_validated_at,
|
|
163
|
+
l.importance,
|
|
164
|
+
l.tags,
|
|
165
|
+
l.phase,
|
|
166
|
+
l.agent,
|
|
167
|
+
l.created_at,
|
|
168
|
+
l.updated_at,
|
|
169
|
+
l.created_by,
|
|
170
|
+
-- Derive is_propagated from relational tables
|
|
171
|
+
CASE
|
|
172
|
+
WHEN prop_stats.total_targets > 0 AND prop_stats.propagated_count = prop_stats.total_targets THEN true
|
|
173
|
+
ELSE false
|
|
174
|
+
END AS is_propagated,
|
|
175
|
+
-- Keep propagated_to for backward compat
|
|
176
|
+
l.propagated_to,
|
|
177
|
+
l.propagated_at,
|
|
178
|
+
-- Derive ready_for_propagation from relational tables
|
|
179
|
+
CASE
|
|
180
|
+
WHEN l.confidence_score >= 0.80
|
|
181
|
+
AND prop_stats.total_targets > 0
|
|
182
|
+
AND prop_stats.propagated_count < prop_stats.total_targets THEN true
|
|
183
|
+
ELSE false
|
|
184
|
+
END AS ready_for_propagation,
|
|
185
|
+
(EXISTS (
|
|
186
|
+
SELECT 1 FROM learnings s WHERE s.predecessor_id = l.id
|
|
187
|
+
)) AS has_successors,
|
|
188
|
+
-- Propagation status for badges
|
|
189
|
+
COALESCE(prop_stats.propagation_status, 'no_targets') AS propagation_status,
|
|
190
|
+
COALESCE(prop_stats.total_targets, 0) AS total_targets,
|
|
191
|
+
COALESCE(prop_stats.propagated_count, 0) AS propagated_count
|
|
192
|
+
FROM learnings l
|
|
193
|
+
LEFT JOIN features f ON l.feature_id = f.id
|
|
194
|
+
LEFT JOIN LATERAL (
|
|
195
|
+
SELECT
|
|
196
|
+
count(lpt.id)::integer AS total_targets,
|
|
197
|
+
count(lp.id)::integer AS propagated_count,
|
|
198
|
+
CASE
|
|
199
|
+
WHEN count(lpt.id) = 0 THEN 'no_targets'
|
|
200
|
+
WHEN count(lp.id) = count(lpt.id) THEN 'complete'
|
|
201
|
+
WHEN count(lp.id) > 0 THEN 'partial'
|
|
202
|
+
ELSE 'pending'
|
|
203
|
+
END AS propagation_status
|
|
204
|
+
FROM learning_propagation_targets lpt
|
|
205
|
+
LEFT JOIN learning_propagations lp
|
|
206
|
+
ON lpt.learning_id = lp.learning_id
|
|
207
|
+
AND lpt.target_type = lp.target_type
|
|
208
|
+
AND NOT lpt.target_path IS DISTINCT FROM lp.target_path
|
|
209
|
+
WHERE lpt.learning_id = l.id
|
|
210
|
+
) prop_stats ON true
|
|
211
|
+
WHERE NOT l.is_superseded;
|
|
212
|
+
|
|
213
|
+
COMMENT ON VIEW active_learnings IS 'Active (non-superseded) learnings with propagation status';
|
|
214
|
+
|
|
215
|
+
-- Propagation queue (learnings ready for propagation — matches live DB)
|
|
216
|
+
CREATE OR REPLACE VIEW propagation_queue WITH (security_invoker = true) AS
|
|
217
|
+
SELECT
|
|
218
|
+
l.id,
|
|
219
|
+
l.category,
|
|
220
|
+
l.title,
|
|
221
|
+
l.content,
|
|
222
|
+
l.confidence_score,
|
|
223
|
+
l.validation_count,
|
|
224
|
+
l.importance,
|
|
225
|
+
l.feature_id,
|
|
226
|
+
f.name AS feature_name,
|
|
227
|
+
l.tags,
|
|
228
|
+
l.created_at,
|
|
229
|
+
l.created_by,
|
|
230
|
+
CASE
|
|
231
|
+
WHEN l.propagation_summary IS NOT NULL THEN l.propagation_summary
|
|
232
|
+
ELSE left(l.content, 200) ||
|
|
233
|
+
CASE WHEN length(l.content) > 200 THEN '...' ELSE '' END
|
|
234
|
+
END AS suggested_summary
|
|
235
|
+
FROM learnings l
|
|
236
|
+
LEFT JOIN features f ON l.feature_id = f.id
|
|
237
|
+
WHERE l.confidence_score >= 0.80
|
|
238
|
+
AND array_length(l.propagated_to, 1) IS NULL
|
|
239
|
+
AND NOT l.is_superseded
|
|
240
|
+
ORDER BY l.confidence_score DESC, l.importance DESC;
|
|
241
|
+
|
|
242
|
+
COMMENT ON VIEW propagation_queue IS 'Learnings eligible for propagation (confidence >= 0.80)';
|
|
243
|
+
|
|
244
|
+
-- Skill propagation queue
|
|
245
|
+
CREATE OR REPLACE VIEW skill_propagation_queue WITH (security_invoker = true) AS
|
|
246
|
+
SELECT
|
|
247
|
+
l.id AS learning_id,
|
|
248
|
+
l.title,
|
|
249
|
+
l.category,
|
|
250
|
+
l.content,
|
|
251
|
+
l.confidence_score,
|
|
252
|
+
l.feature_id,
|
|
253
|
+
lpt.target_type,
|
|
254
|
+
lpt.target_path,
|
|
255
|
+
lpt.relevance_score
|
|
256
|
+
FROM learnings l
|
|
257
|
+
JOIN learning_propagation_targets lpt ON l.id = lpt.learning_id
|
|
258
|
+
LEFT JOIN learning_propagations lp
|
|
259
|
+
ON lpt.learning_id = lp.learning_id
|
|
260
|
+
AND lpt.target_type = lp.target_type
|
|
261
|
+
AND lpt.target_path IS NOT DISTINCT FROM lp.target_path
|
|
262
|
+
WHERE l.confidence_score >= 0.80
|
|
263
|
+
AND NOT l.is_superseded
|
|
264
|
+
AND lpt.relevance_score >= 0.60
|
|
265
|
+
AND lp.id IS NULL
|
|
266
|
+
AND NOT EXISTS (
|
|
267
|
+
SELECT 1 FROM learning_conflicts lc
|
|
268
|
+
WHERE (lc.learning_a_id = l.id OR lc.learning_b_id = l.id)
|
|
269
|
+
AND lc.status = 'OPEN'
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
COMMENT ON VIEW skill_propagation_queue IS 'Learnings with unpropagated skill targets';
|
|
273
|
+
|
|
274
|
+
-- Learning propagation overview
|
|
275
|
+
CREATE OR REPLACE VIEW learning_propagation_overview WITH (security_invoker = true) AS
|
|
276
|
+
SELECT
|
|
277
|
+
l.id AS learning_id,
|
|
278
|
+
l.title,
|
|
279
|
+
l.category,
|
|
280
|
+
l.confidence_score,
|
|
281
|
+
l.feature_id,
|
|
282
|
+
COUNT(lpt.id)::INTEGER AS total_targets,
|
|
283
|
+
COUNT(lp.id)::INTEGER AS propagated_count,
|
|
284
|
+
(COUNT(lpt.id) - COUNT(lp.id))::INTEGER AS pending_count,
|
|
285
|
+
CASE
|
|
286
|
+
WHEN COUNT(lpt.id) = 0 THEN 'no_targets'
|
|
287
|
+
WHEN COUNT(lp.id) = COUNT(lpt.id) THEN 'complete'
|
|
288
|
+
WHEN COUNT(lp.id) > 0 THEN 'partial'
|
|
289
|
+
ELSE 'pending'
|
|
290
|
+
END AS propagation_status
|
|
291
|
+
FROM learnings l
|
|
292
|
+
LEFT JOIN learning_propagation_targets lpt ON l.id = lpt.learning_id
|
|
293
|
+
LEFT JOIN learning_propagations lp
|
|
294
|
+
ON lpt.learning_id = lp.learning_id
|
|
295
|
+
AND lpt.target_type = lp.target_type
|
|
296
|
+
AND lpt.target_path IS NOT DISTINCT FROM lp.target_path
|
|
297
|
+
WHERE NOT l.is_superseded
|
|
298
|
+
GROUP BY l.id, l.title, l.category, l.confidence_score, l.feature_id;
|
|
299
|
+
|
|
300
|
+
COMMENT ON VIEW learning_propagation_overview IS 'Propagation status summary per learning';
|
|
301
|
+
|
|
302
|
+
-- Open learning conflicts (matches live DB with extra columns)
|
|
303
|
+
CREATE OR REPLACE VIEW open_learning_conflicts WITH (security_invoker = true) AS
|
|
304
|
+
SELECT
|
|
305
|
+
c.id,
|
|
306
|
+
c.conflict_type,
|
|
307
|
+
c.description,
|
|
308
|
+
c.status,
|
|
309
|
+
c.detected_at,
|
|
310
|
+
c.detected_by,
|
|
311
|
+
c.learning_a_id,
|
|
312
|
+
la.title AS learning_a_title,
|
|
313
|
+
la.category AS learning_a_category,
|
|
314
|
+
la.confidence_score AS learning_a_confidence,
|
|
315
|
+
la.feature_id AS learning_a_feature_id,
|
|
316
|
+
c.learning_b_id,
|
|
317
|
+
lb.title AS learning_b_title,
|
|
318
|
+
lb.category AS learning_b_category,
|
|
319
|
+
lb.confidence_score AS learning_b_confidence,
|
|
320
|
+
lb.feature_id AS learning_b_feature_id,
|
|
321
|
+
EXTRACT(EPOCH FROM (now() - c.detected_at)) / 3600 AS hours_open
|
|
322
|
+
FROM learning_conflicts c
|
|
323
|
+
JOIN learnings la ON c.learning_a_id = la.id
|
|
324
|
+
JOIN learnings lb ON c.learning_b_id = lb.id
|
|
325
|
+
WHERE c.status IN ('OPEN', 'INVESTIGATING')
|
|
326
|
+
ORDER BY c.detected_at;
|
|
327
|
+
|
|
328
|
+
COMMENT ON VIEW open_learning_conflicts IS 'Open learning conflicts requiring resolution';
|
|
329
|
+
|
|
330
|
+
-- Feature learning summary (matches live DB with extra columns)
|
|
331
|
+
CREATE OR REPLACE VIEW feature_learning_summary WITH (security_invoker = true) AS
|
|
332
|
+
SELECT
|
|
333
|
+
f.id AS feature_id,
|
|
334
|
+
f.name AS feature_name,
|
|
335
|
+
f.status AS feature_status,
|
|
336
|
+
COUNT(l.id) AS total_learnings,
|
|
337
|
+
COUNT(l.id) FILTER (WHERE NOT l.is_superseded) AS active_learnings,
|
|
338
|
+
COUNT(l.id) FILTER (WHERE l.confidence_score >= 0.80) AS high_confidence_learnings,
|
|
339
|
+
COUNT(l.id) FILTER (WHERE array_length(l.propagated_to, 1) > 0) AS propagated_learnings,
|
|
340
|
+
AVG(l.confidence_score) FILTER (WHERE NOT l.is_superseded) AS avg_confidence,
|
|
341
|
+
MAX(l.created_at) AS last_learning_at,
|
|
342
|
+
array_agg(DISTINCT l.category) FILTER (WHERE NOT l.is_superseded) AS categories_covered
|
|
343
|
+
FROM features f
|
|
344
|
+
LEFT JOIN learnings l ON l.feature_id = f.id
|
|
345
|
+
GROUP BY f.id, f.name, f.status;
|
|
346
|
+
|
|
347
|
+
COMMENT ON VIEW feature_learning_summary IS 'Learning statistics per feature';
|
|
348
|
+
|
|
349
|
+
-- Learning chain summary (evolution chains)
|
|
350
|
+
CREATE OR REPLACE VIEW learning_chain_summary WITH (security_invoker = true) AS
|
|
351
|
+
WITH chain_stats AS (
|
|
352
|
+
SELECT
|
|
353
|
+
(WITH RECURSIVE find_root AS (
|
|
354
|
+
SELECT l.id, l.predecessor_id, l.id AS current
|
|
355
|
+
FROM learnings l WHERE l.id = outer_l.id
|
|
356
|
+
UNION ALL
|
|
357
|
+
SELECT fr.id, p.predecessor_id, p.id
|
|
358
|
+
FROM find_root fr JOIN learnings p ON fr.predecessor_id = p.id
|
|
359
|
+
)
|
|
360
|
+
SELECT find_root.current FROM find_root WHERE find_root.predecessor_id IS NULL LIMIT 1
|
|
361
|
+
) AS chain_root_id,
|
|
362
|
+
outer_l.id,
|
|
363
|
+
outer_l.iteration_number,
|
|
364
|
+
outer_l.is_superseded,
|
|
365
|
+
outer_l.confidence_score,
|
|
366
|
+
outer_l.title,
|
|
367
|
+
outer_l.created_at
|
|
368
|
+
FROM learnings outer_l
|
|
369
|
+
)
|
|
370
|
+
SELECT
|
|
371
|
+
chain_root_id,
|
|
372
|
+
count(*) AS chain_length,
|
|
373
|
+
max(iteration_number) AS latest_iteration,
|
|
374
|
+
max(confidence_score) FILTER (WHERE NOT is_superseded) AS current_confidence,
|
|
375
|
+
(SELECT learnings.title FROM learnings WHERE learnings.id = chain_stats.chain_root_id) AS original_title,
|
|
376
|
+
(SELECT cs2.id FROM chain_stats cs2
|
|
377
|
+
WHERE cs2.chain_root_id = chain_stats.chain_root_id AND NOT cs2.is_superseded
|
|
378
|
+
ORDER BY cs2.iteration_number DESC LIMIT 1) AS current_learning_id,
|
|
379
|
+
min(created_at) AS chain_started_at,
|
|
380
|
+
max(created_at) AS last_evolved_at
|
|
381
|
+
FROM chain_stats
|
|
382
|
+
WHERE chain_root_id IS NOT NULL
|
|
383
|
+
GROUP BY chain_root_id;
|
|
384
|
+
|
|
385
|
+
COMMENT ON VIEW learning_chain_summary IS 'Summary of learning evolution chains';
|
|
386
|
+
|
|
387
|
+
-- ============================================================================
|
|
388
|
+
-- EVALS VIEWS
|
|
389
|
+
-- ============================================================================
|
|
390
|
+
|
|
391
|
+
-- Active eval alerts (matches live DB with extra columns)
|
|
392
|
+
CREATE OR REPLACE VIEW active_eval_alerts WITH (security_invoker = true) AS
|
|
393
|
+
SELECT
|
|
394
|
+
a.id,
|
|
395
|
+
a.severity,
|
|
396
|
+
a.dimension,
|
|
397
|
+
a.message,
|
|
398
|
+
a.current_value,
|
|
399
|
+
a.threshold,
|
|
400
|
+
a.source_type,
|
|
401
|
+
a.feature_id,
|
|
402
|
+
f.name AS feature_name,
|
|
403
|
+
a.created_at,
|
|
404
|
+
EXTRACT(EPOCH FROM (now() - a.created_at)) / 3600 AS hours_active,
|
|
405
|
+
(a.acknowledged_at IS NOT NULL) AS is_acknowledged,
|
|
406
|
+
a.acknowledged_by
|
|
407
|
+
FROM eval_alerts a
|
|
408
|
+
LEFT JOIN features f ON a.feature_id = f.id
|
|
409
|
+
WHERE a.resolved_at IS NULL
|
|
410
|
+
ORDER BY
|
|
411
|
+
CASE a.severity WHEN 'CRITICAL' THEN 0 ELSE 1 END,
|
|
412
|
+
a.created_at DESC;
|
|
413
|
+
|
|
414
|
+
COMMENT ON VIEW active_eval_alerts IS 'Unresolved evaluation alerts';
|
|
415
|
+
|
|
416
|
+
-- Latest system health per period
|
|
417
|
+
CREATE OR REPLACE VIEW latest_system_health WITH (security_invoker = true) AS
|
|
418
|
+
SELECT DISTINCT ON (period_days)
|
|
419
|
+
id,
|
|
420
|
+
computed_at,
|
|
421
|
+
period_days,
|
|
422
|
+
overall_health_score,
|
|
423
|
+
health_status,
|
|
424
|
+
workflow_metrics,
|
|
425
|
+
quality_metrics,
|
|
426
|
+
learning_metrics,
|
|
427
|
+
alerts
|
|
428
|
+
FROM system_health_evals
|
|
429
|
+
ORDER BY period_days, computed_at DESC;
|
|
430
|
+
|
|
431
|
+
COMMENT ON VIEW latest_system_health IS 'Most recent system health eval per time period';
|
|
432
|
+
|
|
433
|
+
-- ============================================================================
|
|
434
|
+
-- BATCH EXECUTION VIEWS
|
|
435
|
+
-- ============================================================================
|
|
436
|
+
|
|
437
|
+
-- Batch execution stats (last 30 days)
|
|
438
|
+
CREATE OR REPLACE VIEW batch_execution_stats WITH (security_invoker = true) AS
|
|
439
|
+
SELECT
|
|
440
|
+
COALESCE(template_used, 'custom') AS template,
|
|
441
|
+
COUNT(*) AS total_executions,
|
|
442
|
+
COUNT(*) FILTER (WHERE success) AS successful,
|
|
443
|
+
COUNT(*) FILTER (WHERE NOT success) AS failed,
|
|
444
|
+
ROUND(AVG(duration_ms), 0) AS avg_duration_ms,
|
|
445
|
+
MAX(executed_at) AS last_execution
|
|
446
|
+
FROM batch_executions
|
|
447
|
+
WHERE executed_at >= now() - INTERVAL '30 days'
|
|
448
|
+
GROUP BY COALESCE(template_used, 'custom')
|
|
449
|
+
ORDER BY COUNT(*) DESC;
|
|
450
|
+
|
|
451
|
+
COMMENT ON VIEW batch_execution_stats IS 'Batch execution statistics by template (30 day window)';
|
|
452
|
+
|
|
453
|
+
-- ============================================================================
|
|
454
|
+
-- MEMORY VIEWS
|
|
455
|
+
-- ============================================================================
|
|
456
|
+
|
|
457
|
+
-- Recent memories (last 30 days)
|
|
458
|
+
CREATE OR REPLACE VIEW v_recent_memories WITH (security_invoker = true) AS
|
|
459
|
+
SELECT id, feature_id, category, importance, title, content, rationale, tags, phase, agent, created_at, created_by
|
|
460
|
+
FROM memories
|
|
461
|
+
WHERE is_archived = false AND created_at > now() - INTERVAL '30 days'
|
|
462
|
+
ORDER BY created_at DESC;
|
|
463
|
+
|
|
464
|
+
COMMENT ON VIEW v_recent_memories IS 'Memories created in the last 30 days';
|
|
465
|
+
|
|
466
|
+
-- Critical memories (HIGH importance)
|
|
467
|
+
CREATE OR REPLACE VIEW v_critical_memories WITH (security_invoker = true) AS
|
|
468
|
+
SELECT id, feature_id, category, importance, title, content, rationale, tags, phase, agent, created_at, created_by
|
|
469
|
+
FROM memories
|
|
470
|
+
WHERE is_archived = false AND importance = 'HIGH'
|
|
471
|
+
ORDER BY created_at DESC;
|
|
472
|
+
|
|
473
|
+
COMMENT ON VIEW v_critical_memories IS 'High-importance memories';
|
|
474
|
+
|
|
475
|
+
-- Global memories (not tied to a feature)
|
|
476
|
+
CREATE OR REPLACE VIEW v_global_memories WITH (security_invoker = true) AS
|
|
477
|
+
SELECT id, category, importance, title, content, rationale, tags, phase, agent, created_at, created_by
|
|
478
|
+
FROM memories
|
|
479
|
+
WHERE is_archived = false AND feature_id IS NULL
|
|
480
|
+
ORDER BY importance DESC, created_at DESC;
|
|
481
|
+
|
|
482
|
+
COMMENT ON VIEW v_global_memories IS 'Global memories not tied to any feature';
|
|
483
|
+
|
|
484
|
+
-- Gotchas
|
|
485
|
+
CREATE OR REPLACE VIEW v_gotchas WITH (security_invoker = true) AS
|
|
486
|
+
SELECT id, feature_id, importance, title, content, rationale, tags, created_at
|
|
487
|
+
FROM memories
|
|
488
|
+
WHERE is_archived = false AND category = 'GOTCHA'
|
|
489
|
+
ORDER BY importance DESC, created_at DESC;
|
|
490
|
+
|
|
491
|
+
COMMENT ON VIEW v_gotchas IS 'All gotcha memories';
|
|
492
|
+
|
|
493
|
+
-- Architecture timeline
|
|
494
|
+
CREATE OR REPLACE VIEW v_architecture_timeline WITH (security_invoker = true) AS
|
|
495
|
+
SELECT id, feature_id, category, importance, title, content, rationale, tags, created_at, created_by
|
|
496
|
+
FROM memories
|
|
497
|
+
WHERE is_archived = false AND category IN ('ARCHITECTURE', 'DECISION')
|
|
498
|
+
ORDER BY created_at DESC;
|
|
499
|
+
|
|
500
|
+
COMMENT ON VIEW v_architecture_timeline IS 'Architecture decisions and patterns timeline';
|
|
501
|
+
|
|
502
|
+
-- Feature memory stats
|
|
503
|
+
CREATE OR REPLACE VIEW v_feature_memory_stats WITH (security_invoker = true) AS
|
|
504
|
+
SELECT
|
|
505
|
+
feature_id,
|
|
506
|
+
count(*) AS total_memories,
|
|
507
|
+
count(*) FILTER (WHERE importance = 'HIGH') AS high_importance,
|
|
508
|
+
count(*) FILTER (WHERE category = 'DECISION') AS decisions,
|
|
509
|
+
count(*) FILTER (WHERE category = 'GOTCHA') AS gotchas,
|
|
510
|
+
count(*) FILTER (WHERE category = 'PATTERN') AS patterns,
|
|
511
|
+
count(*) FILTER (WHERE category = 'ARCHITECTURE') AS architecture,
|
|
512
|
+
count(*) FILTER (WHERE category = 'BLOCKER') AS blockers,
|
|
513
|
+
max(created_at) AS last_memory_at
|
|
514
|
+
FROM memories
|
|
515
|
+
WHERE is_archived = false AND feature_id IS NOT NULL
|
|
516
|
+
GROUP BY feature_id;
|
|
517
|
+
|
|
518
|
+
COMMENT ON VIEW v_feature_memory_stats IS 'Memory statistics per feature';
|
|
519
|
+
|
|
520
|
+
-- ============================================================================
|
|
521
|
+
-- ARCHIVE VIEWS
|
|
522
|
+
-- ============================================================================
|
|
523
|
+
|
|
524
|
+
-- Recent archives
|
|
525
|
+
CREATE OR REPLACE VIEW v_recent_archives WITH (security_invoker = true) AS
|
|
526
|
+
SELECT
|
|
527
|
+
fa.id,
|
|
528
|
+
fa.feature_id,
|
|
529
|
+
f.name AS feature_name,
|
|
530
|
+
fa.summary,
|
|
531
|
+
fa.files_archived,
|
|
532
|
+
fa.total_size_bytes,
|
|
533
|
+
fa.release_version,
|
|
534
|
+
fa.archived_at,
|
|
535
|
+
fa.spec_snapshot->>'complexity_level' AS complexity_level,
|
|
536
|
+
array_length(fa.files_archived, 1) AS file_count
|
|
537
|
+
FROM feature_archives fa
|
|
538
|
+
JOIN features f ON f.id = fa.feature_id::text
|
|
539
|
+
ORDER BY fa.archived_at DESC
|
|
540
|
+
LIMIT 50;
|
|
541
|
+
|
|
542
|
+
COMMENT ON VIEW v_recent_archives IS 'Most recent 50 feature archives';
|
|
543
|
+
|
|
544
|
+
-- Archive stats
|
|
545
|
+
CREATE OR REPLACE VIEW v_archive_stats WITH (security_invoker = true) AS
|
|
546
|
+
SELECT
|
|
547
|
+
count(*) AS total_archives,
|
|
548
|
+
sum(total_size_bytes) AS total_storage_bytes,
|
|
549
|
+
sum(array_length(files_archived, 1)) AS total_files,
|
|
550
|
+
count(DISTINCT release_version) AS release_count,
|
|
551
|
+
min(archived_at) AS oldest_archive,
|
|
552
|
+
max(archived_at) AS newest_archive
|
|
553
|
+
FROM feature_archives;
|
|
554
|
+
|
|
555
|
+
COMMENT ON VIEW v_archive_stats IS 'Aggregate archive statistics';
|
|
556
|
+
|
|
557
|
+
-- Archives by release
|
|
558
|
+
CREATE OR REPLACE VIEW v_archives_by_release WITH (security_invoker = true) AS
|
|
559
|
+
SELECT
|
|
560
|
+
release_version,
|
|
561
|
+
count(*) AS feature_count,
|
|
562
|
+
sum(total_size_bytes) AS total_bytes,
|
|
563
|
+
array_agg(feature_id ORDER BY archived_at) AS features,
|
|
564
|
+
min(archived_at) AS release_date
|
|
565
|
+
FROM feature_archives
|
|
566
|
+
WHERE release_version IS NOT NULL
|
|
567
|
+
GROUP BY release_version
|
|
568
|
+
ORDER BY min(archived_at) DESC;
|
|
569
|
+
|
|
570
|
+
COMMENT ON VIEW v_archives_by_release IS 'Archives grouped by release version';
|
|
571
|
+
|
|
572
|
+
-- ============================================================================
|
|
573
|
+
-- CONFLICT VIEWS
|
|
574
|
+
-- ============================================================================
|
|
575
|
+
|
|
576
|
+
-- High risk conflicts
|
|
577
|
+
CREATE OR REPLACE VIEW v_high_risk_conflicts WITH (security_invoker = true) AS
|
|
578
|
+
SELECT
|
|
579
|
+
cd.id,
|
|
580
|
+
cd.feature_a_id,
|
|
581
|
+
cd.feature_b_id,
|
|
582
|
+
cd.file_path,
|
|
583
|
+
cd.conflict_risk,
|
|
584
|
+
cd.detected_at,
|
|
585
|
+
cd.detected_phase,
|
|
586
|
+
cd.status,
|
|
587
|
+
cd.strategy,
|
|
588
|
+
cd.notes,
|
|
589
|
+
fa.name AS feature_a_name,
|
|
590
|
+
fb.name AS feature_b_name,
|
|
591
|
+
fa.assigned_agent AS agent_a,
|
|
592
|
+
fb.assigned_agent AS agent_b
|
|
593
|
+
FROM conflict_detection cd
|
|
594
|
+
JOIN features fa ON cd.feature_a_id = fa.id
|
|
595
|
+
JOIN features fb ON cd.feature_b_id = fb.id
|
|
596
|
+
WHERE cd.conflict_risk IN ('HIGH', 'MEDIUM')
|
|
597
|
+
AND cd.status = 'DETECTED';
|
|
598
|
+
|
|
599
|
+
COMMENT ON VIEW v_high_risk_conflicts IS 'Unresolved high/medium risk conflicts between features';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- Odin SDD Framework - Seed Data
|
|
3
|
+
-- Version: 1.0.0
|
|
4
|
+
-- Created: 2026-02-16
|
|
5
|
+
-- Description: Initial seed data for Odin. Run after 003_views.sql.
|
|
6
|
+
-- Contains batch templates for common operations.
|
|
7
|
+
-- ============================================================================
|
|
8
|
+
|
|
9
|
+
-- ============================================================================
|
|
10
|
+
-- BATCH TEMPLATES
|
|
11
|
+
-- ============================================================================
|
|
12
|
+
|
|
13
|
+
-- Clear existing templates (idempotent)
|
|
14
|
+
DELETE FROM batch_templates WHERE created_by = 'system';
|
|
15
|
+
|
|
16
|
+
-- Template: Full Feature Status
|
|
17
|
+
INSERT INTO batch_templates (name, description, params, steps, output_config, created_by)
|
|
18
|
+
VALUES (
|
|
19
|
+
'feature_full_status',
|
|
20
|
+
'Get complete feature status including durations, gates, blockers, transitions',
|
|
21
|
+
'[{"name": "feature_id", "type": "string", "required": true}]',
|
|
22
|
+
'[
|
|
23
|
+
{"step_id": 0, "tool": "get_feature", "args": {"feature_id": "$params.feature_id"}, "on_error": "fail"},
|
|
24
|
+
{"step_id": 1, "tool": "get_phase_durations", "args": {"feature_id": "$params.feature_id"}, "on_error": "continue"},
|
|
25
|
+
{"step_id": 2, "tool": "get_quality_gates", "args": {"feature_id": "$params.feature_id"}, "on_error": "continue"},
|
|
26
|
+
{"step_id": 3, "tool": "get_blockers", "args": {"feature_id": "$params.feature_id"}, "on_error": "continue"},
|
|
27
|
+
{"step_id": 4, "tool": "get_phase_transitions", "args": {"feature_id": "$params.feature_id"}, "on_error": "continue"}
|
|
28
|
+
]',
|
|
29
|
+
'{"include_steps": [0,1,2,3,4], "format": "full"}',
|
|
30
|
+
'system'
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
-- Template: Feature with Learnings
|
|
34
|
+
INSERT INTO batch_templates (name, description, params, steps, output_config, created_by)
|
|
35
|
+
VALUES (
|
|
36
|
+
'feature_with_learnings',
|
|
37
|
+
'Get feature status plus all associated learnings',
|
|
38
|
+
'[{"name": "feature_id", "type": "string", "required": true}]',
|
|
39
|
+
'[
|
|
40
|
+
{"step_id": 0, "tool": "get_feature", "args": {"feature_id": "$params.feature_id"}, "on_error": "fail"},
|
|
41
|
+
{"step_id": 1, "tool": "get_learnings_for_feature", "args": {"feature_id": "$params.feature_id"}, "on_error": "continue"},
|
|
42
|
+
{"step_id": 2, "tool": "compute_feature_eval", "args": {"feature_id": "$params.feature_id"}, "on_error": "skip"}
|
|
43
|
+
]',
|
|
44
|
+
'{"include_steps": [0,1,2], "format": "full"}',
|
|
45
|
+
'system'
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
-- Template: System Health Check
|
|
49
|
+
INSERT INTO batch_templates (name, description, params, steps, output_config, created_by)
|
|
50
|
+
VALUES (
|
|
51
|
+
'system_health_check',
|
|
52
|
+
'Get system health, active alerts, and blocked features',
|
|
53
|
+
'[]',
|
|
54
|
+
'[
|
|
55
|
+
{"step_id": 0, "tool": "get_system_health", "args": {}, "on_error": "continue"},
|
|
56
|
+
{"step_id": 1, "tool": "get_active_alerts", "args": {}, "on_error": "continue"},
|
|
57
|
+
{"step_id": 2, "tool": "list_features", "args": {"status": "BLOCKED"}, "on_error": "continue"}
|
|
58
|
+
]',
|
|
59
|
+
'{"include_steps": [0,1,2], "format": "full"}',
|
|
60
|
+
'system'
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
-- Template: Learning Evolution
|
|
64
|
+
INSERT INTO batch_templates (name, description, params, steps, output_config, created_by)
|
|
65
|
+
VALUES (
|
|
66
|
+
'learning_evolution',
|
|
67
|
+
'Get full evolution chain for a learning',
|
|
68
|
+
'[{"name": "learning_id", "type": "uuid", "required": true}]',
|
|
69
|
+
'[
|
|
70
|
+
{"step_id": 0, "tool": "get_learning", "args": {"learning_id": "$params.learning_id"}, "on_error": "fail"},
|
|
71
|
+
{"step_id": 1, "tool": "get_learning_chain", "args": {"learning_id": "$params.learning_id"}, "on_error": "continue"},
|
|
72
|
+
{"step_id": 2, "tool": "detect_conflicts", "args": {"learning_id": "$params.learning_id"}, "on_error": "skip"}
|
|
73
|
+
]',
|
|
74
|
+
'{"include_steps": [0,1,2], "format": "full"}',
|
|
75
|
+
'system'
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
-- Template: Propagation Review
|
|
79
|
+
INSERT INTO batch_templates (name, description, params, steps, output_config, created_by)
|
|
80
|
+
VALUES (
|
|
81
|
+
'propagation_review',
|
|
82
|
+
'Get learnings ready for propagation and any open conflicts',
|
|
83
|
+
'[]',
|
|
84
|
+
'[
|
|
85
|
+
{"step_id": 0, "tool": "get_propagation_queue", "args": {}, "on_error": "continue"},
|
|
86
|
+
{"step_id": 1, "tool": "get_open_conflicts", "args": {}, "on_error": "continue"}
|
|
87
|
+
]',
|
|
88
|
+
'{"include_steps": [0,1], "format": "full"}',
|
|
89
|
+
'system'
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
-- ============================================================================
|
|
93
|
+
-- VERIFICATION
|
|
94
|
+
-- ============================================================================
|
|
95
|
+
|
|
96
|
+
-- Verify all templates were inserted
|
|
97
|
+
DO $$
|
|
98
|
+
DECLARE
|
|
99
|
+
template_count INTEGER;
|
|
100
|
+
BEGIN
|
|
101
|
+
SELECT COUNT(*) INTO template_count FROM batch_templates WHERE created_by = 'system';
|
|
102
|
+
IF template_count != 5 THEN
|
|
103
|
+
RAISE EXCEPTION 'Expected 5 system templates, found %', template_count;
|
|
104
|
+
END IF;
|
|
105
|
+
RAISE NOTICE 'Seed data verified: % batch templates created', template_count;
|
|
106
|
+
END $$;
|