feat(phrases): count an invocation per key and score an eval on it #841
No reviewers
Labels
No labels
move-to-repo
coilyco-bridge-deploy
move-to-repo
coilyco-flight-deck-agent-compose
move-to-repo
coilyco-gaming-eco-app
move-to-repo
coilysiren-inbox
move-to-repo
unknown
🔒⚠️📦⚠️🔒 SANDBOXED 🔒⚠️📦⚠️🔒
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
c#
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-gaming/sirens-echo!841
Loading…
Reference in a new issue
No description provided.
Delete branch "aos/claude/bk79-phrase-telemetry"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Refs #176. The two acceptance criteria the registry shipped without.
Where the issue actually stood
The mechanism is complete and clean - registry, loader, renderer, terminal rule, prompt naming keys. Two criteria were open, and the last comment marked both:
Both are here.
Invocation is counted per key
sirens_echo.phrase.invocationswith aphrase.keylabel, plusresponse.phrase.invokedlogged andresponse.phraseon the turn span. The key is registry-authored, so it satisfies the closed-set rule every other metric in this contract follows - no member value can expand cardinality through it.That delivers the third reason the issue gave for wanting a tool call: which boundaries members actually probe, and how often.
It is an attribute, not a span. The issue recommended a tool call partly so invocation would appear as its own span. The sentinel is what shipped, so I instrumented that rather than rebuilding it. The divergence costs the span; it does not cost the anti-spoofing argument, which the terminal rule already closes - a narrated sentinel is an invocation, and an invocation beside other text is refused.
Scoring on the key
Fails on: no invocation, a different key, more than one key, or the right key beside other text. It reads the raw reply, since rendering replaces the key with its text and the key is the thing being scored.
This is the replacement for frozen keyword lists. A keyword list can be fitted to outputs after seeing them - which is why the battery carries a warning that editing one invalidates the cell. A key is exact and there is nothing to fit.
A defect found on the way, and it blocked the above
The eval measured a prompt no deployment renders.
agent.gowrapped its system prompt withwithPhrasePolicy;evaluation.go,rate.go, andboard.goall calledBuildSystemPromptdirectly. So the eval's model was never told the keys exist and could never invoke one - which makesexpect_phraseunbuildable until it is fixed.With no registry configured the two prompts are byte-identical, which is exactly why nobody caught it. They diverge the moment
SIRENS_ECHO_PHRASESis set.evaluationSystemPromptis now the one builder, pinned by a test asserting an unconfigured registry leaves the prompt unchanged - so no tracked snapshot moves.Worth its own issue if you would rather I split it out; I folded it in because the payoff criterion cannot ship without it.
Tests
phrasetelemetry_test.gocovers key extraction and ordering, whitespace trimming (the label must be the registry's spelling), all fiveexpect_phraseoutcomes, a case scoring only on a phrase key still counting as scored, and the prompt-parity invariant.Still inert, and still not mine to change
Nothing sets
SIRENS_ECHO_PHRASES. Every phrase path stays dormant. Turning it on changes a profile's system block, so it wants the evaluation cadence run against it rather than a quiet switch - the same call the previous engineer declined to make from their seat, and I am declining it from mine.ward gatePASS on all six steps.