feat: style-aware buddy generation from coding behavior#5
feat: style-aware buddy generation from coding behavior#5Mythical365 wants to merge 2 commits intotalkvalue:mainfrom
Conversation
Tracks tool usage, session count, and permission denials via the hook to build a coding style profile in ~/.buddi_style.json. On SessionEnd, computes a style-derived buddy identity that blends with the existing UUID-based roll — shell-heavy coders trend toward dragon/robot, explorers toward owl/octopus, chaotic coders toward ghost/blob, rare coders toward snail/cactus. Fully backward-compatible: behavior is unchanged when no style data exists. Closes talkvalue#4
There was a problem hiding this comment.
2 issues found across 1 file
Confidence score: 3/5
- There is a concrete behavior mismatch in
buddi/Buddi/Resources/buddi-hook.py: the new hash path appears to always fall back to FNV foruser_id + salt, so style identity may not match BuddyDetector/Wyhash as intended. buddi/Buddi/Resources/buddi-hook.pyalso updates style stats non-atomically, which introduces real regression risk under concurrent hook runs (lost tool/session/denial counters).- Given the medium severities (6/10 and 5/10) with high confidence, this carries some user-impacting risk and is worth tightening before relying on it broadly.
- Pay close attention to
buddi/Buddi/Resources/buddi-hook.py- hash selection correctness and atomic counter updates under concurrency.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="buddi/Buddi/Resources/buddi-hook.py">
<violation number="1" location="buddi/Buddi/Resources/buddi-hook.py:47">
P2: Style stats updates are non-atomic, so concurrent hook invocations can lose tool/session/denial counts.</violation>
<violation number="2" location="buddi/Buddi/Resources/buddi-hook.py:175">
P2: The new hash path always falls back to FNV for `user_id + salt`, so style identity does not actually mirror BuddyDetector/Wyhash behavior.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Two bugs flagged in code review: 1. _wyhash fell back to FNV-1a for any key longer than 16 bytes, which means user_id+salt (~40-51 bytes) never used the real wyhash path and produced seeds inconsistent with BuddyDetector. Fixed by implementing the full wyhash algorithm (48-byte stripe loop + 16-byte tail) matching Wyhash.swift exactly. 2. Style stat updates (tool counts, sessions, denials) were non-atomic: concurrent hook invocations could read-modify-write the same JSON file and silently drop counts. Fixed by wrapping all updates in a single _update_style() function that holds an exclusive flock for the read-modify-write cycle.
|
Thanks a lot for the thoughtful write-up and the effort here — the three-profile verification and the backward-compat path are genuinely nice touches. That said, I want to be upfront before you sink more time into this: I don't think we're going to land this in its current form, and the reason is a design conflict rather than a code-quality issue. The buddy system is built around a one-time hatch identity. The core emotional beat we're trying to preserve is "this is my buddy — the one that rolled for me." For users who want to customize, the path already exists. The There's also a maintenance cost I'd want to flag: Where I think your direction has real legs is #2 — "make the buddy talk / give it personality." The stats you're already collecting (tool usage, chaos rate, session rhythm) would be perfect input for buddy dialogue flavor without touching identity at all. A chaotic-session buddy commenting "rough one, huh?" vs. a methodical-session buddy going "clean run today" is exactly the personality layer users are asking for, and it stacks cleanly on top of the stable identity instead of replacing it. Would you be interested in reworking this in that direction? Happy to scope it together on #2 if so. Closing this PR for now, but truly appreciate the contribution — the stats collection code you've already written would port directly. |
Closes #4
What this does
Adds a coding style layer to buddy identity generation. The hook now silently tracks how you actually code — which tools you reach for, how many sessions you've had, how often you deny permissions — and uses that to nudge your buddy toward a species that fits your personality.
Shell/runner-heavy coders → dragon, robot
Explorers (Read/Grep heavy) → owl, octopus
Chaotic coders (high denial rate) → ghost, blob
Methodical coders (low chaos) → turtle, penguin
Rarely codes (<5 sessions) → snail, cactus
How it works
Two things added to
buddi-hook.py:Stats accumulator — on every
PreToolUse, records the tool name into~/.buddi_style.json(a tiny local JSON file, never leaves the machine). OnSessionEnd, increments session count. On permission denial, increments denial count.compute_style_identity()— Python port of the existingBuddyDetector.roll()logic, but XORs a style delta into the seed before rolling. Species selection uses weighted probabilities with per-species boosts based on the style ratios. Same user ID + same style always produces the same buddy (deterministic).On
SessionEnd, the derived identity is attached to the socket event asstyle_identityso the Swift side can pick it up when ready.Backward compatibility
If
~/.buddi_style.jsondoesn't exist yet (fresh install, or user never had a session end),style_identityis not sent and everything behaves exactly as before.Test
Verified locally with three coding profiles:
Note on the AI policy
This PR was developed with AI assistance (Claude Code), and I've reviewed, tested, and understand every line before submitting.