Chunks from friction
The friction log works today and is useful, but the design isn't finalized. The implementation may change, significant rethinking is possible, and input is welcome.
The friction log is an accumulative ledger. You write down pain points as you hit them: something that almost worked, a workflow gap, a confusing CLI behavior, a doc that lied. The log doesn't fix anything by itself; it remembers, so a pattern can emerge.
When three or more entries cluster around a theme, that's signal: there's probably something to do in there. Whether it's a chunk or just something to vibe depends on what the work looks like once the pattern is named. A chunk if the resolution carries architectural intent. Vibe it if it's a mechanical fix the code doesn't need to remember.
Logging
Friction is captured with the /friction-log skill.
Describe what bit you and ask the agent to log it; the skill picks
the theme, writes a short description, and appends an entry to
docs/trunk/FRICTION.md (calling
ve friction log underneath). Each entry has an ID, a
date, a theme tag, and a short description:
### F012: 2026-04-26 [orchestrator] Hard to tell why a chunk was flagged
The attention queue shows that my_chunk needs attention but doesn't say
which other chunk it conflicts with. I had to grep the daemon logs to
figure out it was the parallel auth refactor.
Themes are loose categories that grow over time:
orchestrator, cli, docs,
workflow. Use an existing theme if it fits; add a new one
when nothing matches.
The lifecycle is derived
Entries don't have a status field. Their lifecycle is computed from the rest of the document:
| State | Meaning |
|---|---|
OPEN | Entry isn't referenced by any proposed chunk. |
ADDRESSED | Entry appears in a proposed_chunks.addresses list and the chunk has been created. |
RESOLVED | The chunk that addresses the entry has reached ACTIVE. |
No one sets these. They follow from the relationship between the friction entry and the chunk that addresses it.
From pattern to chunk
When a theme has accumulated enough (typically three or more entries with a shared root cause), tell the agent to add a proposed chunk to the friction log's frontmatter that addresses the cluster. The frontmatter ends up looking like this:
proposed_chunks:
- prompt: "Surface conflict reasons in the orchestrator attention queue"
chunk_directory: null
addresses:
- "F001: Over-eager conflict oracle causes unnecessary blocking"
- "F004: Hard to tell why a chunk was flagged"
- "F011: Operator can't see which chunk caused a conflict" addresses is a list of entry titles: the friction this
chunk would resolve. Once the chunk is created and reaches
ACTIVE, the listed entries are derived as
RESOLVED.
Realizing the chunk
Run the intent test on the proposal first: does the resolution carry architectural intent that future contributors will need to reconstruct? If yes, ask the agent to materialize it as a FUTURE chunk. If no, the friction is real but the fix is just something to vibe; close the friction entries when the fix lands and skip the chunk.
When the agent materializes the chunk, it updates the proposed
chunk's chunk_directory in FRICTION.md to point at
the new directory. The friction-to-chunk linkage is now closed;
subsequent runs of ve chunk list-proposed won't
surface it as outstanding.
Why log friction at all
Real friction is hard to remember in the moment when you're trying to ship something else. The log lets you keep moving and gives a future you (or another agent) a map of where the rough edges actually are. The patterns in the log are usually more honest than a planning meeting would be.
Run ve friction analyze when the log gets long. It
surfaces themes that have crossed the "probably a chunk" threshold
and suggests where to look next.