# How Distilly Creates Local-First Person Profiles for Coding Agents

> Discover how Distilly builds local-first person profiles for coding agents. Learn to transform persona.md into offline-ready profiles using skill writer and schema modules on your machine.

- Repository: [Tianyi Zhou/distilly](https://github.com/titanwings/distilly)
- Tags: deep-dive
- Published: 2026-09-10

---

**Distilly constructs local-first person profiles entirely on the developer's machine using the skill writer and skill schema modules to transform a simple [`persona.md`](https://github.com/titanwings/distilly/blob/main/persona.md) file into a complete, offline-ready profile for coding agents.**

The `titanwings/distilly` repository implements a privacy-focused architecture for creating **local-first person profiles** that never require external API calls during runtime. By leveraging local markdown files and structured metadata normalization, Distilly ensures that personality traits, cultural contexts, and behavioral profiles remain under the developer's complete control while maintaining complete offline functionality.

## Understanding the Persona Architecture

The local-first design centers on three core components that process persona data without network dependencies. The **skill writer** ([`tools/skill_writer.py`](https://github.com/titanwings/distilly/blob/main/tools/skill_writer.py)) handles artifact generation and file operations, while the **skill schema** ([`tools/skill_schema.py`](https://github.com/titanwings/distilly/blob/main/tools/skill_schema.py)) validates and normalizes metadata structures. These tools work together to produce self-contained skill packages that encapsulate both work capabilities and personality definitions.

## Step-by-Step Profile Creation Process

### Collecting Raw Persona Data

The process begins when the CLI accepts a `--persona` flag pointing to a [`persona.md`](https://github.com/titanwings/distilly/blob/main/persona.md) file, as defined in [`skill_writer.py`](https://github.com/titanwings/distilly/blob/main/skill_writer.py). The system reads this file, optionally applies patches via the `--persona-patch` argument, and merges any correction entries through the `apply_correction` function. This raw text serves as the foundation for the agent's behavioral patterns and communication style.

### Normalizing the Meta-Profile

In [`tools/skill_schema.py`](https://github.com/titanwings/distilly/blob/main/tools/skill_schema.py), the system resolves the `profile` section from the metadata, which can be either a string (preset name) or a dictionary containing specific fields like `mbti`, `culture`, and `personality`. The helper function `normalize_research_profile` automatically selects research presets matching the character family—whether celebrity, colleague, or custom archetype—and injects intelligent defaults for `quality_profile` and `merge_strategy` parameters.

### Embedding the Profile into the Skill

The `write_artifacts()` function in [`skill_writer.py`](https://github.com/titanwings/distilly/blob/main/skill_writer.py) generates three critical artifacts within the skill directory:

- [`persona.md`](https://github.com/titanwings/distilly/blob/main/persona.md): The raw persona description in markdown format
- [`persona_skill.md`](https://github.com/titanwings/distilly/blob/main/persona_skill.md): A user-invocable skill artifact containing only the persona (`user-invocable: true`)
- [`combined_skill.md`](https://github.com/titanwings/distilly/blob/main/combined_skill.md): A merged skill integrating both work capabilities and personality traits

These files are persisted under localized paths such as `skills/colleague/example_tianyi/`, creating a portable, version-controlled profile package.

## Local-First Execution Model

All artifacts remain stored locally within the skill's directory structure, ensuring complete offline functionality. The architecture guarantees that **no remote API is consulted at runtime**, maintaining data privacy and eliminating external dependencies. When developers create skills programmatically, the `create_skill()` function accepts `persona_content` directly and writes it to the local filesystem alongside work artifacts.

```python

# Creating a skill with a local persona

import pathlib
from tools import skill_writer

skill_dir = pathlib.Path("skills/colleague/jane")
meta = {
    "display_name": "Jane Doe",
    "profile": {
        "mbti": "INTJ",
        "culture": "tech",
        "personality": ["direct", "data-driven"]
    },
}

persona_path = pathlib.Path("persona.md")
persona_content = persona_path.read_text()

skill_writer.create_skill(
    base_dir=skill_dir.parent,
    slug="jane",
    meta=meta,
    work_content="def foo(): pass",
    persona_content=persona_content,
)

```

## Runtime Consumption by Coding Agents

When the coding agent initializes, the Distilly engine loads the generated [`persona_skill.md`](https://github.com/titanwings/distilly/blob/main/persona_skill.md) together with any work-specific skills. The engine interprets persona fields—including `mbti` type, cultural context, and personality arrays—to dynamically shape prompts, adjust tone, and influence decision-making algorithms. This consumption happens entirely within the local environment using the pre-generated artifacts.

```bash

# CLI usage implementing the same local-first flow

distilly create \
    --slug jane \
    --name "Jane Doe" \
    --persona persona.md \
    --work work.md

```

## Summary

- Distilly creates **local-first person profiles** through the `skill_writer` and `skill_schema` modules without external API dependencies.
- The system accepts raw persona markdown via the `--persona` CLI flag and normalizes metadata through `normalize_research_profile`.
- Three artifacts are generated: [`persona.md`](https://github.com/titanwings/distilly/blob/main/persona.md), [`persona_skill.md`](https://github.com/titanwings/distilly/blob/main/persona_skill.md), and [`combined_skill.md`](https://github.com/titanwings/distilly/blob/main/combined_skill.md), stored under localized skill directories.
- Runtime consumption uses only local files, ensuring complete privacy and offline capability for coding agents.

## Frequently Asked Questions

### What file formats does Distilly accept for persona definitions?

Distilly primarily accepts markdown files (`.md`) through the `--persona` flag, though the metadata system in [`skill_schema.py`](https://github.com/titanwings/distilly/blob/main/skill_schema.py) can parse JSON and YAML descriptions for the profile section. The raw persona content is treated as markdown text that gets embedded directly into the generated skill artifacts.

### How does Distilly handle persona updates or corrections?

The system supports iterative refinement through the `--persona-patch` argument and the `apply_correction` function in [`skill_writer.py`](https://github.com/titanwings/distilly/blob/main/skill_writer.py). These mechanisms merge correction entries into the existing persona without overwriting the original file, allowing developers to version control personality adjustments separately from base definitions.

### Can personas include specific behavioral traits like MBTI types?

Yes, the `profile` metadata supports detailed psychological and cultural markers including `mbti` (e.g., "INTJ"), `culture` (e.g., "tech"), and `personality` arrays (e.g., ["direct", "data-driven"]). The `normalize_research_profile` function in [`skill_schema.py`](https://github.com/titanwings/distilly/blob/main/skill_schema.py) validates these fields against preset families like celebrity or colleague archetypes.

### Where are the generated persona files stored locally?

All artifacts are stored within the skill's directory structure, typically following the pattern `skills/{family}/{slug}/`. This includes [`persona.md`](https://github.com/titanwings/distilly/blob/main/persona.md) (source), [`persona_skill.md`](https://github.com/titanwings/distilly/blob/main/persona_skill.md) (executable skill), and [`combined_skill.md`](https://github.com/titanwings/distilly/blob/main/combined_skill.md) (merged capability), ensuring that coding agents access profiles through local filesystem calls at runtime.