

# Plan: Eliminate Soul — Everything Is a Skill

## Summary

Remove the concept of a "soul" (kind `31120`) as a special, privileged entity. The agent's base personality, instructions, and context assembly template become a regular private skill (kind `31124`) that is adopted like any other skill. This simplifies the architecture: there is only one concept — **skills** — and the adoption list (`10123`) determines what the agent knows and how it behaves.

## Architecture Decision

- Kind `31120` is eliminated entirely.
- What was the "soul" becomes a private skill (kind `31124`) with a conventional d-tag (e.g., `didactyl-default`).
- The `---template---` mechanism stays — any skill can contain it.
- The `genesis.jsonc` `default_skill` field defines this skill's content for first-run publishing.
- On subsequent runs, the agent fetches its adopted skills from Nostr relays.

## Startup Flow

```
First Run (genesis.jsonc present):
  1. Read genesis.jsonc
  2. Publish default_skill as kind 31124 (private skill) to relays
  3. Publish kind 10123 adoption list referencing the default skill
  4. Load default_skill content into g_system_context
  5. Continue normal startup

Subsequent Run (nsec only):
  1. Detect not-first-run via kind 10002 presence
  2. Query own kind 10123 adoption list from relays
  3. Fetch first adopted skill content from relays
  4. Load that content into g_system_context
  5. Continue normal startup
```

## genesis.jsonc Schema

The `default_skill` field replaces the old kind `31120` startup event:

```jsonc
{
  "key": { "nsec": "nsec1..." },
  "admin": { "pubkey": "npub1..." },
  "llm": { ... },
  "api": { ... },

  // Default skill — published as kind 31124 on first run
  // and adopted into the agent's 10123 list.
  "default_skill": {
    "d_tag": "didactyl-default",
    "kind": 31124,
    "content": "# Didactyl Agent\n\nYou are Didactyl...\n\n---template---\n\n- section: admin_identity\n  role: system\n  tool: admin_identity\n  ...",
    "tags": [
      ["app", "didactyl"],
      ["scope", "private"]
    ]
  }
}
```

## Code Changes

### src/nostr_handler.c

- Remove the kind `31120` scan in `nostr_handler_reconcile_startup_events()` (lines 2487-2493).
- Add logic to load `g_system_context` from the `default_skill` config field on first run.
- On subsequent run, query own `10123` adoption list, resolve the first adopted skill address, fetch its content, and set `g_system_context`.

### src/config.c / src/config.h

- Add `default_skill` parsing to `config_load()`.
- Add a `default_skill_t` struct to `didactyl_config_t` with fields: `d_tag`, `kind`, `content`, `tags_json`.
- Remove any special handling of kind `31120` in startup event parsing.

### src/main.c

- On first run: publish the `default_skill` as a kind `31124` event and publish/update the `10123` adoption list to include it.
- On subsequent run: the adoption-list-driven fetch provides the system context.
- Remove the kind `31120` fallback in system context extraction.

### src/agent.c

- `g_system_context` continues to work the same way — it's just sourced from a skill instead of a soul.
- The trigger execution path (`agent_on_trigger`) prepends `g_system_context` unchanged.
- The WoT/stranger chat path uses `g_system_context` unchanged.
- The non-template fallback path uses `g_system_context` unchanged.

### src/prompt_template.c

- Rename `soul_content` parameter to `skill_content` in `prompt_template_parse()`.
- Rename `personality` field to `base_instructions` or similar.
- No functional changes — the `---template---` split mechanism is unchanged.

### config.jsonc

- Replace the kind `31120` startup event with a kind `31124` startup event using the same content.
- Update the d-tag from `soul` to `didactyl-default`.

### genesis.jsonc

- Populate the `default_skill` field with the current soul content (personality + template sections).

## Documentation Changes

### README.md

- Remove all references to "Soul", "soul", kind `31120`.
- Replace "Soul/personality" with "Default skill" or "Base skill".
- Update the Didactyl Kinds table: remove `31120` row.
- Update the Roadmap table: remove "Soul/personality | Kind 31120" row.
- Update context model description: "assembled from adopted skill templates" not "soul template".

### docs/SKILLS.md

- Remove `{{soul}}` template variable.
- Remove `soul` content field from skill schema.
- Remove any language about soul being special or separate from skills.
- Document that any skill can contain `---template---` sections.

### docs/CONTEXT.md

- Remove soul-specific assembly language.
- Context is assembled from adopted skills in adoption list order.

### docs/GENESIS.md

- Update to reference `default_skill` instead of kind `31120` soul event.
- Update first-run behavior description.

### docs/API.md

- Remove `/api/events/soul` endpoint.
- Rename `system_prompt` context part to `default_skill` or `base_instructions`.

## What Does NOT Change

- The `---template---` mechanism works identically — it just lives in a skill.
- Kind `10123` adoption list still drives context composition order.
- Template variable resolution via tools is unchanged.
- Trigger execution flow is unchanged (uses `g_system_context`).
- Encrypted config tools (`config_store`/`config_recall`) are unchanged.
- The genesis/nsec startup detection is unchanged.

## Dependency Order

1. Define `default_skill` schema in config structs and genesis.jsonc
2. Update config parser to read `default_skill`
3. Update nostr_handler to source system context from default_skill (first run) or adopted skill (subsequent run)
4. Update main.c first-run path to publish default_skill as 31124 and update 10123
5. Remove all kind 31120 references from code
6. Rename soul terminology in prompt_template.c
7. Update config.jsonc startup events
8. Update all documentation
9. Build and test
