Skip to main content
All Sorat data lives under ~/.sorat/. No external database is required.

Directory tree

~/.sorat/
├── config.json                     # Main configuration
├── user.md                         # User profile (name, timezone, country)
├── .cli_token                      # CLI auth token (created at startup)

├── agent/
│   └── persona.md                  # System prompt template (Go template)

├── sessions/
│   ├── index.json                  # Session registry
│   └── {uuid}/
│       ├── meta.json               # Session metadata
│       └── messages.json           # Message history

├── memory/
│   ├── facts.md                    # Timestamped facts
│   └── soul.md                     # Agent personality/values

├── workspace/                      # Agent file sandbox

├── skills/
│   ├── _state.json                 # Disabled skill names
│   └── {name}/
│       └── SKILL.md                # Skill definition (frontmatter + instructions)

├── cron/
│   └── jobs.json                   # Scheduled jobs with state and logs

├── auth/
│   └── credentials.json            # OAuth tokens (mode 0600)

├── logs/
│   └── YYYY-MM-DD.log             # Daily rotated JSON logs

└── tools/
    └── config.json                 # Tool configuration

File formats

sessions/index.json

[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "title": "Chat about Go concurrency",
    "model": "gpt-4o",
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-01-15T10:30:00Z",
    "message_count": 12
  }
]

sessions//messages.json

[
  {
    "role": "user",
    "content": "Hello!",
    "timestamp": "2025-01-15T10:00:00Z"
  },
  {
    "role": "assistant",
    "content": "Hi! How can I help you?",
    "timestamp": "2025-01-15T10:00:01Z",
    "tool_calls": []
  }
]

memory/facts.md

- [2025-01-15T10:30:00Z] User prefers dark mode
- [2025-01-15T14:00:00Z] Project uses Go 1.24

memory/soul.md

Free-form Markdown appended to the system prompt after the persona template.

agent/persona.md

Go template with system instructions:
You are Sorat, running on {{.Hostname}} ({{.OS}}/{{.Arch}}).
...

skills//SKILL.md

---
name: my-skill
description: What this skill does
---

[Skill instructions]

cron/jobs.json

[
  {
    "id": "job-uuid",
    "name": "hourly-check",
    "enabled": true,
    "schedule": {"kind": "every", "every_ms": 3600000},
    "payload": {"kind": "message", "message": "Check system health"},
    "state": {
      "last_run": "2025-01-15T10:00:00Z",
      "next_run": "2025-01-15T11:00:00Z",
      "run_count": 24,
      "last_status": "success"
    },
    "execution_log": [
      {
        "timestamp": "2025-01-15T10:00:00Z",
        "status": "success",
        "result": "System health is good.",
        "duration_ms": 4500,
        "tool_calls": 3
      }
    ]
  }
]

auth/credentials.json

OAuth tokens (file permissions 0600):
{
  "google-antigravity": {
    "provider": "google-antigravity",
    "access_token": "ya29...",
    "refresh_token": "1//...",
    "expiry": "2025-01-15T11:00:00Z"
  }
}

logs/YYYY-MM-DD.log

Newline-delimited JSON (one entry per line):
{"time":"2025-01-15T10:00:00.123Z","level":"INFO","msg":"server started","port":8080}

Initialization

On first run, ~/.sorat/ is created with:
  • Default config.json
  • Empty sessions/index.json ([])
  • Empty memory/facts.md and memory/soul.md
  • Default agent/persona.md (expanded from template)
  • Default user.md (# User Profile)
  • All required subdirectories

Atomic writes

All file writes use the atomic pattern: write to path.tmp, then os.Rename(tmp, path). This prevents partial writes from corrupting data on crashes.