Skip to content

Conversation

@JAORMX
Copy link
Contributor

@JAORMX JAORMX commented Feb 9, 2026

Summary

Proposes replacing ToolHive's file-based local state management with a single SQLite database (toolhive.db).

Phase 1 targets the skills subsystem to unblock toolhive#3648. Later phases will migrate workload statuses and groups. RunConfigs and config.yaml remain file-based.

Key Design Decisions

  • modernc.org/sqlite (pure Go) -- required because ToolHive builds with CGO_ENABLED=0
  • WAL mode for concurrent access from thv serve, CLI commands, and detached proxies
  • New pkg/storage/ package with domain-specific interfaces (not extending the stream-oriented pkg/state/)
  • Embedded SQL migrations with a version tracking table
  • Single toolhive.db at $XDG_STATE_HOME/toolhive/ rather than per-subsystem databases

Related

🤖 Generated with Claude Code

JAORMX and others added 2 commits February 9, 2026 18:00
Proposes replacing file-based local state management with a single
SQLite database. Phase 1 targets skills to unblock skills lifecycle
management. Later phases will migrate workload statuses and groups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Juan Antonio Osorio <ozz@stacklok.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Juan Antonio Osorio <ozz@stacklok.com>
rdimitrov
rdimitrov previously approved these changes Feb 10, 2026
Copy link
Member

@rdimitrov rdimitrov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't looked deeper at the database model, but overall LGTM

Copy link
Contributor

@blkt blkt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First review, I've yet to read past the Dependency Graph section, but this should represent most of it.

aponcedeleonch
aponcedeleonch previously approved these changes Feb 10, 2026
@JAORMX
Copy link
Contributor Author

JAORMX commented Feb 10, 2026

Responding to the discussion around normalizing clients to its own table (from @aponcedeleonch and @blkt):

Good suggestion. I looked into this carefully. The tradeoffs:

Normalized junction table gives you efficient per-client queries and relational integrity, but at this scale (dozens of rows, 1-3 client apps per skill) those benefits are marginal. It also introduces complexity around whether skills and groups share the same junction table or have separate ones — since skills associate client_apps per-installation (scope + project) while groups associate them at the group level, a shared table needs qualifiers that get awkward fast.

JSONB array maps directly to the Go []string / ClientApp types, keeps the schema simple, and json_each() handles "find skills for client X" queries when needed. modernc.org/sqlite fully supports JSONB (it implements SQLite 3.51.2).

Going with JSONB for now. If query patterns evolve to justify normalization, it's a straightforward migration. Same pattern will apply to groups when they're migrated.

Also renaming the column from clients to client_apps to align with the ClientApp domain type in pkg/client/.

Revise schema based on reviewer feedback from blkt, rdimitrov,
and aponcedeleonch:

- Add thin `entries` identity table shared across lifecycle-tracked
  entities (skills, workloads). Groups are standalone.
- Change scope model from user/system to user/project with
  project_root column for multi-project support.
- Use JSONB (BLOB) for tags and client_apps columns, confirmed
  supported by modernc.org/sqlite (SQLite 3.51.2).
- Rename clients to client_apps to align with ClientApp domain type.
- Add OCI artifact tracking (reference, tag, digest) from skillet.
- Add skill_dependencies and oci_tags tables.
- Document cross-platform XDG paths via adrg/xdg library.
- Drop premature status index.
- Remove resolved open questions (WAL checkpoint, client normalization).
- Update future phase tables, alternatives, and references.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JAORMX JAORMX dismissed stale reviews from aponcedeleonch and rdimitrov via 5b92436 February 10, 2026 14:56
Copy link
Contributor

@blkt blkt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! 🚀

@JAORMX JAORMX merged commit cfcd522 into main Feb 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants