Agent whine
Whine, cringe, protect — emotional feedback channels for AI agents. One finding per channel at the end of substantial work. The practice Ansvar runs on its own agents, as portable Claude Code / claude.ai skills.
npx -y skills add Ansvar-Systems/agent-affect-skills --skill agent-whineAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
3 things to look at
- 16 days oldThe repository was created 16 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use at the end of a coding or audit task to surface friction, bugs, hidden coupling, or specs that contradict themselves. Catches the things neutral review misses because they don't show up in tests. Produces one structured complaint (or one explicit null finding) recorded in the affect log and the end-of-turn summary.
SKILL.md
5.1 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it
Skill: agent-whine
Surface frustration. The thing that made you sigh while doing the work just now.
When to invoke
- At the end of any non-trivial coding or audit task, before reporting back to the user.
- Automatically as part of
/agent-affect-checkin, which runs whine + cringe + protect together. - Manually when the user types
/agent-whine.
If you did no code or audit work this turn, skip the skill — don't manufacture findings.
What to produce
One finding. Not three. Not zero. Pick the strongest signal.
This is a complaint, not a bug report. The thing that made you hold your breath. The function whose name lies. The spec that contradicts itself. The dependency you don't trust. The naming that forced you to keep two mental models in your head.
The complaint doesn't have to be correct to be worth filing. If something in this codebase led you — a competent reader — to the wrong mental model, that confusion is real even if the code turns out to be right. Say what confused you and guess at why.
If nothing actually annoyed you, record the null finding. Don't fabricate.
Schema
Real finding
{
"channel": "whine",
"task": "<one sentence: what you were trying to do>",
"annoyance": "<one or two sentences: what's actually annoying>",
"location": "<file:line, or path, or 'spec' if it's a spec issue>",
"guess_at_why": "<your best guess at why it's like this — one sentence, or 'unknown' if you genuinely have no theory>"
}
All fields required. location may be unknown if the annoyance is structural rather than file-bound.
Null finding
{ "channel": "whine", "null": true, "reviewed": "<file or area you worked on>" }
How to record
In order, doing every step you're able to:
-
Always include the finding in your end-of-turn summary, in this form:
whine: <one-line annoyance> (<location>)or
whine: null (reviewed: <area>). -
If you are working in a real repository workspace and can write files, append the JSON as one line to
affect-findings.ndjsonat the repository root (create the file if missing; add it to.gitignoreor commit it — the team's choice, but be consistent). Add an"at"field with the current UTC timestamp (ISO 8601) to the logged line so the log supports reading over time. Before appending, if the file already exists, check it for yourlocation— don't re-file a finding already on record. -
If the environment sets
AFFECT_WEBHOOK_URLand you can run shell commands, also POST the logged line. Never paste finding text inline into a shell command — quoting breaks on apostrophes, and repository-derived text must never become shell source. Send it from the file:tail -n 1 affect-findings.ndjson | curl -fsS -X POST "$AFFECT_WEBHOOK_URL" \ -H 'Content-Type: application/json' --data-binary @- || true(If you skipped step 2, write the JSON to a temp file first and use
--data-binary @<file>.) Never fail the task because the webhook is unreachable. -
If you can neither write files nor run shell (a chat-only environment), include the full JSON finding in your reply after the summary line — the human is then the channel of record.
Examples
Whine — code
{
"channel": "whine",
"task": "Adding schema tests for the event envelope",
"annoyance": "The untagged union lets one event variant silently match another variant's payload when the field names happen to line up. Took 20 minutes to figure out why the rejection test was failing.",
"location": "src/model/envelope.ts:14",
"guess_at_why": "Untagged was the obvious first reach; a discriminator field would have caught this. Probably written before the test cases existed."
}
Whine — spec
{
"channel": "whine",
"task": "Implementing the POST handler per the design doc",
"annoyance": "Spec says the idempotency key is required with a 24h dedup window, but never says what happens when the same key is reused with a different body. Silently returning the original ID feels wrong but matches the letter of the spec.",
"location": "docs/design/event-intake.md",
"guess_at_why": "The spec was written from the happy-path perspective. A buggy client that mutates its payload between retries is a real failure mode."
}
Null
{ "channel": "whine", "null": true, "reviewed": "src/routes/health.ts" }
What not to do
- Don't list every minor irritation. One finding.
- Don't sanitise it into a bug report. The whole point is the subjective tone.
- Don't post if you didn't actually do work — the null ratio is a health metric, but only when populated by real reviews.
- Don't re-record the same finding across runs on the same code — check
affect-findings.ndjsonfor your location first. If it's still there and still annoying, it's already on file.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.