recording-friction · git:20260901.57e1092 · 2026-09-01 · sha256 defe52d1bc88b387
recording-friction git:20260901.57e1092A
Immutable. This exact content is served forever at /api/v1/blob/defe52d1bc88b387.
--- name: recording-friction description: >- When and how to record friction with `record_friction` — the moment a tool is missing, awkward, or wrong, and the moment you catch yourself taking a long way round. Read this when you hit a rough edge, when you reach for a shell to do something that should be a tool, or when you are triaging the friction backlog. --- # Recording friction The friction ledger is how this system improves itself. Auto-capture already logs tool errors and escape-hatch reaches; it cannot see the thing only you know — that a tool was *there* and *awkward*, that an error message sent you the wrong way, or that you got the right answer by the wrong route. **The bar is low on purpose.** An unrecorded friction point costs the next agent the same hour it cost you. A slightly noisy ledger costs one line. ## Record it at the moment it happens Not at the end of the turn, not "if it comes up again". You will have moved on and the specifics — the exact path, the exact error, the call you wished existed — are the whole value. A summary written from memory an hour later is a complaint; one written in the moment is a spec. ## Which channel `kind="harness"` — **the tooling should change.** - A tool you needed did not exist. - A tool existed but made you do it in N calls when one would have done. - An error message was wrong, vague, or pointed at the wrong cause. - You reached for a shell/`run_command` for something that should be first-class. - A limit bit you (truncation, pagination, a cap) and you had to work around it. `kind="model"` — **you should have known better.** A wrong path you recognized, a weak answer, a retry you caused. This is a labeled trace, not self-flagellation; record it and move on. ## Severity `major` when it **blocked** you or produced a wrong result you had to undo. `minor` when it cost you time or elegance. Be honest in both directions — everything marked major is the same as nothing marked major. ## Write it so it can be fixed A summary is one line, and it is a **claim about the system**, not a feeling: - ✅ `read_file truncates at 50k chars — reconstructing a 167KB file took ~8 search_files calls` - ❌ `read_file was annoying` Then put the reproduction in `detail`: what you were doing, what happened, and — the part people forget — **what would have helped**. "A `from_line`/`to_line` parameter would have made this one call" is the sentence that turns a report into a ticket. Keep the summary under ~200 characters and the detail under ~600: the ledger caps both on write, and it cuts mid-word. ## Do not record - A tool refusing you on purpose (a permission gate, an approval pause, a HITL interrupt). That is the system working. - A failure you caused and immediately fixed with no lesson in it. - The same friction twice in one turn — identical summaries are grouped, so say it once and let the count speak. ## Reviewing and closing the loop `friction_review` reads the backlog; open friction also appears in your `<working_state>` under **OPEN FRICTION**, so you do not need to poll for it. Call `resolve_friction` **when the rough edge is actually fixed** — the fix merged, the tool shipped. It stamps `resolved_at` in place (nothing is deleted, the audit trail survives) and drops the entry from the backlog and from the operator's console alike. Do not use it to quiet a signal you have not fixed; a live problem marked resolved is worse than one never recorded, because now nobody is looking. If a friction point warrants a tracked fix, file it in the repo that owns the fix and say so in the resolve reason.