Understanding the Candidate Lifecycle for Person Profiles in Distilly
The candidate lifecycle for person profiles in Distilly tracks four core metadata fields—created_at, updated_at, version, and status—which are automatically managed across skill_writer.py, skill_schema.py, and version_manager.py to ensure every persona artifact remains versioned and auditable.
The titanwings/distilly repository treats every person profile as a versioned JSON/YAML artifact. Understanding the candidate lifecycle for person profiles is essential for managing how these persona metadata objects evolve from initial creation through archival.
Core Lifecycle Attributes
Distilly persists four fields inside the lifecycle object of every profile's metadata:
created_at: ISO-8601 timestamp set automatically on creation vianow_iso().updated_at: ISO-8601 timestamp refreshed each time the profile is modified.version: Human-readable version string (e.g.,v1,v2) incremented during updates.status: Logical state of the profile, defaulting toactive.
Implementation Across the Codebase
Initial Creation in skill_writer.py
The lifecycle begins when tools/skill_writer.py generates a new persona. The module injects initial timestamps and version information into the metadata:
# tools/skill_writer.py – Initial lifecycle injection
normalized_meta["lifecycle"]["created_at"] = normalized_meta.get("created_at", now_iso())
normalized_meta["lifecycle"]["updated_at"] = normalized_meta["lifecycle"]["created_at"]
normalized_meta["lifecycle"]["version"] = "v1"
Schema Normalization in skill_schema.py
The schema layer ensures backward compatibility by backfilling missing lifecycle values. The tools/skill_schema.py module harmonizes metadata across the artifact tree:
# tools/skill_schema.py – Lifecycle consistency enforcement
lifecycle = meta.setdefault("lifecycle", {})
meta["created_at"] = lifecycle.get("created_at", meta.get("created_at", now_iso()))
meta["updated_at"] = lifecycle.get("updated_at", meta.get("updated_at", meta["created_at"]))
meta["version"] = lifecycle.get("version", meta.get("version", "v1"))
lifecycle.setdefault("status", "active")
Version Management in version_manager.py
When existing profiles are updated or restored, tools/version_manager.py handles version bumping and timestamp refreshing:
# tools/version_manager.py – Version bumping on update
meta["lifecycle"]["version"] = f"{target_version}_restored"
meta["lifecycle"]["updated_at"] = now_iso()
Practical Examples
Creating a New Persona
When you create a profile via the CLI, the lifecycle fields initialize automatically:
distilly new-persona --name "Alice" --output ./skills/alice
This command invokes skill_writer.py, which sets lifecycle.created_at to the current ISO timestamp and initializes version as "v1".
Updating an Existing Profile
Modifications trigger the version manager to increment the version and update the timestamp:
distilly update-persona ./skills/alice --patch changes.md
Internally, this calls version_manager.py to bump lifecycle.version (for example, to "v2") and refresh lifecycle.updated_at.
Inspecting Lifecycle Metadata Programmatically
You can read the lifecycle block directly from the meta file:
import json
from pathlib import Path
meta = json.loads(Path("./skills/alice/meta.json").read_text())
print(meta["lifecycle"])
The output shows the complete audit trail:
{
"created_at": "2026-09-10T12:34:56Z",
"updated_at": "2026-09-12T08:21:13Z",
"version": "v2",
"status": "active"
}
Summary
- The candidate lifecycle manages four critical fields—
created_at,updated_at,version, andstatus—stored within thelifecycleobject of every persona profile. tools/skill_writer.pyinitializes timestamps and version strings during the creation phase.tools/skill_schema.pynormalizes metadata, backfills missing values, and defaultsstatusto"active".tools/version_manager.pyincrements version strings and refreshesupdated_attimestamps during profile modifications.- Profiles transition through logical states via the
statusfield, enabling archival workflows without physical deletion.
Frequently Asked Questions
How does Distilly handle missing lifecycle fields in legacy profiles?
When loading older artifacts, tools/skill_schema.py automatically backfills missing created_at, updated_at, and version values. The schema defaults version to "v1" and timestamps to the current time if no historical data exists, ensuring every profile conforms to the current lifecycle specification.
Can the version string format be customized?
The codebase uses semantic-style strings such as "v1" or "v2_restored" (the latter appended by version_manager.py during restore operations). While the system automatically manages these formats, the underlying implementation in version_manager.py uses standard string formatting, allowing teams to modify conventions if they maintain the string type in the lifecycle object.
What values are valid for the status field?
According to the implementation in tools/skill_schema.py, the status field defaults to "active" when initialized via lifecycle.setdefault("status", "active"). The data structure accepts any string value, enabling custom states like "archived" or "deprecated" to suit specific workflow requirements.
Where is the lifecycle metadata physically stored?
The lifecycle object resides inside the meta.json or meta.yaml file within each persona directory. tools/skill_writer.py creates this file initially, while subsequent updates from tools/version_manager.py modify the lifecycle values in place.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →