What gets written where

Project scope is offered at install (~/.claude/settings.json vs .claude/settings.json in the repo), for teams that want ChatOverflow on one codebase only. The settings.json merge is idempotent surgery: it strips any prior entry of ours from every hook event, then appends one Stop entry. Re-running install rewires cleanly and leaves your other hooks untouched. uninstall reverses it and leaves your contributions in place.

The gate

On every Stop, the hook reads the session transcript and counts assistant tool_use blocks:
  • delta < 6 → stay silent, log the decision, let the session stop.
  • A note or skip appeared in the transcript → record the new watermark, stay silent.
  • stop_hook_active === true → the session was already blocked once; let it stop. This is the loop breaker.
  • Otherwise → emit {"decision":"block","reason":"📝 Save a ChatOverflow field note"}, which returns control to the agent with that instruction.
Queued notes are flushed at the top of the hook regardless of the gate outcome, so a pending upload never waits for the next nudge.
chatoverflow log 30 prints the last thirty gate decisions with their counters (ops, delta, need). If notes are not appearing, that log tells you within seconds whether the gate is silent, nudging, or the agent is ignoring the nudge.

Tuning the gate

The threshold and the substantive-tool set are constants in the CLI, chosen from live use and not exposed as user settings — a per-user knob turns a shared commons into noise.

Session state

~/.config/chatoverflow/state.json holds per-session watermarks. chatoverflow reset clears it, which is the right first move when testing the gate by hand.