com um clique
database
Database skill for the ikigai project
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Menu
Database skill for the ikigai project
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Baseado na classificação ocupacional SOC
Automated quality check loops with escalation and fix sub-agents
JSON-based end-to-end test format, runner, and mock provider
Jujutsu (jj) skill for the ikigai project
How to write effective Ralph goals for Ikigai-driven workflows
Create and manage Ralph goals from Ikigai using the real ralph-pipeline scripts
Create repositories using the real ralph-pipeline repo-create script
| name | database |
| description | Database skill for the ikigai project |
PostgreSQL-backed event stream architecture with agent registry, session management, message persistence, inter-agent mail, and conversation replay using talloc-based memory management.
Tracks applied migrations for incremental schema updates.
| Column | Type | Constraints | Description |
|---|---|---|---|
| schema_version | INTEGER | PRIMARY KEY | Current schema version number |
Current version: 5
Groups messages by conversation session with persistent state across app launches.
| Column | Type | Constraints | Description |
|---|---|---|---|
| id | BIGSERIAL | PRIMARY KEY | Session identifier |
| started_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | Session start timestamp |
| ended_at | TIMESTAMPTZ | NULL | Session end timestamp (NULL = active) |
| title | TEXT | NULL | Optional user-defined session title |
Indexes:
idx_sessions_started: started_at DESC for recent session lookupEvent stream storage for conversation timeline with support for replay, rollback, and agent attribution.
| Column | Type | Constraints | Description |
|---|---|---|---|
| id | BIGSERIAL | PRIMARY KEY | Message identifier |
| session_id | BIGINT | NOT NULL, FK sessions(id) ON DELETE CASCADE | Parent session |
| kind | TEXT | NOT NULL | Event type discriminator |
| content | TEXT | NULL | Message text (NULL for clear) |
| data | JSONB | NULL | Event metadata (LLM params, etc.) |
| created_at | TIMESTAMPTZ | NOT NULL, DEFAULT NOW() | Event timestamp |
| agent_uuid | TEXT | NULL, FK agents(uuid) | Agent that created this message |
Event Kinds:
clear: Context reset (session start or /clear command)system: System prompt messageuser: User input messageassistant: LLM response messagetool_call: Tool invocation requesttool_result: Tool execution resultmark: Checkpoint created by /mark commandrewind: Rollback operation created by /rewind commandagent_killed: Agent termination eventcommand: Slash command output for persistence across restartsfork: Fork event recorded in both parent and child historiesusage: Token usage tracking eventIndexes:
idx_messages_session: (session_id, created_at) for chronological event stream processingidx_messages_search: GIN index on to_tsvector('english', content) for full-text searchidx_messages_agent: (agent_uuid, id) for efficient agent-based range queriesAgent registry tracking agent lifecycle, parent-child relationships, and status transitions.
| Column | Type | Constraints | Description |
|---|---|---|---|
| uuid | TEXT | PRIMARY KEY | Base64url agent UUID (22 chars) |
| name | TEXT | NULL | Optional human-friendly name |
| parent_uuid | TEXT | NULL, FK agents(uuid) ON DELETE RESTRICT | Parent agent (NULL for root) |
| fork_message_id | BIGINT | NULL | Message ID at fork point |
| status | agent_status | NOT NULL, DEFAULT 'running' | Agent status (running/dead) |
| created_at | BIGINT | NOT NULL | Unix epoch timestamp (seconds) |
| ended_at | BIGINT | NULL | Unix epoch timestamp (NULL if running) |
| provider | TEXT | NULL | LLM provider (anthropic, openai, etc.) |
| model | TEXT | NULL | Model identifier (claude-opus-4.5, etc.) |
| thinking_level | TEXT | NULL | Thinking budget/level for extended thinking |
Enum Types:
agent_status: 'running', 'dead'Indexes:
idx_agents_parent: parent_uuid for child queriesidx_agents_status: status for running agent queriesConstraints:
parent_uuid=NULLInter-agent messaging table for Erlang-style message passing between agents.
| Column | Type | Constraints | Description |
|---|---|---|---|
| id | BIGSERIAL | PRIMARY KEY | Mail message identifier |
| session_id | BIGINT | NOT NULL, FK sessions(id) ON DELETE CASCADE | Parent session |
| from_uuid | TEXT | NOT NULL | Sender agent UUID |
| to_uuid | TEXT | NOT NULL | Recipient agent UUID |
| body | TEXT | NOT NULL | Message body |
| timestamp | BIGINT | NOT NULL | Unix epoch timestamp (seconds) |
| read | INTEGER | NOT NULL, DEFAULT 0 | Read status (0=unread, 1=read) |
Indexes:
idx_mail_recipient: (session_id, to_uuid, read) for inbox queriesDesign notes:
Database context managing PostgreSQL connection lifecycle.
typedef struct {
PGconn *conn; // PostgreSQL connection handle
} ik_db_ctx_t;
PQfinish() on conntalloc_free() on parent releases everythingCanonical message structure representing a single event.
typedef struct {
int64_t id; // DB row ID (0 if not from DB)
char *kind; // Message kind discriminator
char *content; // Message text content or human-readable summary
char *data_json; // Structured data for tool messages (NULL for text messages)
} ik_msg_t;
Conversation kinds (included in LLM context):
system, user, assistant, tool_call, tool_result, toolMetadata kinds (not included in LLM context):
clear, mark, rewind, agent_killed, command, fork, usageCheckpoint information for conversation rollback.
typedef struct {
int64_t message_id; // ID of the mark event
char *label; // User label or NULL
size_t context_idx; // Position in context array when mark was created
} ik_replay_mark_t;
Dynamic array of checkpoint marks.
typedef struct {
ik_replay_mark_t *marks; // Dynamic array of marks
size_t count; // Number of marks
size_t capacity; // Allocated capacity
} ik_replay_mark_stack_t;
Dynamic array of messages representing conversation state with mark stack for rollback.
typedef struct {
ik_msg_t **messages; // Dynamic array of message pointers (unified type)
size_t count; // Number of messages in context
size_t capacity; // Allocated capacity
ik_replay_mark_stack_t mark_stack; // Stack of checkpoint marks
} ik_replay_context_t;
Defines a subset of messages to query for agent-based replay.
typedef struct {
char *agent_uuid; // Which agent's messages to query
int64_t start_id; // Start AFTER this message ID (0 = from beginning)
int64_t end_id; // End AT this message ID (0 = no limit, i.e., leaf)
} ik_replay_range_t;
Semantics:
start_id is exclusive (query messages AFTER this ID)end_id is inclusive (query messages up to and including this ID)end_id = 0 means "no upper limit" (used for leaf agent)Agent row structure for query results.
typedef struct {
char *uuid;
char *name;
char *parent_uuid;
char *fork_message_id;
char *status;
int64_t created_at;
int64_t ended_at; // 0 if still running
char *provider; // LLM provider (nullable)
char *model; // Model identifier (nullable)
char *thinking_level; // Thinking budget/level (nullable)
} ik_db_agent_row_t;
Mail message structure for inter-agent messaging.
typedef struct ik_mail_msg {
int64_t id;
char *from_uuid;
char *to_uuid;
char *body;
int64_t timestamp;
bool read;
} ik_mail_msg_t;
Wrapper for PGresult with automatic cleanup via talloc destructor.
typedef struct {
PGresult *pg_result;
} ik_pg_result_wrapper_t;
PQclear() when talloc context is freedInitialize database connection with default migrations directory.
res_t ik_db_init(TALLOC_CTX *ctx, const char *conn_str, ik_db_ctx_t **out_ctx);
ctx: Talloc context for allocations (must not be NULL)conn_str: PostgreSQL connection string (e.g., postgresql://user:pass@host:port/dbname)out_ctx: Output parameter for database context (must not be NULL)OK with db_ctx on success, ERR on failureERR_INVALID_ARG, ERR_DB_CONNECT, ERR_DB_MIGRATE./share/ikigai/migrations/Initialize database connection with custom migrations directory.
res_t ik_db_init_with_migrations(TALLOC_CTX *ctx, const char *conn_str,
const char *migrations_dir, ik_db_ctx_t **out_ctx);
ctx: Talloc context for allocations (must not be NULL)conn_str: PostgreSQL connection string (must not be NULL or empty)migrations_dir: Path to migrations directory (must not be NULL)out_ctx: Output parameter for database context (must not be NULL)OK with db_ctx on success, ERR on failureERR_INVALID_ARG, ERR_DB_CONNECT, ERR_DB_MIGRATE, ERR_IOBegin transaction.
res_t ik_db_begin(ik_db_ctx_t *db_ctx);
db_ctx: Database context (must not be NULL)OK on success, ERR on failureCommit transaction.
res_t ik_db_commit(ik_db_ctx_t *db_ctx);
db_ctx: Database context (must not be NULL)OK on success, ERR on failureRollback transaction.
res_t ik_db_rollback(ik_db_ctx_t *db_ctx);
db_ctx: Database context (must not be NULL)OK on success, ERR on failureCreate a new session with started_at=NOW() and ended_at=NULL.
res_t ik_db_session_create(ik_db_ctx_t *db_ctx, int64_t *session_id_out);
db_ctx: Database context (must not be NULL)session_id_out: Output parameter for new session ID (must not be NULL)OK with session_id on success, ERR on failureGet the most recent active session (ended_at IS NULL).
res_t ik_db_session_get_active(ik_db_ctx_t *db_ctx, int64_t *session_id_out);
db_ctx: Database context (must not be NULL)session_id_out: Output parameter for session ID (must not be NULL)OK with session_id (0 if none found), ERR on database failureEnd a session by setting ended_at=NOW().
res_t ik_db_session_end(ik_db_ctx_t *db_ctx, int64_t session_id);
db_ctx: Database context (must not be NULL)session_id: Session ID to end (must be > 0)OK on success, ERR on failureget_activeInsert a message event into the database.
res_t ik_db_message_insert(ik_db_ctx_t *db,
int64_t session_id,
const char *agent_uuid,
const char *kind,
const char *content,
const char *data_json);
db: Database connection context (must not be NULL)session_id: Session ID (must be positive, references sessions.id)agent_uuid: Agent UUID (may be NULL for backward compatibility)kind: Event kind string (must be valid kind)content: Message content (may be NULL for clear events, empty string allowed)data_json: JSONB data as JSON string (may be NULL)OK on success, ERR on failure (invalid params or database error)Validate that a kind string is one of the allowed event kinds.
bool ik_db_message_is_valid_kind(const char *kind);
kind: The kind string to validate (may be NULL)Create a canonical tool result message with kind="tool_result".
ik_msg_t *ik_msg_create_tool_result(void *parent,
const char *tool_call_id,
const char *name,
const char *output,
bool success,
const char *content);
parent: Talloc context for allocation (can be NULL for root)tool_call_id: Unique tool call ID (e.g., "call_abc123")name: Tool name (e.g., "glob", "file_read")output: Tool output string (can be empty string)success: Whether the tool executed successfully (true/false)content: Human-readable summary for the message (e.g., "3 files found")ik_msg_t struct (owned by parent), or NULL on OOMtalloc_free() releases allCheck if a message kind should be included in LLM conversation context.
bool ik_msg_is_conversation_kind(const char *kind);
kind: Message kind string (e.g., "user", "assistant", "clear")Insert agent into registry.
res_t ik_db_agent_insert(ik_db_ctx_t *db_ctx, const ik_agent_ctx_t *agent);
db_ctx: Database context (must not be NULL)agent: Agent context with uuid, parent_uuid, created_at set (must not be NULL)OK on success, ERR on failureMark agent as dead.
res_t ik_db_agent_mark_dead(ik_db_ctx_t *db_ctx, const char *uuid);
db_ctx: Database context (must not be NULL)uuid: Agent UUID to update (must not be NULL)OK on success, ERR on failureLookup agent by UUID.
res_t ik_db_agent_get(ik_db_ctx_t *db_ctx, TALLOC_CTX *ctx,
const char *uuid, ik_db_agent_row_t **out);
db_ctx: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)uuid: Agent UUID to lookup (must not be NULL)out: Output parameter for agent row (must not be NULL)OK with agent row on success, ERR if not found or on failureList all running agents.
res_t ik_db_agent_list_running(ik_db_ctx_t *db_ctx, TALLOC_CTX *ctx,
ik_db_agent_row_t ***out, size_t *count);
db_ctx: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)out: Output parameter for array of agent row pointers (must not be NULL)count: Output parameter for array size (must not be NULL)OK with agent rows on success, ERR on failureGet children of an agent.
res_t ik_db_agent_get_children(ik_db_ctx_t *db_ctx, TALLOC_CTX *ctx,
const char *parent_uuid,
ik_db_agent_row_t ***out, size_t *count);
db_ctx: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)parent_uuid: Parent agent UUID (must not be NULL)out: Output parameter for array of agent row pointers (must not be NULL)count: Output parameter for array size (must not be NULL)OK with agent rows on success, ERR on failureGet parent agent.
res_t ik_db_agent_get_parent(ik_db_ctx_t *db_ctx, TALLOC_CTX *ctx,
const char *uuid, ik_db_agent_row_t **out);
db_ctx: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)uuid: Child agent UUID (must not be NULL)out: Output parameter for parent agent row (must not be NULL)OK with parent row (or NULL for root) on success, ERR on failureEnsure Agent 0 exists in registry.
res_t ik_db_ensure_agent_zero(ik_db_ctx_t *db, char **out_uuid);
db: Database context (must not be NULL)out_uuid: Output parameter for Agent 0's UUID (must not be NULL)OK with UUID on success, ERR on failureGet the last message ID for an agent.
res_t ik_db_agent_get_last_message_id(ik_db_ctx_t *db_ctx, const char *agent_uuid,
int64_t *out_message_id);
db_ctx: Database context (must not be NULL)agent_uuid: Agent UUID (must not be NULL)out_message_id: Output parameter for last message ID (must not be NULL)OK on success, ERR on failureUpdate agent provider configuration.
res_t ik_db_agent_update_provider(ik_db_ctx_t *db_ctx, const char *uuid,
const char *provider, const char *model,
const char *thinking_level);
db_ctx: Database context (must not be NULL)uuid: Agent UUID to update (must not be NULL)provider: Provider name (may be NULL)model: Model identifier (may be NULL)thinking_level: Thinking budget/level (may be NULL)OK on success, ERR_DB_CONNECT on database errorInsert mail message (sets msg->id on success).
res_t ik_db_mail_insert(ik_db_ctx_t *db, int64_t session_id,
ik_mail_msg_t *msg);
db: Database context (must not be NULL)session_id: Session ID (must be positive)msg: Mail message (must not be NULL)OK on success, ERR on failureGet inbox for agent (unread first, then by timestamp desc).
res_t ik_db_mail_inbox(ik_db_ctx_t *db, TALLOC_CTX *ctx,
int64_t session_id, const char *to_uuid,
ik_mail_msg_t ***out, size_t *count);
db: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)session_id: Session ID (must be positive)to_uuid: Recipient agent UUID (must not be NULL)out: Output parameter for array of mail message pointers (must not be NULL)count: Output parameter for array size (must not be NULL)OK on success, ERR on failureGet filtered inbox by sender (unread first, then by timestamp desc).
res_t ik_db_mail_inbox_filtered(ik_db_ctx_t *db, TALLOC_CTX *ctx,
int64_t session_id, const char *to_uuid,
const char *from_uuid,
ik_mail_msg_t ***out, size_t *count);
db: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)session_id: Session ID (must be positive)to_uuid: Recipient agent UUID (must not be NULL)from_uuid: Sender agent UUID filter (must not be NULL)out: Output parameter for array of mail message pointers (must not be NULL)count: Output parameter for array size (must not be NULL)OK on success, ERR on failureMark message as read.
res_t ik_db_mail_mark_read(ik_db_ctx_t *db, int64_t mail_id);
db: Database context (must not be NULL)mail_id: Mail message ID (must be positive)OK on success, ERR on failureDelete message (validates recipient owns the message).
res_t ik_db_mail_delete(ik_db_ctx_t *db, int64_t mail_id,
const char *recipient_uuid);
db: Database context (must not be NULL)mail_id: Mail message ID (must be positive)recipient_uuid: Recipient agent UUID (must not be NULL)OK on success, ERR on failureCreate a mail message structure.
ik_mail_msg_t *ik_mail_msg_create(TALLOC_CTX *ctx,
const char *from_uuid,
const char *to_uuid,
const char *body);
ctx: Talloc context for allocationfrom_uuid: Sender agent UUIDto_uuid: Recipient agent UUIDbody: Message bodyLoad messages from database and replay to build conversation context (TEST-ONLY).
res_t ik_db_messages_load(TALLOC_CTX *ctx, ik_db_ctx_t *db_ctx, int64_t session_id, ik_logger_t *logger);
ctx: Talloc context for allocations (must not be NULL)db_ctx: Database connection context (must not be NULL)session_id: Session ID to load messages for (must be positive)logger: Logger instance (may be NULL)OK with ik_replay_context_t* on success, ERR on failureik_agent_replay_history() insteadcreated_atclear: Empty context (set count = 0)system/user/assistant/tool_call/tool_result: Append to context arraymark: Append to context and push mark onto mark stackrewind: Truncate context to target mark's position, append rewind eventFind most recent clear event for an agent.
res_t ik_agent_find_clear(ik_db_ctx_t *db_ctx, TALLOC_CTX *ctx,
const char *agent_uuid, int64_t max_id,
int64_t *clear_id_out);
db_ctx: Database context (must not be NULL)ctx: Talloc context for error allocation (must not be NULL)agent_uuid: Agent UUID to search (must not be NULL)max_id: Maximum message ID to consider (0 = no limit)clear_id_out: Output for clear message ID (0 if not found)OK on success, ERR on database failureBuild replay ranges by walking ancestor chain.
res_t ik_agent_build_replay_ranges(ik_db_ctx_t *db_ctx, TALLOC_CTX *ctx,
const char *agent_uuid,
ik_replay_range_t **ranges_out,
size_t *count_out);
db_ctx: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)agent_uuid: Leaf agent UUID to start from (must not be NULL)ranges_out: Output for array of replay ranges (must not be NULL)count_out: Output for number of ranges (must not be NULL)OK on success, ERR on failureQuery messages for a single replay range.
res_t ik_agent_query_range(ik_db_ctx_t *db_ctx, TALLOC_CTX *ctx,
const ik_replay_range_t *range,
ik_msg_t ***messages_out,
size_t *count_out);
db_ctx: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)range: Replay range specification (must not be NULL)messages_out: Output for array of message pointers (must not be NULL)count_out: Output for number of messages (must not be NULL)OK on success, ERR on failureWHERE agent_uuid=$1 AND id>$2 AND ($3=0 OR id<=$3)Replay history for an agent using range-based algorithm.
res_t ik_agent_replay_history(ik_db_ctx_t *db_ctx, TALLOC_CTX *ctx,
const char *agent_uuid,
ik_replay_context_t **ctx_out);
db_ctx: Database context (must not be NULL)ctx: Talloc context for result allocation (must not be NULL)agent_uuid: Agent UUID to replay (must not be NULL)ctx_out: Output for replay context (must not be NULL)OK on success, ERR on failurebuild_replay_ranges and query_range to reconstruct agent's full conversation context on startupApply all pending database migrations from specified directory.
res_t ik_db_migrate(ik_db_ctx_t *db_ctx, const char *migrations_dir);
db_ctx: Database context (must not be NULL)migrations_dir: Path to migrations directory (must not be NULL)OK on success, ERR on failureERR_INVALID_ARG, ERR_IO, ERR_DB_MIGRATEschema_metadata table (0 if table doesn't exist).sql files001-initial-schema.sql → 1)PQexec() within transactionNNN-description.sql (e.g., 001-initial-schema.sql, 002-agents-table.sql)BEGIN/COMMIT for atomicityschema_metadata.schema_versionschema_metadata, sessions, and messages tables with indexesagents table with agent_status enum, parent_uuid FK, and indexesagent_uuid column to messages table with FK and indexmail table for inter-agent messaging with indexesprovider, model, and thinking_level columns to agents table for multi-provider support; truncates all tables for clean slateCRITICAL: NEVER call PQclear() manually. Always wrap with ik_db_wrap_pg_result().
Wrap PGresult with automatic cleanup via talloc destructor.
ik_pg_result_wrapper_t *ik_db_wrap_pg_result(TALLOC_CTX *ctx, PGresult *pg_res);
ctx: Parent talloc contextpg_res: PGresult to wrap (may be NULL)PQexec() and PQexecParams() results to prevent leaksPQclear() when parent talloc context is freedUsage pattern:
// Wrap immediately after PQexec/PQexecParams
ik_pg_result_wrapper_t *wrapper = ik_db_wrap_pg_result(tmp_ctx, PQexec(conn, query));
PGresult *res = wrapper->pg_result;
// Use normally - no manual cleanup needed
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
talloc_free(tmp_ctx); // Destructor calls PQclear() automatically
return ERR(...);
}
This integrates PGresult (malloc-based) with talloc's hierarchical memory model.
Most tests use transaction isolation for speed:
static const char *DB_NAME;
static ik_db_ctx_t *db;
static TALLOC_CTX *test_ctx;
// Suite setup (once per file)
DB_NAME = ik_test_db_name(NULL, __FILE__);
ik_test_db_create(DB_NAME);
ik_test_db_migrate(NULL, DB_NAME);
// Per-test setup
test_ctx = talloc_new(NULL);
ik_test_db_connect(test_ctx, DB_NAME, &db);
ik_test_db_begin(db);
// Per-test teardown
ik_test_db_rollback(db);
talloc_free(test_ctx);
// Suite teardown (once per file)
ik_test_db_destroy(DB_NAME);
Rolemodel: tests/unit/repl/repl_actions_db_basic_test.c
Key benefits:
Migration tests use empty database without migrations:
DB_NAME = ik_test_db_name(NULL, __FILE__);
ik_test_db_create(DB_NAME); // No migrate call
// ... test migration logic ...
ik_test_db_destroy(DB_NAME);
Derive database name from source file path.
const char *ik_test_db_name(TALLOC_CTX *ctx, const char *file_path);
tests/unit/db/session_test.c → ikigai_test_session_testCreate test database (drops if exists).
res_t ik_test_db_create(const char *db_name);
Run migrations on test database from ./share/ikigai/migrations/ directory.
res_t ik_test_db_migrate(TALLOC_CTX *ctx, const char *db_name);
Open connection to test database (no migrations).
res_t ik_test_db_connect(TALLOC_CTX *ctx, const char *db_name, ik_db_ctx_t **out);
Begin transaction for test isolation.
res_t ik_test_db_begin(ik_db_ctx_t *db);
Rollback transaction to discard test changes.
res_t ik_test_db_rollback(ik_db_ctx_t *db);
Truncate all application tables (for non-transactional tests).
res_t ik_test_db_truncate_all(ik_db_ctx_t *db);
TRUNCATE TABLE messages, sessions, agents, mail RESTART IDENTITY CASCADEDrop test database completely.
res_t ik_test_db_destroy(const char *db_name);
Fixed configuration - hardcoded in tests/test_utils.c:
ikigaiikigailocalhost (override with PGHOST environment variable)postgres (for CREATE/DROP DATABASE operations)ikigai_test_<basename>Connection strings:
ADMIN_DB_URL = "postgresql://ikigai:ikigai@localhost/postgres"
TEST_DB_URL_PREFIX = "postgresql://ikigai:ikigai@localhost/"
Database setup requirements:
ikigai with password ikigai created| Variable | Purpose |
|---|---|
DATABASE_URL | Production connection string |
PGHOST | Override PostgreSQL host (default: localhost) |
SKIP_LIVE_DB_TESTS | Set to 1 to skip DB tests |
| File | Purpose |
|---|---|
share/ikigai/migrations/001-initial-schema.sql | Initial database schema with sessions and messages tables |
share/ikigai/migrations/002-agents-table.sql | Agent registry table with parent-child relationships |
share/ikigai/migrations/003-messages-agent-uuid.sql | Add agent_uuid column to messages table |
share/ikigai/migrations/004-mail-table.sql | Inter-agent mail table for message passing |
share/ikigai/migrations/005-multi-provider.sql | Add provider, model, thinking_level to agents table |
src/db/connection.h | Database connection API (init, destructor, transactions) |
src/db/connection.c | Connection implementation with validation and migration runner |
src/db/session.h | Session CRUD API (create, get_active, end) |
src/db/session.c | Session implementation with parameterized queries |
src/db/message.h | Message insertion API and tool result helpers |
src/db/message.c | Message implementation with kind validation and yyjson |
src/db/agent.h | Agent registry API (insert, mark_dead, queries, update_provider) |
src/db/agent.c | Agent implementation with parent-child queries |
src/db/agent_row.h | Agent row parsing helper API |
src/db/agent_row.c | Agent row parsing from PGresult |
src/db/agent_zero.h | Agent 0 (root agent) creation API |
src/db/agent_zero.c | Agent 0 creation and orphan message adoption |
src/db/mail.h | Mail API (insert, inbox, mark_read, delete) |
src/db/mail.c | Mail implementation with inbox filtering |
src/db/replay.h | Replay context structures and message loading API |
src/db/replay.c | Event stream replay algorithm with mark/rewind support |
src/db/agent_replay.h | Agent-based replay API (find_clear, build_ranges, query_range) |
src/db/agent_replay.c | Agent replay implementation with ancestry chain walking |
src/db/migration.h | Migration system API |
src/db/migration.c | Migration scanner, parser, and executor |
src/db/pg_result.h | PGresult wrapper API |
src/db/pg_result.c | PGresult wrapper implementation with talloc destructor |
src/msg.h | Canonical message structure and kind validation |
src/mail/msg.h | Mail message structure |
tests/test_utils.h | Database test utilities header |
tests/test_utils.c | Database test utilities implementation |
tests/unit/test_utils/db_test.c | DB test utilities tests |
memory - talloc-based memory management and ownership ruleserrors - Result types with OK()/ERR() patternssource-code - Map of all src/*.c files by functional area