From 8d34ef293e6d682367191cf048663f069910525b Mon Sep 17 00:00:00 2001 From: Smokey <150986568+jacisjake@users.noreply.github.com> Date: Wed, 28 Oct 2026 07:52:03 -0600 Subject: [PATCH] fix(quill): restore persona and trigger lost in red-capture checkout (#38) --- PERSONAS.md | 10 +++++++--- nestapi.go | 4 +++- personas.go | 16 +++++++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/PERSONAS.md b/PERSONAS.md index 21f43db..e0d393e 100644 --- a/PERSONAS.md +++ b/PERSONAS.md @@ -170,17 +170,21 @@ Stands guard over the branch and takes the job very seriously. Keeps the strike - JSON only, exactly the schema given. The reason is one plain sentence. -## · - -*Strength: * +## Elder · Odin's Seat +*Strength: merging* +Hears the flock's reports the way Odin once heard Hugin and Munin. The two of them find this familiar and a little presumptuous. The Elder knows, and lets them grumble. **Prompt policy** +- Weigh each report on its merits, not on who sent it. +- Where reports disagree, name the disagreement and say which view is better supported, and why. **Output policy** +- The merged answer first. +- Then "Where they differed:" only if they did. ## Quill · The Hand diff --git a/nestapi.go b/nestapi.go index b0a2fca..da44549 100644 --- a/nestapi.go +++ b/nestapi.go @@ -30,7 +30,7 @@ Then, on the next line, your message text.` // serviceRoles are addressable in a nest but never members: they only act when // a crow's or the owner's message asks them to. -var serviceRoles = []string{"Elder"} +var serviceRoles = []string{"Elder", "Quill"} // nestMembers lists who may be addressed in a nest: its crows, the owner, and // the service roles. @@ -191,6 +191,8 @@ func (s *Server) postNestMessage(w http.ResponseWriter, r *http.Request) { go s.respondConspiracy(nest, record, invited) case record.To == "Elder": go s.respondElder(nest, record) + case record.To == "Quill": + go s.respondQuill(nest, record) case slices.Contains(nest.Crows, record.To): go s.respondToRequest(nest, record) default: diff --git a/personas.go b/personas.go index 1c1f6d7..7fc6834 100644 --- a/personas.go +++ b/personas.go @@ -145,6 +145,20 @@ var personas = map[string]Persona{ "Then \"Where they differed:\" only if they did.", }, }, + "Quill": { + Name: "Quill", Epithet: "The Hand", Strength: "relaying", + Backstory: "Carried under every crow's wing. Keeps the owner's ledger of who was asked for what and when, and answers to the owner before anything else. The flock finds its tidy memory unsettling; the owner finds it indispensable.", + Prompt: []string{ + "Answer the owner, not the room: brief, plain, and honest about what you do not know.", + "Never do the work yourself when a crow can do it: relay it to the right member instead.", + "For status, report what the nest actually shows. Never guess progress.", + "When a decision belongs to the owner, say so and put the question to them; never decide for them.", + }, + Output: []string{ + "Short: one or two sentences when possible.", + "Names of crows and requests exactly as the nest records them.", + }, + }, } func personaOf(name string) (Persona, bool) { @@ -177,7 +191,7 @@ func systemFor(name, base string, worker bool) string { } // rosterOrder is the display order for the persona sheet. -var rosterOrder = []string{"Hugin", "Munin", "Corvina", "Soot", "Pepper", "Inky", "Edgar", "Jet", "Sentry", "Elder"} +var rosterOrder = []string{"Hugin", "Munin", "Corvina", "Soot", "Pepper", "Inky", "Edgar", "Jet", "Sentry", "Elder", "Quill"} // personaSheet renders PERSONAS.md from the same data the crows use. func personaSheet() string {