Files
headquarter/openspec/changes/add-config-profiles/design.md
T
alex 22c035984e feat: add config profiles data model and migrations
- Add ConfigProfile model with user ownership, name, description
- Add ConfigInclude model for ordered profile self-references
- Add ConfigMount model for mount/file definitions
- Add selected_profile_id to ToolInstance for per-instance profile selection
- Add default profile properties to UserConfig JSONB config
- Create Alembic migration 0013 for new tables and columns
- Register new models in models/__init__.py
- Mark config_folders.is_active as deprecated
- Add migration metadata test

Quality gates: syntax check passed (all files parse successfully)
OpenSpec: add-config-profiles task 1.1
2026-05-24 12:54:45 +00:00

2.5 KiB

Context

The current system uses config_folders with a flat files JSONB and an is_active flag for auto-mounting at tool launch time. This design is inflexible: only one folder can be active, there's no ordering of includes, no explicit per-tool-instance selection, and mount definitions are mixed with file contents in a single blob.

Goals / Non-Goals

Goals:

  • Provide structured config profiles with named collections of mounts and includes
  • Support ordered include lists so profiles can reference other profiles in sequence
  • Allow per-tool-instance profile selection with fallback to user/tool-type defaults
  • Remove implicit auto-mounting behavior at launch time
  • Maintain backward compatibility for existing config_folders data during migration

Non-Goals:

  • Frontend UI for profile management (separate change)
  • Real-time profile switching on running instances
  • Profile versioning or history

Decisions

1. New config_profiles table replaces the semantic role of config_folders

  • Rationale: A profile is a higher-level concept than a folder; it includes mounts, includes, and metadata
  • config_folders remains for data migration but is no longer used for auto-mounting

2. config_includes provides ordered many-to-many self-reference on config_profiles

  • Rationale: Profiles need to include other profiles (e.g., a "base" profile included by "project-specific")
  • order_index column controls application order

3. config_mounts stores individual mount/file entries

  • Rationale: Normalizing mounts allows querying, ordering, and validation per mount
  • Each mount has a mount_path, optional content text, and optional source_profile_id for transitive includes

4. Default profile stored on user_configs.config JSONB

  • Rationale: Avoids schema changes to users; the existing user_configs table already stores per-user JSON
  • Key: default_profile_id (global default) and default_profiles map for per-tool-type defaults

5. tool_instances.selected_profile_id for explicit selection

  • Rationale: Clear, direct foreign key; nullable to allow fallback to defaults
  • Null means "use default resolution"

Risks / Trade-offs

  • [Risk] Existing config_folders data becomes orphaned if not migrated → Mitigation: keep table, stop auto-mount behavior only
  • [Risk] Profile include cycles could cause infinite loops → Mitigation: validate at write time, detect cycles in include graph
  • [Risk] Multiple includes with overlapping mount paths → Mitigation: last-include-wins based on order_index