Why 360 cycles quietly stop happening
Not because anyone objects to them. Because someone has to pick reviewers, send forms, chase the 40% who forget, strip identifying detail from the responses, and synthesise the rest — and that person has a day job. The cycle survives two rounds and then slips. Automating the mechanical parts is the difference between a quarterly rhythm and an annual scramble.
Anonymity has to be real, not promised
People write what they actually think only if they believe the process. That means aggregating below a minimum response count rather than showing individual comments, stripping identifying phrasing before a manager ever sees the text, and never exposing raw responses through the tooling — not even to admins. If someone can reconstruct who said what, the next round gets you nothing but platitudes.
# never surface a theme that can be traced to one person
MIN_RESPONSES = 4
if len(responses) < MIN_RESPONSES:
return {"status": "withheld", "reason": "below anonymity threshold"}A hard floor, checked before summarisation rather than after. Three responses about a two-person team is not anonymous no matter how it's phrased.
Themes, not sentiment scores
Reducing a paragraph to 'sentiment: 0.62' throws away the only useful part. The model clusters comments into recurring themes and quotes representative lines verbatim, so the manager reads what was said rather than a number derived from it. The synthesis is a reading aid, not a verdict.
The human stays in the loop
Nothing generated goes to an employee unreviewed. The output is a draft for the manager — themes, quotes, suggested areas — that they edit and own. Automating the delivery of performance feedback would be a way to make a sensitive process worse, quickly.
# n8n: schedule -> collect -> threshold -> summarise -> DRAFT to manager
# └─ never auto-sendThe workflow deliberately terminates at a draft. Every path that could send generated feedback directly to a person is absent by design, not disabled by config.