Files
goclaw/migrations/000079_skill_self_evolution.up.sql
Goon 7692939d09 Merge remote-tracking branch 'origin/dev' into codex/issue-161-skill-self-evolution
# Conflicts:
#	cmd/skills_cmd.go
#	docs/project-changelog.md
#	internal/http/skills.go
#	internal/store/sqlitestore/schema.go
2026-06-12 14:57:09 +07:00

90 lines
4.6 KiB
SQL

CREATE TABLE skill_evolution_settings (
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
skill_id UUID NOT NULL REFERENCES skills(id) ON DELETE CASCADE,
enabled BOOLEAN NOT NULL DEFAULT false,
mode VARCHAR(32) NOT NULL DEFAULT 'suggest_only',
last_analyzed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
PRIMARY KEY (tenant_id, skill_id),
CONSTRAINT chk_skill_evolution_mode CHECK (mode IN ('suggest_only', 'auto_analyze'))
);
CREATE INDEX idx_skill_evolution_settings_skill ON skill_evolution_settings(skill_id);
CREATE TABLE skill_usage_metrics (
id UUID PRIMARY KEY DEFAULT uuid_generate_v7(),
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
skill_id UUID NOT NULL REFERENCES skills(id) ON DELETE CASCADE,
skill_slug VARCHAR(255) NOT NULL,
skill_version INT NOT NULL DEFAULT 1,
agent_id UUID REFERENCES agents(id) ON DELETE SET NULL,
user_id VARCHAR(255),
session_key TEXT,
trace_id TEXT,
invocation_id TEXT,
invocation_source VARCHAR(32) NOT NULL DEFAULT 'runtime',
status VARCHAR(32) NOT NULL DEFAULT 'started',
failure_reason TEXT,
tool_calls_count INT NOT NULL DEFAULT 0,
duration_ms BIGINT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT chk_skill_usage_status CHECK (status IN ('started', 'succeeded', 'failed', 'abandoned'))
);
CREATE INDEX idx_skill_usage_metrics_skill_created ON skill_usage_metrics(skill_id, created_at DESC);
CREATE INDEX idx_skill_usage_metrics_tenant_created ON skill_usage_metrics(tenant_id, created_at DESC);
CREATE INDEX idx_skill_usage_metrics_status ON skill_usage_metrics(skill_id, status, created_at DESC);
CREATE INDEX idx_skill_usage_metrics_invocation ON skill_usage_metrics(invocation_id) WHERE invocation_id IS NOT NULL;
CREATE TABLE skill_improvement_suggestions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v7(),
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
skill_id UUID NOT NULL REFERENCES skills(id) ON DELETE CASCADE,
skill_slug VARCHAR(255) NOT NULL,
suggestion_type VARCHAR(64) NOT NULL,
status VARCHAR(32) NOT NULL DEFAULT 'pending',
reason TEXT NOT NULL DEFAULT '',
evidence JSONB NOT NULL DEFAULT '{}',
draft_patch JSONB NOT NULL DEFAULT '{}',
target_file TEXT NOT NULL DEFAULT '',
created_by_actor_type VARCHAR(32) NOT NULL DEFAULT '',
created_by_actor_id VARCHAR(255) NOT NULL DEFAULT '',
reviewed_by_actor_type VARCHAR(32) NOT NULL DEFAULT '',
reviewed_by_actor_id VARCHAR(255) NOT NULL DEFAULT '',
reviewed_at TIMESTAMPTZ,
applied_version INT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT chk_skill_suggestion_status CHECK (status IN ('pending', 'approved', 'rejected', 'applied'))
);
CREATE INDEX idx_skill_suggestions_skill_status_created ON skill_improvement_suggestions(skill_id, status, created_at DESC);
CREATE INDEX idx_skill_suggestions_tenant_created ON skill_improvement_suggestions(tenant_id, created_at DESC);
CREATE TABLE skill_versions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v7(),
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
skill_id UUID NOT NULL REFERENCES skills(id) ON DELETE CASCADE,
version INT NOT NULL,
content_hash VARCHAR(64) NOT NULL DEFAULT '',
changed_files JSONB NOT NULL DEFAULT '[]',
created_by_actor_type VARCHAR(32) NOT NULL DEFAULT '',
created_by_actor_id VARCHAR(255) NOT NULL DEFAULT '',
created_from_suggestion_id UUID REFERENCES skill_improvement_suggestions(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(skill_id, version)
);
CREATE INDEX idx_skill_versions_tenant_skill ON skill_versions(tenant_id, skill_id, version DESC);
INSERT INTO skill_versions (
tenant_id, skill_id, version, content_hash, changed_files,
created_by_actor_type, created_by_actor_id, created_at
)
SELECT tenant_id, id, version, COALESCE(file_hash, ''), '[]'::jsonb,
'system', 'migration', COALESCE(created_at, NOW())
FROM skills
WHERE status != 'deleted'
ON CONFLICT (skill_id, version) DO NOTHING;