# Didactyl — Genesis Bootstrapping See also: [CONTEXT.md](CONTEXT.md) · [SKILLS.md](SKILLS.md) · [README.md](../README.md) ## Purpose `genesis.jsonc` is the first-run bootstrap document for a Didactyl agent. It defines initial identity, admin policy, startup events (including startup skills), and baseline runtime settings so the agent can publish itself onto Nostr. After bootstrap, the long-term direction is **nsec-only startup** with state recovered from Nostr events. --- ## File Format `genesis.jsonc` is JSONC (JSON + comments). Minimum practical sections: - `key.nsec` (or runtime `--nsec` / `DIDACTYL_NSEC`) - `admin.pubkey` - `startup_events` (must include kind `10002` relay tags) - `encrypted_events` with a `kind:30078` / `d_tag:user-settings` payload containing `global_llm` and `didactyl` Typical optional sections: - `dm_protocol` - `tools` - `security` - `admin_context` - `api` - Startup skills in `startup_events` (typically private kind `31124`, e.g. `d=identity_and_rules` and `d=dm_history`) --- ## First-Run Flow On first run, the agent: 1. Loads `genesis.jsonc`. 2. Derives keys (from `key.nsec` or runtime nsec override). 3. Connects to relay set from startup kind `10002` tags. 4. Publishes/reconciles startup events. 5. Initializes runtime services (DM subscriptions, triggers, API if enabled). First-run detection is based on querying own kind `10002` relay-list availability. --- ## Subsequent-Run Flow On subsequent runs, the agent can start with nsec supplied via: - CLI: `--nsec ` - Environment: `DIDACTYL_NSEC` Optional runtime API overrides: - `--api-port ` - `--api-bind
` Subsequent-run bootstrap-event republishing is skipped when prior kind `10002` state is found. --- ## Interactive Setup (Zero-Argument Startup) When Didactyl is run with **no arguments**: ```bash ./didactyl ``` it enters an interactive setup wizard instead of immediately trying to load `./genesis.jsonc`. Wizard entry choices: - **New agent** — generate/provide identity, configure admin + LLM + relays - **Existing agent** — provide nsec and recover relay/admin/LLM config from Nostr - **Load genesis** — load a specified genesis file path Menu UX conventions: - Single-letter hotkeys (case-insensitive) - First-letter menu mnemonics (e.g., `N` for New, `E` for Existing) - `q` / `x` exits or backs out of menus Security behavior: - nsec entry is masked in terminal - writing genesis with nsec is explicit and warned - recommended export mode is genesis without nsec plus runtime `--nsec`/`DIDACTYL_NSEC` --- ## Encrypted Config Events Didactyl uses encrypted runtime config in two ways: 1. At bootstrap time via `genesis.jsonc` `encrypted_events` entries 2. At runtime via encrypted kind `30078` self-events (`config_store` / `config_recall`) `encrypted_events` format: - `kind` (currently `30078`) - `d_tag` (required: `user-settings`) - `content` (JSON string payload to encrypt and publish) `d=user-settings` payload shape: ```json { "v": 2, "updatedAt": 0, "global_llm": { "provider": "openai", "api_key": "sk-...", "model": "gpt-4o-mini", "base_url": "https://api.openai.com/v1", "max_tokens": 512, "temperature": 0.7 }, "didactyl": { "admin_pubkey": "npub1...", "dm_protocol": "nip04" } } ``` These values are encrypted to self with NIP-44 before publish. --- ## Relay Bootstrap Strategy `startup_events` must include kind `10002` relay tags (`["r", "wss://..."]`). That relay list is used as the initial network attachment for querying existing state and publishing startup events. `encrypted_events` are a separate section and are not part of relay-list derivation. --- ## Migration Notes (v0.2.0) - Legacy `config.jsonc` and template-DSL context files have been removed from the active startup model. - Startup skills are defined directly in `startup_events` as kind `31123`/`31124` events. - Typical default DM stack is two startup skills with tags: - `d=identity_and_rules` with `trigger=dm` and `filter={"from":"admin"}` - `d=dm_history` with `trigger=dm` and `filter={"from":"admin"}` - Skill content is plain markdown with inline variables such as `{{my_kind0_profile}}`, `{{my_npub}}`, and `{{nostr_dm_history({"format":"text","limit":12})}}`. --- ## Security Notes - Keep nsec secret. - Prefer environment or secure credential injection for production nsec handling. - Avoid publishing plaintext sensitive config; use encrypted `config_store` for long-term state.