refactor(db): move ticketing database to shared worktree location

The SQLite database now lives at ../settledreach.db, shared across all
git worktrees. This eliminates binary merge conflicts that occurred
whenever two branches modified the database independently.

All Python connectors (ticket CLI, sqlite_connector, decisions_sync)
now resolve the DB path relative to their own location — three levels
up from db/connectors/ reaches the worktree parent. The _main_worktree()
git-rev-parse pattern and config.json sqlite_db key are removed.

The database file is untracked from git; a backup mechanism commits
snapshots through the main branch (see following commits).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-12 16:54:00 +01:00
co-authored by Claude Opus 4.6
parent ffb73a6a77
commit c21671d44c
6 changed files with 15 additions and 53 deletions
+2 -3
View File
@@ -8,9 +8,8 @@ client/export/
client/reports/
client/*.import
# Database journal files (transient, not the DB itself)
db/commonwealth.db-wal
db/commonwealth.db-shm
# Database (shared across worktrees at ../settledreach.db, not tracked)
db/commonwealth.db*
# Python
__pycache__/
Binary file not shown.
+1 -1
View File
@@ -1,5 +1,5 @@
{
"sqlite_db": "../commonwealth.db",
"qdrant_url": "http://tower-of-joy:6333",
"ollama_url": "http://tower-of-joy:11434",
"collection": "commonwealth",
+6 -5
View File
@@ -24,8 +24,10 @@ from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
CONFIG_PATH = SCRIPT_DIR / "config.json"
SCHEMA_PATH = SCRIPT_DIR.parent / "schema.sql"
REPO_ROOT = SCRIPT_DIR.parent.parent
DECISIONS_DIR = REPO_ROOT / "decisions"
WORKTREE_ROOT = SCRIPT_DIR.parent.parent
DECISIONS_DIR = WORKTREE_ROOT / "decisions"
# Shared database lives in the parent of all worktrees (three levels up from db/connectors/).
DB_PATH = (SCRIPT_DIR / ".." / ".." / ".." / "settledreach.db").resolve()
# ---------------------------------------------------------------------------
# Config / DB (same pattern as sqlite_connector.py)
@@ -36,8 +38,7 @@ def load_config():
"""Load config.json and resolve the SQLite database path."""
with open(CONFIG_PATH, "r") as f:
cfg = json.load(f)
db_path = (SCRIPT_DIR / cfg["sqlite_db"]).resolve()
cfg["sqlite_db_resolved"] = str(db_path)
cfg["sqlite_db_resolved"] = str(DB_PATH)
return cfg
@@ -193,7 +194,7 @@ def parse_file(filepath):
and a refs list of (target_id, ref_type, note).
"""
domain = filepath.stem # e.g. "architecture" from "architecture.md"
rel_path = str(filepath.relative_to(REPO_ROOT))
rel_path = str(filepath.relative_to(WORKTREE_ROOT))
text = filepath.read_text(encoding="utf-8")
lines = text.split("\n")
+3 -18
View File
@@ -13,7 +13,6 @@ Usage:
import json
import os
import sqlite3
import subprocess
import sys
from pathlib import Path
@@ -24,29 +23,15 @@ from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
CONFIG_PATH = SCRIPT_DIR / "config.json"
SCHEMA_PATH = SCRIPT_DIR.parent / "schema.sql"
def _main_worktree():
"""Find the main worktree root via git's common dir."""
try:
common = subprocess.check_output(
["git", "rev-parse", "--git-common-dir"],
stderr=subprocess.DEVNULL, text=True
).strip()
return Path(common).resolve().parent
except (subprocess.CalledProcessError, OSError):
return SCRIPT_DIR.parent.parent
# Shared database lives in the parent of all worktrees (three levels up from db/connectors/).
DB_PATH = (SCRIPT_DIR / ".." / ".." / ".." / "settledreach.db").resolve()
def load_config():
"""Load config.json and resolve the SQLite database path."""
with open(CONFIG_PATH, "r") as f:
cfg = json.load(f)
# Always resolve DB path in the main worktree to avoid
# WAL/journal pollution on feature branches causing merge conflicts.
main_root = _main_worktree()
db_path = (main_root / "db" / "commonwealth.db").resolve()
cfg["sqlite_db_resolved"] = str(db_path)
cfg["sqlite_db_resolved"] = str(DB_PATH)
return cfg
+3 -26
View File
@@ -25,42 +25,19 @@ All output is JSON on stdout.
import json
import os
import sqlite3
import subprocess
import sys
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
CONFIG_PATH = SCRIPT_DIR / "config.json"
def _main_worktree():
"""Find the main worktree root via git's common dir.
In a worktree layout like:
settled-reach/main/ (main worktree, holds .git/)
settled-reach/server/ (linked worktree, .git is a file)
git rev-parse --git-common-dir always points to main's .git/,
so its parent is the main worktree root.
"""
try:
common = subprocess.check_output(
["git", "rev-parse", "--git-common-dir"],
stderr=subprocess.DEVNULL, text=True
).strip()
return Path(common).resolve().parent
except (subprocess.CalledProcessError, OSError):
# Fallback: assume script lives in the main worktree
return SCRIPT_DIR.parent.parent
# Shared database lives in the parent of all worktrees (three levels up from db/connectors/).
DB_PATH = (SCRIPT_DIR / ".." / ".." / ".." / "settledreach.db").resolve()
def load_config():
with open(CONFIG_PATH, "r") as f:
cfg = json.load(f)
# Always resolve DB path in the main worktree to avoid
# WAL/journal pollution on feature branches causing merge conflicts.
main_root = _main_worktree()
db_path = (main_root / "db" / "commonwealth.db").resolve()
cfg["sqlite_db_resolved"] = str(db_path)
cfg["sqlite_db_resolved"] = str(DB_PATH)
return cfg