Files
steve c8559676ed
executus CI / test (push) Has been cancelled
P4b: skill noun + contrib/store (SQLite for budget/persona/skill/audit)
Merges the skill half of the persona/skill pair plus the second nested module.
(Squashed onto main from phase-4b-skill; the audit/budget/persona batteries it
was stacked on already landed via the P4 merge.)

- skill/: clean-redesign Skill noun + LEAN SkillStore (lifecycle/versions/
  schedule only) + ToRunnable + Memory default.
- contrib/store/: separate go.mod carrying modernc.org/sqlite, so the driver
  never enters the core go.sum. db.Budget()/Personas()/Skills()/Audit() back
  all four store seams (JSON-blob + indexed columns; round-trip tested).
  Includes the verified gadfly #5 fixes (AppendVersion tx+UNIQUE+error,
  Mark*ScheduledRun atomic json_set, busy_timeout, NaN guard).
- CI: builds + tests the nested module and asserts it owns the sqlite driver.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 00:15:00 -04:00

45 lines
1.8 KiB
Go

package skill
import (
"context"
"errors"
"time"
)
// ErrNotFound is returned when a skill (or version) lookup misses.
var ErrNotFound = errors.New("skill not found")
// SkillStore is the persistence seam for saved skills. This is the DELIBERATELY
// LEAN redesign of mort's 60-method skills.Storage: it carries only skill
// lifecycle (CRUD + visibility), versioning, and scheduling. The KV/file/quota
// sub-stores that were fused into mort's interface are NOT here — they are the
// tools/ store seams (KVStorage / FileStorage / QuotaProvider); email recipients
// and channel grants stay host concerns. A host backs this with its DB; Memory()
// is the zero-dependency default; contrib/store adds durable SQLite.
type SkillStore interface {
// Initialize prepares storage (idempotent).
Initialize(ctx context.Context) error
// --- lifecycle ---
Save(ctx context.Context, s *Skill) error
Get(ctx context.Context, id string) (*Skill, error)
GetByName(ctx context.Context, ownerID, name string) (*Skill, error)
Delete(ctx context.Context, id string) error
// --- listing / visibility ---
ListByOwner(ctx context.Context, ownerID string) ([]Skill, error)
ListPublic(ctx context.Context) ([]Skill, error)
ListSharedWith(ctx context.Context, memberID string) ([]Skill, error)
ListBuiltinByName(ctx context.Context, name string) (*Skill, error)
ListChatbotExposed(ctx context.Context) ([]Skill, error)
// --- scheduling ---
ListDueScheduled(ctx context.Context, now time.Time) ([]Skill, error)
MarkScheduledRun(ctx context.Context, skillID string, ranAt, nextAt time.Time) error
// --- versioning ---
AppendVersion(ctx context.Context, sv SkillVersion) error
ListVersionsBySkill(ctx context.Context, skillID string, limit int) ([]SkillVersion, error)
GetVersionByID(ctx context.Context, versionID string) (*SkillVersion, error)
}