record who authored a commit, and who merely asked for it

Authorship named the human on commits the agent wrote start to finish, with a
Co-Authored-By trailer as the only trace of who did the work. That is backwards:
directing a change is not writing it, and a log that cannot tell the two apart
cannot answer "how much of this did the agent write" — a question worth being
able to ask honestly about a repository built this way.

Three cases, no fourth: agent alone is agent-authored with no trailer, since the
author field already says it; both is the human's with the agent as co-author;
the human alone names only the human. The committer and the GPG signature stay
the human's throughout — the key attests to taking responsibility for a commit,
not to having typed it.

Applied to the whole history in the same sitting: 62 of 63 commits are now
agent-authored, init is the human's with a co-author trailer, and every tree,
message, parent and author date is byte-identical to before. Committer dates were
restored from backup/pre-fold, since the earlier fold had reset all 62 of them to
the moment of the replay.

The state.md sha rides along rather than taking its own commit: rewriting the
history is what invalidated it, and the verify.sh advisory that caught it is the
same one that caught the previous rewrite.
This commit is contained in:
Claude Opus 5
2026-08-01 02:37:37 +06:00
committed by bdeshi
parent 8905686d27
commit aad7d64270
3 changed files with 21 additions and 1 deletions
+6
View File
@@ -90,6 +90,12 @@ even when it is harmless. The asymmetry is the argument: a commit you did not wa
away, and work that existed only in the working tree when something went wrong is gone. If you want
the tree left dirty, say so and the loop stops at Document.
Authorship records who wrote the bytes: a commit the agent wrote is authored by it, one you both wrote
is yours with the agent as co-author, one you wrote alone names only you (`conventions.md` "Git"). You
remain the committer and the signature in every case — the key says you take responsibility for the
commit, which is not the same claim as having typed it. `git log --author=Claude` is then a truthful
answer to how much of this the agent wrote.
**What is staged has to build, not just the working tree.** Every other gate looks at your files; this one
looks at the commit you are about to make, by building a throwaway checkout of the index. It exists because
staging a subset — a changed signature without its caller — produced a commit that did not compile while
+14
View File
@@ -107,3 +107,17 @@ already wrong beforehand is a separate unit even when it lands in the same sitti
Imperative subject under 72 characters; body says *why*, and carries the numbers the change earned.
Committing happens by itself and needs no request (`CLAUDE.md` §4); pushing never does.
**Authorship names who wrote the bytes, not who asked for them.** Three cases, no fourth:
| Who wrote the change | `Author` | Trailer |
|---|---|---|
| the agent alone | `Claude Opus 5 <noreply@anthropic.com>` | none — the author field already says it |
| both | the human | `Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>` |
| the human alone | the human | none |
Directing a change is not writing it: a one-sentence request that the agent implements in full is
agent-authored. The committer stays the human in every case, and so does the signature — the key
attests to taking responsibility for the commit, which is a different claim from having written it.
`git log --author=Claude` is then an honest answer to "how much of this did the agent write", which is
the whole point of recording it.
+1 -1
View File
@@ -1,6 +1,6 @@
# State
**Verified against:** `8900aab` on 2026-07-30 — update this line every change.
**Verified against:** `de1ce73` on 2026-07-30 — update this line every change.
If this file disagrees with the code, the code is right and this file is a bug.
## Inventory