feat(cli): add shared infrastructure

Amolith and Crush created

All CLI commands need shared foundation for environment management, plan
rendering, and common helpers.

- Add Environment with DB and store wrappers
- Add plan rendering with status icons
- Add shared command helpers (Environment, ActiveSession, PrintPlan,
  CommandString)
- Add db_test.go for database tests

Co-authored-by: Crush <crush@charm.land>

Change summary

cmd/shared/helpers.go       |  58 +++
internal/cli/environment.go | 122 ++++++++
internal/cli/plan.go        | 168 +++++++++++
internal/cli/plan_test.go   | 101 ++++++
internal/db/db_test.go      | 591 +++++++++++++++++++++++++++++++++++++++
5 files changed, 1,040 insertions(+)

Detailed changes

cmd/shared/helpers.go 🔗

@@ -0,0 +1,58 @@
+// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+package shared
+
+import (
+	"fmt"
+	"os"
+	"strings"
+
+	"git.secluded.site/np/internal/cli"
+	"git.secluded.site/np/internal/session"
+	"github.com/spf13/cobra"
+)
+
+// Environment extracts the CLI environment from the command context.
+func Environment(cmd *cobra.Command) (*cli.Environment, error) {
+	env, ok := cli.FromContext(cmd.Context())
+	if !ok || env == nil {
+		return nil, fmt.Errorf("environment not initialised")
+	}
+	return env, nil
+}
+
+// ActiveSession resolves the current session for cmd, printing guidance when absent.
+func ActiveSession(cmd *cobra.Command, env *cli.Environment) (session.Document, bool, error) {
+	cwd, err := os.Getwd()
+	if err != nil {
+		return session.Document{}, false, fmt.Errorf("determine working directory: %w", err)
+	}
+
+	doc, found, err := env.ActiveSession(cmd.Context(), cwd)
+	if err != nil {
+		return session.Document{}, false, err
+	}
+	if !found {
+		fmt.Fprintln(cmd.OutOrStdout(), "No active session. Start one with `np s`.")
+		return session.Document{}, false, nil
+	}
+	return doc, true, nil
+}
+
+// CommandString returns the full invocation string for logging events.
+func CommandString() string {
+	return strings.Join(os.Args, " ")
+}
+
+// PrintPlan renders the plan for sid, returning the state used for rendering.
+func PrintPlan(cmd *cobra.Command, env *cli.Environment, sid string) (cli.PlanState, error) {
+	state, err := cli.BuildPlanState(cmd.Context(), env, sid)
+	if err != nil {
+		return cli.PlanState{}, err
+	}
+
+	fmt.Fprintln(cmd.OutOrStdout(), cli.RenderPlan(state))
+	return state, nil
+}

internal/cli/environment.go 🔗

@@ -0,0 +1,122 @@
+// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+package cli
+
+import (
+	"context"
+	"errors"
+	"fmt"
+
+	"git.secluded.site/np/internal/db"
+	"git.secluded.site/np/internal/event"
+	"git.secluded.site/np/internal/goal"
+	"git.secluded.site/np/internal/session"
+	"git.secluded.site/np/internal/task"
+	"git.secluded.site/np/internal/timeutil"
+)
+
+// Environment aggregates long-lived services needed by CLI commands.
+type Environment struct {
+	DB           *db.Database
+	Clock        timeutil.Clock
+	SessionStore *session.Store
+	GoalStore    *goal.Store
+	TaskStore    *task.Store
+	EventStore   *event.Store
+}
+
+// OpenEnvironment initialises storage and domain stores for CLI commands.
+func OpenEnvironment(opts db.Options, clock timeutil.Clock) (*Environment, error) {
+	database, err := db.Open(opts)
+	if err != nil {
+		return nil, fmt.Errorf("cli: open database: %w", err)
+	}
+
+	if clock == nil {
+		clock = timeutil.UTCClock{}
+	}
+
+	env := &Environment{
+		DB:           database,
+		Clock:        clock,
+		SessionStore: session.NewStore(database, clock),
+		GoalStore:    goal.NewStore(database, clock),
+		TaskStore:    task.NewStore(database, clock),
+		EventStore:   event.NewStore(database, clock),
+	}
+	return env, nil
+}
+
+// Close releases resources allocated by the environment.
+func (e *Environment) Close() error {
+	if e == nil || e.DB == nil {
+		return nil
+	}
+	return e.DB.Close()
+}
+
+// ActiveSession resolves the active session for path (or parent paths).
+func (e *Environment) ActiveSession(ctx context.Context, path string) (session.Document, bool, error) {
+	if e == nil || e.SessionStore == nil {
+		return session.Document{}, false, errors.New("cli: environment not initialised")
+	}
+	return e.SessionStore.ActiveByPath(ctx, path)
+}
+
+// LoadGoal retrieves the goal for sid. When absent, ok is false.
+func (e *Environment) LoadGoal(ctx context.Context, sid string) (goal.Document, bool, error) {
+	if e == nil || e.GoalStore == nil {
+		return goal.Document{}, false, errors.New("cli: environment not initialised")
+	}
+	doc, err := e.GoalStore.Get(ctx, sid)
+	if err != nil {
+		if errors.Is(err, goal.ErrNotFound) {
+			return goal.Document{}, false, nil
+		}
+		return goal.Document{}, false, err
+	}
+	return doc, true, nil
+}
+
+// LoadTasks returns tasks for sid sorted by creation order.
+func (e *Environment) LoadTasks(ctx context.Context, sid string) ([]task.Task, error) {
+	if e == nil || e.TaskStore == nil {
+		return nil, errors.New("cli: environment not initialised")
+	}
+	return e.TaskStore.List(ctx, sid)
+}
+
+// LoadTasksByStatus returns tasks filtered by status. When status is empty,
+// all tasks are returned.
+func (e *Environment) LoadTasksByStatus(ctx context.Context, sid string, status task.Status) ([]task.Task, error) {
+	if e == nil || e.TaskStore == nil {
+		return nil, errors.New("cli: environment not initialised")
+	}
+	if status == "" {
+		return e.TaskStore.List(ctx, sid)
+	}
+	return e.TaskStore.ListByStatus(ctx, sid, status)
+}
+
+type contextKey string
+
+const environmentContextKey contextKey = "git.secluded.site/np/internal/cli/environment"
+
+// WithEnvironment stores env inside ctx for retrieval by subcommands.
+func WithEnvironment(ctx context.Context, env *Environment) context.Context {
+	return context.WithValue(ctx, environmentContextKey, env)
+}
+
+// FromContext extracts an Environment that was previously embedded with WithEnvironment.
+func FromContext(ctx context.Context) (*Environment, bool) {
+	if ctx == nil {
+		return nil, false
+	}
+	env, ok := ctx.Value(environmentContextKey).(*Environment)
+	if !ok || env == nil {
+		return nil, false
+	}
+	return env, true
+}

internal/cli/plan.go 🔗

@@ -0,0 +1,168 @@
+// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+package cli
+
+import (
+	"context"
+	"errors"
+	"sort"
+	"strings"
+
+	"git.secluded.site/np/internal/goal"
+	"git.secluded.site/np/internal/task"
+)
+
+var statusIcons = map[task.Status]string{
+	task.StatusPending:    "☐",
+	task.StatusInProgress: "⟳",
+	task.StatusCompleted:  "☑",
+	task.StatusFailed:     "☒",
+	task.StatusCancelled:  "⊗",
+}
+
+var legendBaseOrder = []task.Status{
+	task.StatusPending,
+	task.StatusInProgress,
+	task.StatusCompleted,
+}
+
+var legendOptionalOrder = []task.Status{
+	task.StatusFailed,
+	task.StatusCancelled,
+}
+
+// PlanState captures goal/tasks for rendering.
+type PlanState struct {
+	Goal  *goal.Document
+	Tasks []task.Task
+}
+
+// BuildPlanState aggregates goal and tasks for sid using env.
+func BuildPlanState(ctx context.Context, env *Environment, sid string) (PlanState, error) {
+	if env == nil {
+		return PlanState{}, errors.New("cli: environment not initialised")
+	}
+
+	tasks, err := env.LoadTasks(ctx, sid)
+	if err != nil {
+		return PlanState{}, err
+	}
+
+	state := PlanState{
+		Tasks: tasks,
+	}
+
+	goalDoc, ok, err := env.LoadGoal(ctx, sid)
+	if err != nil {
+		return PlanState{}, err
+	}
+	if ok {
+		state.Goal = &goalDoc
+	}
+
+	return state, nil
+}
+
+// RenderPlan produces the textual plan layout consumed by LLM agents.
+func RenderPlan(state PlanState) string {
+	var b strings.Builder
+
+	if state.Goal != nil {
+		b.WriteString(strings.TrimSpace(state.Goal.Title))
+		b.WriteString("\n")
+
+		if desc := strings.TrimSpace(state.Goal.Description); desc != "" {
+			b.WriteString("\n")
+			writeIndentedBlock(&b, desc, "")
+			b.WriteString("\n")
+		} else {
+			b.WriteString("\n")
+		}
+	} else {
+		b.WriteString("No goal set yet\n\n")
+	}
+
+	legend := buildLegend(state.Tasks)
+	if legend != "" {
+		b.WriteString("Legend: ")
+		b.WriteString(legend)
+		b.WriteString("\n")
+	}
+
+	if len(state.Tasks) == 0 {
+		b.WriteString("No tasks yet.\n")
+		return b.String()
+	}
+
+	sorted := make([]task.Task, len(state.Tasks))
+	copy(sorted, state.Tasks)
+	sort.Slice(sorted, func(i, j int) bool {
+		if sorted[i].CreatedSeq != sorted[j].CreatedSeq {
+			return sorted[i].CreatedSeq < sorted[j].CreatedSeq
+		}
+		if !sorted[i].CreatedAt.Equal(sorted[j].CreatedAt) {
+			return sorted[i].CreatedAt.Before(sorted[j].CreatedAt)
+		}
+		return sorted[i].ID < sorted[j].ID
+	})
+
+	for _, t := range sorted {
+		icon := statusIcons[t.Status]
+		if icon == "" {
+			icon = "?"
+		}
+		b.WriteString(icon)
+		b.WriteString(" ")
+		b.WriteString(strings.TrimSpace(t.Title))
+		b.WriteString(" [")
+		b.WriteString(strings.TrimSpace(t.ID))
+		b.WriteString("]\n")
+
+		if desc := strings.TrimSpace(t.Description); desc != "" {
+			writeIndentedBlock(&b, desc, "  ")
+		}
+	}
+
+	return b.String()
+}
+
+func buildLegend(tasks []task.Task) string {
+	present := map[task.Status]bool{}
+	for _, t := range tasks {
+		present[t.Status] = true
+	}
+
+	var parts []string
+	for _, status := range legendBaseOrder {
+		parts = append(parts, legendEntry(status))
+	}
+	for _, status := range legendOptionalOrder {
+		if present[status] {
+			parts = append(parts, legendEntry(status))
+		}
+	}
+	return strings.Join(parts, "  ")
+}
+
+func legendEntry(status task.Status) string {
+	icon := statusIcons[status]
+	if icon == "" {
+		icon = "?"
+	}
+	return icon + " " + statusLabel(status)
+}
+
+func writeIndentedBlock(b *strings.Builder, text string, prefix string) {
+	lines := strings.Split(text, "\n")
+	for _, line := range lines {
+		b.WriteString(prefix)
+		b.WriteString(strings.TrimSpace(line))
+		b.WriteString("\n")
+	}
+}
+
+func statusLabel(status task.Status) string {
+	return strings.ReplaceAll(status.String(), "_", " ")
+}

internal/cli/plan_test.go 🔗

@@ -0,0 +1,101 @@
+// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+package cli_test
+
+import (
+	"strings"
+	"testing"
+	"time"
+
+	"git.secluded.site/np/internal/cli"
+	"git.secluded.site/np/internal/goal"
+	"git.secluded.site/np/internal/task"
+)
+
+func TestRenderPlanWithGoalAndTasks(t *testing.T) {
+	title := "Build reliable planning workflow"
+	description := "Capture context from ticket and operator input.\nPrioritise determinism."
+	goalDoc := goal.Document{
+		Title:       title,
+		Description: description,
+		UpdatedAt:   time.Now(),
+	}
+
+	tasks := []task.Task{
+		{
+			ID:          "alpha1",
+			Title:       "Add initial goal",
+			Description: "Use `np g s` to capture summary.",
+			Status:      task.StatusCompleted,
+			CreatedAt:   time.Now(),
+			UpdatedAt:   time.Now(),
+			CreatedSeq:  1,
+		},
+		{
+			ID:          "beta2",
+			Title:       "Implement task list",
+			Description: "Track progress for each major change.\nRemember to cite files.",
+			Status:      task.StatusInProgress,
+			CreatedAt:   time.Now(),
+			UpdatedAt:   time.Now(),
+			CreatedSeq:  2,
+		},
+		{
+			ID:          "gamma3",
+			Title:       "Polish output",
+			Description: "Ensure legend only includes relevant statuses.",
+			Status:      task.StatusPending,
+			CreatedAt:   time.Now(),
+			UpdatedAt:   time.Now(),
+			CreatedSeq:  3,
+		},
+		{
+			ID:          "delta4",
+			Title:       "Document edge cases",
+			Description: "Explain handling for cancelled operations.",
+			Status:      task.StatusCancelled,
+			CreatedAt:   time.Now(),
+			UpdatedAt:   time.Now(),
+			CreatedSeq:  4,
+		},
+	}
+
+	result := cli.RenderPlan(cli.PlanState{
+		Goal:  &goalDoc,
+		Tasks: tasks,
+	})
+
+	expectedLegend := "Legend: ☐ pending  ⟳ in progress  ☑ completed  ⊗ cancelled"
+	if !strings.Contains(result, expectedLegend) {
+		t.Fatalf("expected legend %q in output:\n%s", expectedLegend, result)
+	}
+
+	if !strings.Contains(result, title) {
+		t.Fatalf("expected goal title in output")
+	}
+
+	if !strings.Contains(result, "Add initial goal [alpha1]") {
+		t.Fatalf("expected completed task line")
+	}
+
+	if !strings.Contains(result, "  Track progress for each major change.") {
+		t.Fatalf("expected indented description line")
+	}
+
+	if strings.Contains(result, "☒ failed") {
+		t.Fatalf("failed legend entry should not appear without failed tasks")
+	}
+}
+
+func TestRenderPlanWithoutGoalOrTasks(t *testing.T) {
+	result := cli.RenderPlan(cli.PlanState{})
+
+	if !strings.Contains(result, "No goal set yet") {
+		t.Fatalf("expected placeholder goal")
+	}
+	if !strings.Contains(result, "No tasks yet.") {
+		t.Fatalf("expected placeholder task message")
+	}
+}

internal/db/db_test.go 🔗

@@ -0,0 +1,591 @@
+// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+package db
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+)
+
+func openTestDB(t *testing.T) *Database {
+	t.Helper()
+
+	database, err := Open(Options{Path: t.TempDir()})
+	if err != nil {
+		t.Fatalf("open db: %v", err)
+	}
+
+	t.Cleanup(func() {
+		if err := database.Close(); err != nil {
+			t.Fatalf("closing db: %v", err)
+		}
+	})
+
+	return database
+}
+
+func TestDatabasePathAndClose(t *testing.T) {
+	database := openTestDB(t)
+	if database.Path() == "" {
+		t.Fatalf("Path() returned empty string")
+	}
+	if err := database.Close(); err != nil {
+		t.Fatalf("Close() returned error on first call: %v", err)
+	}
+	// Second close should be a noop.
+	if err := database.Close(); err != nil {
+		t.Fatalf("Close() returned error on second call: %v", err)
+	}
+}
+
+func TestDatabaseViewErrorMapping(t *testing.T) {
+	database := openTestDB(t)
+
+	err := database.View(context.Background(), func(txn *Txn) error {
+		_, err := txn.Get([]byte("missing"))
+		return err
+	})
+	if !errors.Is(err, ErrKeyNotFound) {
+		t.Fatalf("expected ErrKeyNotFound, got %v", err)
+	}
+
+	aborted := database.View(context.Background(), func(txn *Txn) error {
+		return txn.Abort()
+	})
+	if aborted != nil {
+		t.Fatalf("expected nil after abort, got %v", aborted)
+	}
+
+	readonlyErr := database.View(context.Background(), func(txn *Txn) error {
+		return txn.Set([]byte("k"), []byte("v"))
+	})
+	if !errors.Is(readonlyErr, ErrReadOnly) {
+		t.Fatalf("expected ErrReadOnly inside view, got %v", readonlyErr)
+	}
+}
+
+func TestDatabaseUpdateLifecycle(t *testing.T) {
+	database := openTestDB(t)
+
+	type payload struct {
+		Message string
+		Count   int
+	}
+	p := payload{Message: "hello", Count: 42}
+
+	err := database.Update(context.Background(), func(txn *Txn) error {
+		if err := txn.Set([]byte("alpha"), []byte("bravo")); err != nil {
+			return err
+		}
+		if err := txn.SetJSON([]byte("payload"), p); err != nil {
+			return err
+		}
+		if _, err := txn.IncrementUint64([]byte("counter"), 5); err != nil {
+			return err
+		}
+		// Seed a value with an invalid length for later IncrementUint64 failure.
+		if err := txn.Set([]byte("counter-invalid"), []byte("oops")); err != nil {
+			return err
+		}
+		return nil
+	})
+	if err != nil {
+		t.Fatalf("Update() returned error: %v", err)
+	}
+
+	err = database.View(context.Background(), func(txn *Txn) error {
+		val, err := txn.Get([]byte("alpha"))
+		if err != nil {
+			return err
+		}
+		if string(val) != "bravo" {
+			t.Fatalf("unexpected value: %q", val)
+		}
+
+		var decoded payload
+		if err := txn.GetJSON([]byte("payload"), &decoded); err != nil {
+			return err
+		}
+		if decoded != p {
+			t.Fatalf("unexpected payload: %#v", decoded)
+		}
+
+		exists, err := txn.Exists([]byte("alpha"))
+		if err != nil {
+			return err
+		}
+		if !exists {
+			t.Fatalf("expected Exists to report true")
+		}
+
+		expected := map[string]string{
+			"alpha":   "bravo",
+			"payload": string(mustJSON(p)),
+		}
+		collected := make(map[string]string)
+		iterErr := txn.Iterate(IterateOptions{PrefetchValues: true}, func(item Item) error {
+			key := item.KeyString()
+			val, err := item.Value()
+			if err != nil {
+				return err
+			}
+			collected[key] = string(val)
+			return nil
+		})
+		if iterErr != nil {
+			return iterErr
+		}
+
+		for key, want := range expected {
+			got, ok := collected[key]
+			if !ok {
+				t.Fatalf("missing key %q in iteration results", key)
+			}
+			if got != want {
+				t.Fatalf("unexpected value for %q: got %q want %q", key, got, want)
+			}
+		}
+
+		abortErr := txn.Iterate(IterateOptions{}, func(Item) error {
+			return ErrTxnAborted
+		})
+		if abortErr != nil {
+			t.Fatalf("expected nil when aborting iteration, got %v", abortErr)
+		}
+
+		prefixCount := 0
+		prefixErr := txn.Iterate(IterateOptions{Prefix: []byte("a")}, func(item Item) error {
+			if !strings.HasPrefix(item.KeyString(), "a") {
+				t.Fatalf("expected prefix match, got %q", item.KeyString())
+			}
+			prefixCount++
+			return nil
+		})
+		if prefixErr != nil {
+			t.Fatalf("prefix iteration error: %v", prefixErr)
+		}
+		if prefixCount == 0 {
+			t.Fatalf("expected at least one prefix item, got %d", prefixCount)
+		}
+
+		return nil
+	})
+	if err != nil {
+		t.Fatalf("View() returned error: %v", err)
+	}
+
+	err = database.Update(context.Background(), func(txn *Txn) error {
+		val, err := txn.IncrementUint64([]byte("counter"), 7)
+		if err != nil {
+			return err
+		}
+		if val != 12 {
+			t.Fatalf("expected counter=12, got %d", val)
+		}
+
+		_, err = txn.IncrementUint64([]byte("counter-invalid"), 1)
+		if err == nil {
+			t.Fatalf("expected error when incrementing invalid counter")
+		}
+
+		return txn.Delete([]byte("alpha"))
+	})
+	if err != nil {
+		t.Fatalf("Update() increment phase error: %v", err)
+	}
+
+	err = database.View(context.Background(), func(txn *Txn) error {
+		ok, err := txn.Exists([]byte("alpha"))
+		if err != nil {
+			return err
+		}
+		if ok {
+			t.Fatalf("expected alpha to be deleted")
+		}
+		return nil
+	})
+	if err != nil {
+		t.Fatalf("View after delete error: %v", err)
+	}
+}
+
+func TestDatabaseUpdateErrorMapping(t *testing.T) {
+	database := openTestDB(t)
+
+	err := database.Update(context.Background(), func(txn *Txn) error {
+		_, err := txn.Get([]byte("missing"))
+		return err
+	})
+	if !errors.Is(err, ErrKeyNotFound) {
+		t.Fatalf("expected ErrKeyNotFound, got %v", err)
+	}
+
+	aborted := database.Update(context.Background(), func(txn *Txn) error {
+		return txn.Abort()
+	})
+	if aborted != nil {
+		t.Fatalf("expected nil after abort, got %v", aborted)
+	}
+}
+
+func TestDatabaseUpdateReadOnly(t *testing.T) {
+	path := t.TempDir()
+	writable, err := Open(Options{Path: path})
+	if err != nil {
+		t.Fatalf("prepare writable db: %v", err)
+	}
+	if err := writable.Close(); err != nil {
+		t.Fatalf("close writable db: %v", err)
+	}
+
+	database, err := Open(Options{Path: path, ReadOnly: true})
+	if err != nil {
+		t.Fatalf("open read-only db: %v", err)
+	}
+	t.Cleanup(func() {
+		if err := database.Close(); err != nil {
+			t.Fatalf("close db: %v", err)
+		}
+	})
+
+	err = database.Update(context.Background(), func(txn *Txn) error {
+		return txn.Set([]byte("k"), []byte("v"))
+	})
+	if !errors.Is(err, ErrReadOnly) {
+		t.Fatalf("expected ErrReadOnly for read-only DB, got %v", err)
+	}
+}
+
+func TestDatabaseUpdateRetryRespectsContext(t *testing.T) {
+	database := openTestDB(t)
+
+	ctx, cancel := context.WithCancel(context.Background())
+	cancel() // cancel immediately
+
+	err := database.Update(ctx, func(txn *Txn) error {
+		return txn.Set([]byte("k"), []byte("v"))
+	})
+	if !errors.Is(err, context.Canceled) {
+		t.Fatalf("expected context.Canceled, got %v", err)
+	}
+}
+
+func TestIterateReverseOrder(t *testing.T) {
+	database := openTestDB(t)
+
+	keys := [][]byte{
+		[]byte("alpha"),
+		[]byte("beta"),
+		[]byte("gamma"),
+	}
+	err := database.Update(context.Background(), func(txn *Txn) error {
+		for _, key := range keys {
+			if err := txn.Set(key, []byte(key)); err != nil {
+				return err
+			}
+		}
+		return nil
+	})
+	if err != nil {
+		t.Fatalf("populate keys: %v", err)
+	}
+
+	var seen []string
+	err = database.View(context.Background(), func(txn *Txn) error {
+		return txn.Iterate(IterateOptions{Reverse: true}, func(item Item) error {
+			seen = append(seen, item.KeyString())
+			return nil
+		})
+	})
+	if err != nil {
+		t.Fatalf("reverse iteration: %v", err)
+	}
+
+	expected := []string{"gamma", "beta", "alpha"}
+	if len(seen) != len(expected) {
+		t.Fatalf("unexpected number of items: got %d want %d", len(seen), len(expected))
+	}
+	for i, want := range expected {
+		if seen[i] != want {
+			t.Fatalf("unexpected key at %d: got %q want %q", i, seen[i], want)
+		}
+	}
+}
+
+func TestIncrementUint64InitialValue(t *testing.T) {
+	database := openTestDB(t)
+	var result uint64
+	err := database.Update(context.Background(), func(txn *Txn) error {
+		var err error
+		result, err = txn.IncrementUint64([]byte("counter"), 3)
+		return err
+	})
+	if err != nil {
+		t.Fatalf("increment: %v", err)
+	}
+	if result != 3 {
+		t.Fatalf("expected counter=3, got %d", result)
+	}
+}
+
+type spyLogger struct {
+	errors   int
+	warnings int
+	infos    int
+	debugs   int
+}
+
+func (s *spyLogger) Errorf(string, ...any)   { s.errors++ }
+func (s *spyLogger) Warningf(string, ...any) { s.warnings++ }
+func (s *spyLogger) Infof(string, ...any)    { s.infos++ }
+func (s *spyLogger) Debugf(string, ...any)   { s.debugs++ }
+
+func TestBadgerLoggerAdapter(t *testing.T) {
+	logger := &spyLogger{}
+	adapter := badgerLoggerAdapter{logger: logger}
+	adapter.Errorf("error")
+	adapter.Warningf("warn")
+	adapter.Infof("info")
+	adapter.Debugf("debug")
+
+	if logger.errors != 1 || logger.warnings != 1 || logger.infos != 1 || logger.debugs != 1 {
+		t.Fatalf("logger counts unexpected: %+v", logger)
+	}
+}
+
+func TestEnsureDir(t *testing.T) {
+	base := t.TempDir()
+	target := filepath.Join(base, "a", "b")
+	if err := ensureDir(target); err != nil {
+		t.Fatalf("ensureDir: %v", err)
+	}
+	info, err := os.Stat(target)
+	if err != nil {
+		t.Fatalf("stat target: %v", err)
+	}
+	if !info.IsDir() {
+		t.Fatalf("expected directory, got file")
+	}
+}
+
+func mustJSON(v any) []byte {
+	data, err := json.Marshal(v)
+	if err != nil {
+		panic(err)
+	}
+	return data
+}
+
+func TestDefaultPath(t *testing.T) {
+	path, err := DefaultPath()
+	if err != nil {
+		t.Fatalf("DefaultPath() error: %v", err)
+	}
+	if path == "" {
+		t.Fatalf("DefaultPath() returned empty string")
+	}
+}
+
+func TestOptionsApplyDefaults(t *testing.T) {
+	t.Run("DefaultsApplied", func(t *testing.T) {
+		opts, err := (Options{}).applyDefaults()
+		if err != nil {
+			t.Fatalf("applyDefaults: %v", err)
+		}
+		if opts.Path == "" {
+			t.Fatalf("expected Path to be populated")
+		}
+		if opts.Logger == nil {
+			t.Fatalf("expected Logger to be non-nil")
+		}
+		if opts.MaxTxnRetries != defaultTxnMaxRetries {
+			t.Fatalf("expected MaxTxnRetries=%d, got %d", defaultTxnMaxRetries, opts.MaxTxnRetries)
+		}
+		if opts.ConflictBackoff != defaultConflictBackoff {
+			t.Fatalf("expected ConflictBackoff=%s, got %s", defaultConflictBackoff, opts.ConflictBackoff)
+		}
+		if !opts.SyncWrites {
+			t.Fatalf("expected SyncWrites default true")
+		}
+	})
+
+	t.Run("NegativeRetries", func(t *testing.T) {
+		_, err := (Options{MaxTxnRetries: -1}).applyDefaults()
+		if err == nil {
+			t.Fatalf("expected error for negative MaxTxnRetries")
+		}
+	})
+
+	t.Run("RespectExistingValues", func(t *testing.T) {
+		opts, err := (Options{
+			Path:            "/tmp/custom",
+			Logger:          &spyLogger{},
+			MaxTxnRetries:   3,
+			ConflictBackoff: time.Second,
+			ReadOnly:        true,
+		}).applyDefaults()
+		if err != nil {
+			t.Fatalf("applyDefaults: %v", err)
+		}
+		if opts.Path != "/tmp/custom" {
+			t.Fatalf("expected Path to be preserved, got %q", opts.Path)
+		}
+		if opts.MaxTxnRetries != 3 {
+			t.Fatalf("expected MaxTxnRetries=3, got %d", opts.MaxTxnRetries)
+		}
+		if opts.ConflictBackoff != time.Second {
+			t.Fatalf("expected ConflictBackoff=1s, got %s", opts.ConflictBackoff)
+		}
+		if opts.SyncWrites {
+			t.Fatalf("expected SyncWrites to remain false for read-only")
+		}
+		if _, ok := opts.Logger.(*spyLogger); !ok {
+			t.Fatalf("expected Logger to remain spyLogger")
+		}
+	})
+}
+
+func TestCanonicalizeDir(t *testing.T) {
+	dir := t.TempDir()
+	canonical, err := CanonicalizeDir(dir)
+	if err != nil {
+		t.Fatalf("CanonicalizeDir error: %v", err)
+	}
+	if canonical == "" {
+		t.Fatalf("expected non-empty canonical path")
+	}
+	if runtime.GOOS != "windows" && !strings.HasPrefix(canonical, "/") {
+		t.Fatalf("expected absolute path, got %q", canonical)
+	}
+}
+
+func TestDirHashConsistency(t *testing.T) {
+	dir := t.TempDir()
+	canonical, err := CanonicalizeDir(dir)
+	if err != nil {
+		t.Fatalf("canonicalize: %v", err)
+	}
+	hash1 := DirHash(canonical)
+	hash2 := DirHash(canonical)
+	if hash1 != hash2 {
+		t.Fatalf("expected consistent hashes, got %q vs %q", hash1, hash2)
+	}
+	if len(hash1) != 64 {
+		t.Fatalf("expected 64 hex chars, got %d", len(hash1))
+	}
+}
+
+func TestCanonicalizeAndHash(t *testing.T) {
+	dir := t.TempDir()
+	canonical, hash, err := CanonicalizeAndHash(dir)
+	if err != nil {
+		t.Fatalf("CanonicalizeAndHash error: %v", err)
+	}
+	if canonical == "" || hash == "" {
+		t.Fatalf("expected non-empty canonical/hash")
+	}
+}
+
+func TestParentWalk(t *testing.T) {
+	dir := t.TempDir()
+	canonical, err := CanonicalizeDir(dir)
+	if err != nil {
+		t.Fatalf("canonicalize: %v", err)
+	}
+	parents := ParentWalk(canonical)
+	if len(parents) == 0 {
+		t.Fatalf("expected at least one parent")
+	}
+	if parents[0] != canonical {
+		t.Fatalf("expected first element to be input path")
+	}
+	seenRoot := false
+	for _, p := range parents {
+		if p == "/" || (runtime.GOOS == "windows" && len(p) == 3 && p[1] == ':' && p[2] == '/') {
+			seenRoot = true
+		}
+	}
+	if !seenRoot {
+		t.Fatalf("expected parent list to reach root, got %v", parents)
+	}
+}
+
+func TestKeysAndPrefixes(t *testing.T) {
+	if got := string(KeySchemaVersion()); got != "meta/schema_version" {
+		t.Fatalf("unexpected schema key: %q", got)
+	}
+	if got := string(KeyDirActive("hash")); got != "dir/hash/active" {
+		t.Fatalf("unexpected dir active key: %q", got)
+	}
+	if got := string(KeyDirArchived("hash", "ts", "sid")); got != "dir/hash/archived/ts/sid" {
+		t.Fatalf("unexpected dir archived key: %q", got)
+	}
+	if got := string(KeyIdxActive("sid")); got != "idx/active/sid" {
+		t.Fatalf("unexpected idx active key: %q", got)
+	}
+	if got := string(KeyIdxArchived("ts", "sid")); got != "idx/archived/ts/sid" {
+		t.Fatalf("unexpected idx archived key: %q", got)
+	}
+	if got := string(KeySessionMeta("sid")); got != "s/sid/meta" {
+		t.Fatalf("unexpected session meta key: %q", got)
+	}
+	if got := string(KeySessionGoal("sid")); got != "s/sid/goal" {
+		t.Fatalf("unexpected session goal key: %q", got)
+	}
+	if got := string(KeySessionTask("sid", "tid")); got != "s/sid/task/tid" {
+		t.Fatalf("unexpected session task key: %q", got)
+	}
+	if got := string(KeySessionTaskStatusIndex("sid", "pending", "tid")); got != "s/sid/idx/status/pending/tid" {
+		t.Fatalf("unexpected status idx key: %q", got)
+	}
+	if got := string(KeySessionEventSeq("sid")); got != "s/sid/meta/evt_seq" {
+		t.Fatalf("unexpected event seq key: %q", got)
+	}
+	if got := string(KeySessionEvent("sid", 10)); got != "s/sid/evt/000000000000000a" {
+		t.Fatalf("unexpected session event key: %q", got)
+	}
+	if prefix := string(PrefixSessionTasks("sid")); prefix != "s/sid/task" {
+		t.Fatalf("unexpected tasks prefix: %q", prefix)
+	}
+	if prefix := string(PrefixSessionStatusIndex("sid", "pending")); prefix != "s/sid/idx/status/pending" {
+		t.Fatalf("unexpected status prefix: %q", prefix)
+	}
+	if prefix := string(PrefixSessionEvents("sid")); prefix != "s/sid/evt" {
+		t.Fatalf("unexpected events prefix: %q", prefix)
+	}
+	if prefix := string(PrefixDirArchived("hash")); prefix != "dir/hash/archived" {
+		t.Fatalf("unexpected dir archived prefix: %q", prefix)
+	}
+	if prefix := string(PrefixIdxActive()); prefix != "idx/active" {
+		t.Fatalf("unexpected idx active prefix: %q", prefix)
+	}
+	if prefix := string(PrefixIdxArchived()); prefix != "idx/archived" {
+		t.Fatalf("unexpected idx archived prefix: %q", prefix)
+	}
+}
+
+func TestEncodingHelpers(t *testing.T) {
+	var buf [8]byte
+	putUint64(buf[:], 123)
+	if got := readUint64(buf[:]); got != 123 {
+		t.Fatalf("unexpected roundtrip: got %d want 123", got)
+	}
+	if _, err := decodeUint64([]byte{1, 2}); err == nil {
+		t.Fatalf("expected error for short buffer")
+	}
+	if hex := Uint64Hex(10); hex != "000000000000000a" {
+		t.Fatalf("unexpected Uint64Hex: %q", hex)
+	}
+	if hex := encodeHex([]byte{0xde, 0xad}); hex != "dead" {
+		t.Fatalf("unexpected encodeHex: %q", hex)
+	}
+}