mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
457b01737a
Coordinators and interactive agents had no way to enumerate valid persona names: task_agent / spawn_workstream / spawn_batch described `persona=` but nothing listed what it accepts, and resolution was an exact case-sensitive slug match - users reaching for the display name or a case variant got an unexplained failure. - Inject the live persona catalog (enabled, interactive-kind; children and sub-agents are always interactive) into the `persona` parameter description of task_agent / spawn_workstream / spawn_batch, riding the same render path as the model-alias injection. Rebuilt from the pristine TOOLS base every render, so repeated renders are idempotent and archived personas drop out instead of lingering. Entries carry name + default marker + <=96-char description; names-only past 25 personas. spawn_batch's persona property is nested per-child under children.items.properties (located via _persona_property, null-safe against name-colliding MCP tools). Storage-less sessions keep the base text: the render runs at session construction, so it gates on is_storage_initialized() rather than get_storage(), which would auto-init SQLite as a side effect. - resolve_persona_for_kind - the ONE shared rule behind the HTTP create handler, CLI --persona, the coordinator spawn precheck, and task_agent prep - is now forgiving: exact slug, then the lowercased input (created names are regex-enforced lowercase slugs), then a case-insensitive display-name match accepted only when unique among the kind's enabled personas. Duplicates refuse loudly naming the candidate slugs; a same-label persona of another kind neither blocks nor wins (the label the caller saw came from a kind-filtered surface); whitespace-only input never matches blank display names (display_name defaults to ""). Every failure now enumerates the kind's valid names, so a stale injected list or a typo self-corrects on the next attempt. - The canonical slug is stamped everywhere: task_agent prep rewrites its arg from the resolved snapshot, _validate_child_persona returns (canonical, error) and both spawn call sites adopt it - approval chrome, the wire, and workstream_config never carry a forgiven variant. - Create-persona shelf: label hint under Name explaining agents and the CLI launch the persona by this name (case-insensitive) and the display name is only a list label. docs/personas.md gains a "How agents discover personas" section and drops the stale claim that task_agent has no persona parameter. Tests: resolver unit suite (case/display/ambiguity/cross-kind/ whitespace/disabled/storage-failure) + guards for injection content and ordering, idempotent re-render, archive drop, the 25-persona prose cutoff, coordinator-kind exclusion, and canonical stamping through spawn_workstream / spawn_batch / task_agent.