Data Store Mapping Guide¶
The course modules show YAML examples by default. If you chose SQLite in the setup wizard, use this guide to translate each YAML construct to its database equivalent.
The architecture (manifest, sentinel, gates, tiers) is identical regardless of data store. Only the source of rules, checks, and config changes.
Config (startup-config.yaml → config table)¶
Rules (rules/*.md → rules table)¶
tiers:
tier1:
- name: core-rules
source: rules/core-rules.md
description: "Project rules and conventions"
Then create the file rules/core-rules.md with rule content.
INSERT INTO rules (name, content, category, tier, description)
VALUES (
'core-rules',
'### project-language
This project uses TypeScript 5.x with strict mode.
### test-framework
Tests use Vitest, not Jest. Run with: pnpm test',
'general',
1,
'Project rules and conventions'
);
No separate file needed — content lives in the content column.
Tier 2 Rules (on-demand loading)¶
INSERT INTO rules (name, content, category, tier, triggers, description)
VALUES (
'api-rules',
'### api-base-url
Always use /api/v2/ prefix...',
'api',
2,
'["api", "endpoint", "REST"]',
'API conventions and endpoint rules'
);
The triggers column stores a JSON array. The gate hook parses it
the same way it parses YAML triggers.
Infrastructure Checks (checks: → checks table)¶
Anti-Hallucination Rules¶
-- Insert the full rule set as a single tier 1 entry
INSERT INTO rules (name, content, category, tier, description)
VALUES (
'ah-rules',
'## PHASE 1 — READ
### R1: ONE ENTITY AT A TIME
...(full content)...',
'anti-hallucination',
1,
'Anti-hallucination rules for faithful outputs'
);
Or load from file:
Backlog (session continuity)¶
INSERT INTO backlog (item, status, priority)
VALUES ('Add dark mode', 'active', 2);
-- Query active items
SELECT item, priority FROM backlog
WHERE status = 'active' ORDER BY priority;
See Session Continuity for the full schema and session handoff patterns.
Cross-Check (drift detection)¶
Session Summaries (session_summaries table — DB mode only)¶
The session_summaries table tracks what happened in each session and
enables continuity across sessions. It is created by --init-db and
queried by both the startup hook (to show "Continue From Last Session")
and the stop hook (to enforce require_session_summary).
CREATE TABLE IF NOT EXISTS session_summaries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
topic TEXT,
completed_items TEXT, -- JSON array of strings
next_items TEXT, -- JSON array of strings
session_date DATE DEFAULT CURRENT_DATE,
duration_minutes INTEGER,
prompt_count INTEGER
);
-- Insert a session summary
INSERT INTO session_summaries (topic, completed_items, next_items)
VALUES (
'Added auth middleware',
'["Implemented JWT validation", "Added rate limiting"]',
'["Write auth tests", "Update API docs"]'
);
-- Query last session for continuity
SELECT topic, completed_items, next_items
FROM session_summaries ORDER BY id DESC LIMIT 1;
This table has no YAML equivalent — session handoff in YAML mode uses a JSON file (see Session Continuity for both approaches).
Hook Script Differences¶
| Aspect | YAML | SQLite |
|---|---|---|
| Script | on_session_start.py |
on_session_start_db.py (renamed by wizard) |
| Config source | startup-config.yaml |
config table |
| Rules source | Markdown files on disk | rules table content column |
| Dependencies | PyYAML | None (sqlite3 is Python stdlib) |
| Init command | Create YAML manually | python3 on_session_start.py --init-db project.db |
| Rule grouping | One file per source | Auto-grouped by category column |
| Truncation guard | N/A (files are read whole) | Stop hook verifies stored length matches source |
Hook Script Naming¶
The repository contains two startup hook scripts:
on_session_start.py— The YAML variant. Reads config fromstartup-config.yamland rules from Markdown files on disk.on_session_start_db.py— The database variant. Reads config from theconfigtable and rules from therulestable. Supports both SQLite and PostgreSQL via auto-detection of the connection string.
When the setup wizard runs with SQLite or PostgreSQL, it copies
on_session_start_db.py into your project's hooks directory and
renames it to on_session_start.py so that settings.json always
points to the same script name regardless of data store. If you set up
hooks manually without the wizard, use the _db variant directly and
rename it yourself, or update your settings.json command to reference
on_session_start_db.py.
Everything downstream of the SessionStart hook (manifest, sentinel, gates, tier2 triggers, cross-check, stop hook) works identically regardless of data store. The only difference is where the data comes from.
PostgreSQL Limitations¶
PostgreSQL is experimental
PostgreSQL support is present in the database variant hook script
(on_session_start_db.py) and uses auto-detection: if AGENT_DB_PATH
starts with postgresql:// or postgres://, the script connects via
psycopg2 instead of sqlite3. Schema creation and basic rule/config
reads work, but several hook features silently skip PostgreSQL:
| Feature | Hook | Behavior with PostgreSQL |
|---|---|---|
| Session summary enforcement | on_stop.py |
Skipped — no exit gate check |
| No-truncation verification | on_stop.py |
Skipped — no length verification on exit |
Edit logging to rule_log |
on_edit.py |
Skipped — edits are not recorded |
| Fact-reference staleness check | gate_check.py |
Skipped — no stale-fact warnings |
These features use sqlite3 directly (Python stdlib) and guard against
PostgreSQL with not db_path.startswith("postgresql"). The setup wizard
marks PostgreSQL as experimental and notes it is not yet tested in
production. If you need these features, use SQLite.
When to Graduate from YAML to SQLite¶
See Data Store & Platforms for the full comparison and pain signals that indicate it's time to migrate.