skald/entrypoint.sh
Kayos f575ad3722 scaffold v0.1: postgres+pgvector inside-container, schema, markdown ingest, CLI
Skald is a generic story-writer. The database is the product; the
binary is the tooling. Everything story-specific lives in rows, not
in code. cwho's monorepo + binary-per-role pattern transplanted to
this domain.

What this commit ships:
- Cargo workspace (resolver=3, edition 2024): skald-core (lib) +
  skald (bin)
- Migration 0001: stories, characters, canon_facts, chapters,
  chapter_summaries, passages (vector(1536)), generation_runs,
  audit_findings, tags. pgvector + pg_trgm extensions. ivfflat
  index deferred until we have data (post-import the first ~1k
  passages and add the index).
- skald-core::ingest — markdown parser for the cwho/coast-down shape:
  '# Title' → '## Chapter N — date' headings → '# Continuity Bible'
  section with character roster (real + fictional sub-sections) +
  setting / mystery / historical / liberty / hook sub-sections.
  Decomposed into structured rows; original bullet body preserved
  in key_facts/body fields for fidelity. 6 unit tests cover the
  shape.
- skald-core::db — Postgres connection pool + migration runner.
- skald-core::models — row types via sqlx::FromRow.
- skald binary — clap CLI: 'serve' (http + migrations) and
  'import-markdown' (one-shot ingest).
- Dockerfile — multi-stage: rust:1.95-bookworm builder, pgvector/
  pgvector:pg17 runtime, tini under PID 1, custom entrypoint.sh
  that boots embedded postgres then execs skald serve.
- compose.yml — singleton container, postgres data in volume,
  story corpus mounted read-only at /seed.

Decisions locked 2026-05-13:
1. DB in same container 'till we have a real working tool' (cobb)
2. postgres+pgvector (NOT sqlite) — keeps semantic-search story
3. Network-not-socket connection (postgresql://localhost:5432) from
   day one so future split is config-only, not code-rewrite

Not yet wired:
- Web UI
- clawdforge calls (gen → cleanup → canon-audit pipeline)
- Embedding pass
- TTS sidecar
2026-05-13 09:04:28 -07:00

37 lines
1.4 KiB
Bash

#!/usr/bin/env bash
# Skald container entrypoint.
#
# Boots the embedded postgres via the pgvector image's own
# docker-entrypoint, waits for it to accept connections, then execs
# `skald` in the foreground. Tini is PID 1 (so it can reap zombies +
# forward signals); we are PID 2; postgres becomes our child.
#
# This is explicitly "DB in the same container, for now" — when we
# split the DB out (see project notes), the entrypoint reduces to
# `exec /usr/local/bin/skald "$@"` and the pg startup goes away.
set -eo pipefail
# Hand off to the pgvector image's own initdb + start dance.
/usr/local/bin/docker-entrypoint.sh postgres &
PG_PID=$!
# Wait for postgres to accept connections — initdb-on-first-run can
# take a few seconds. 60s cap so we don't hang forever.
for i in $(seq 1 120); do
if pg_isready -h localhost -p 5432 -U "${POSTGRES_USER:-skald}" -d "${POSTGRES_DB:-skald}" >/dev/null 2>&1; then
echo "skald-entrypoint: postgres ready after ${i} polls"
break
fi
if [ "$i" -eq 120 ]; then
echo "skald-entrypoint: postgres failed to become ready after 60s" >&2
kill "$PG_PID" 2>/dev/null || true
exit 1
fi
sleep 0.5
done
# Exec skald in the foreground. Container's lifecycle now tracks
# skald — if skald exits, the container exits, postgres comes down
# with it, restart policy decides whether to recycle.
exec /usr/local/bin/skald "$@"