情境提交 – 一种捕获 Git 历史中“为什么”的开放标准
Contextual commits – An open standard for capturing the why in Git history

原始链接: https://vidimitrov.substack.com/p/contextual-commits-an-open-standard

过去一年,作者一直在努力使编码代理真正具有协作性,为此赋予它们对项目的深入理解——超越仅仅是文件内容。最初的尝试侧重于手动向代理提供上下文,虽然有效但不可持续。各种解决方案被尝试过——规则、提取的会话数据和“技能”——但都受到难以持续捕捉*决策时刻*上下文的困扰。 突破来自于意识到 Git 的提交历史已经*记录*了会话。缺失的部分是详细提交信息的规范,解释代码更改的*原因*,而不仅仅是*内容*。这促成了“上下文提交”,一种受 Conventional Commits 启发的规范,在提交信息中使用结构化的行为行来记录意图、决策和学习到的信息。 这种方法消除了对单独上下文跟踪系统的需求,利用了 Git 本身的扩展性和并发性。一个简单的“回忆”技能允许代理主动搜索这段历史以获取推理依据。作者已经将此作为标准开源,希望得到更广泛的应用,并有可能与编码工具进行原生集成,最终目标是实现“更好的提交”——以及更知情、更具协作性的编码体验。

Hacker News 上正在讨论“情境提交 (Contextual Commits)”,这是一个提议的开放标准,旨在向 Git 历史记录中添加“原因”信息,而不仅仅是详细说明“做了什么”的更改。创建者 vidimitrov 认为,当前的提交消息侧重于“做了什么”,对于需要理解意图的自动化工具(“代理”)来说用处不大。 用户们争论结构化标签(情境提交)是否比在提交正文中写好的散文更易读——许多人承认后一种做法很少被采用。有人指出,现有的、未充分利用的提交正文 *本身* 就是解释理由的地方。 该标准提出了一种键值对格式,类似于提交中现有的“拖车 (trailers)”或“页脚 (footers)”,旨在解锁查询历史数据并启用工具。一个关键要点是,该提议不需要新的工具,只需要改变提交的 *方式*。
相关文章

原文

I’ve been using coding agents daily for the past year or so, and a constant problem I’ve been trying to address is making the agent as fluent as possible with my project so it can produce results like an experienced coworker would.

I wanted the agent to know which specific components the system has and how they relate to each other, without manually pointing to files. To produce code that meets my established conventions and expectations, and to really trust it when it says “it works now”.

But most importantly, I wanted it to be familiar with my way of thinking and past decisions, so when we start a new session, it won’t feel like we are starting from scratch.

At first, I was spending a huge amount of time on a single prompt, trying to provide the agent with everything I knew and explaining my intent as I would to a coworker. It worked surprisingly well - the agent could do miracles when it had the right reasoning at the right time. But it wasn’t scalable. So I started reverse engineering what “right reasoning and understanding at the right time” really means.

The models, the harnesses, and the tools were getting better by the day. But after a few months and after I tried pretty much everything - from creating rules in the early days, to extracting artifacts from sessions and providing them back to the agent through slash commands or MCP tools, and finally to utilising skills today - the same problem kept breaking the habit: the overhead of capturing context at the exact moment you have it. You finish a session, you're tired, the context is at its peak freshness, and that's precisely when you have to stop and document something in a separate file. Nobody does it consistently. I didn't either.

So I thought the problem could be solved through automation, and I tried some hacks using Claude hooks and native Git hooks. When I introduced this in my team, it was chaos - the quality of what we were capturing went down dramatically, and it became clear that forcing the capture was making it worse, not better.

The problem wasn't the habit. It was that I was treating something that evolves as something that sits still.

Then one evening, I was looking at a branch diff, trying to reconstruct why I had made a particular decision two weeks earlier. The commit said:

Useful. But it told me nothing about why I had done it that specific way and not the more obvious one. The reasoning was gone.

And then it hit me - the commit body has always been there. Completely underutilised. I’d been trying to build a parallel tracking system for session context when the thing that already tracks sessions already existed. A branch is a session. The commit history is the progression. The only thing missing was a convention for what goes in the body.

I drafted a small internal specification doc, inspired by the Conventional Commits one, so that I can instruct the agents to follow it through a simple skill when I want it to “commit”. And it worked very well. I’ve tested it with a bunch of commits, and I was surprised by how simple it is, yet powerful. So I called this internal specification - Contextual Commits.

Here is an example of how a Contextual Commit looks:

feat(auth): implement Google OAuth provider

intent(auth): users need social login, starting with Google before GitHub and Apple
decision(oauth-library): passport.js over auth0-sdk — better multi-provider flexibility
rejected(oauth-library): auth0-sdk locks us into their session model
constraint(callback-routes): must follow /api/auth/callback/:provider pattern
learned(passport-google): requires explicit offline_access scope for refresh tokens


The commit subject is still the good, well-known Conventional Commit, and it already captures the WHAT, but the body now captures also the WHY. What you see in the body is a simple list of action lines, each supposed to capture a signal that is not available in the diff alone. It has the same structure as the conventional commits, but with different action types.

It’s been a while now since I started using it internally, and I am definitely happy with it. During that time, I also created a simple utility skill that allows you to “recall”, or search through the contextual commit history. What changed in my workflow is not much. I just have the “contextual-commit” skill installed, and I still say the same “commit” to Claude Code or whatever harness I am using to commit my changes and auto-generate a commit message. The difference is that now it automatically creates a meaningful body as well. Regarding the “recall”, I use it in a few ways manually (running it without args so it can give me the “branch brief”, or searching for specific scope or action+scope), but mainly leave it to the agent to invoke proactively when it feels that it lacks reasoning and understanding.

I shared this with a couple of friends, and they immediately wanted to give it a try. That’s why I decided to open it as an “open standard for capturing the WHY in git history” with a small reference implementation (the “contextual-commit” and “recall” skills) that could be easily installed with:

And here is the actual repository: https://github.com/berserkdisruptors/contextual-commits

Looking back at everything I struggled with, it's almost funny how none of those problems exist here. The context decay problem - where a file stays confident long after the reasoning behind it has changed - doesn't exist here, because each action line ages together with the commit it belongs to. The merge conflict race conditions I kept hitting when multiple sessions were writing to shared context files - gone, because git's append-only log was literally built for concurrent contributors. The discipline dependency, where capturing context required a separate deliberate step at the worst possible moment - gone, because the commit you were already making is now the capture. No servers, no sync protocols, no vendor lock-in, no privacy concerns about your reasoning living somewhere else. And it scales the same way git scales - which is to say, to the Linux kernel and beyond. The more I think about it, the more it feels like this was always the right place for this information. We just hadn't needed it badly enough to notice.

It’s a specification, not a tool - one that welcomes anyone who has thought about this problem to help shape something the whole ecosystem can benefit from. If more people find it useful, harnesses might adopt it natively, which would give far more consistent behavior than skills can.

No new tools. No infrastructure. Just better commits.

联系我们 contact @ memedata.com