NEO.K / MSSP 開源專案考古013-git-authorship
專案git
授權GPL-2.0-only
檢視版本measured at run time
日期2026-08-13
來源upstream ↗

013 — git 3.x:一個宣稱自己是任何人的 commit,跟真的是同一種物件

原專案 git(GPL-2.0-only)。本篇沒有重製 git 的任何原始碼,只在一個丟棄式儲存庫上量它的行為。 版本由執行時量出來。

python src/main.py            # 三個 commit、四個欄位、哪一個分得出來
python src/main.py --strict   # 被信任的欄位如果只是宣稱就 exit 1
python src/island_test.py     # 16 項檢查,全部直接跑 git

為什麼選它

2026-08-12 我做的共識機制把三份我自己寫的檔案讀成三方同意。範例 013 把那個缺陷做成量測,結論是一個行為必須在工件之外留下痕跡

那就要問:軟體業最廣泛使用的來源存放處,有沒有這個區分?

順帶一提,這是六則連續 CPython 之後換的上游。連續六則來自同一個標準庫是取樣習慣,不是發現。

原專案的結構地圖

三個 commit:一個誠實的、一個冒充的、一個帶著沒人檢查的 trailer。

  commit    author           committer        %G?   subject
  81f34c5   Real Person      Real Person      N     an ordinary commit
  0a52707   Linus Torvalds   Linus Torvalds   N     a commit by someone who was not there
  d9bd66c   Real Person      Real Person      N     work

冒充那一個不需要任何漏洞——GIT_AUTHOR_NAMEGIT_COMMITTER_NAME 是有文件的環境變數。原始物件裡也沒有多任何東西:

    tree 6640fb01ffae1cdd778a3fe65b469f62a5230def
    parent 81f34c5c647570cac07e593351d0caba2134605f
    author Linus Torvalds <torvalds@linux-foundation.org> 1786590221 +0800
    committer Linus Torvalds <torvalds@linux-foundation.org> 1786590221 +0800
    contains a signature block: False
欄位 記錄的是 分得出誠實與冒充嗎
author 宣稱 值不同——而那個不同就是對方打進去的字
committer 宣稱 同上
trailer 宣稱 git 不讀它回來
signature 行為 不能——兩個都回報 N

MSSP 重切

集合 裡面是什麼
FMS 四個欄位、各自記錄宣稱還是行為,以及 units 對照
SCL 這個部署會信任哪一個欄位當身分
SMS 依 id 解析欄位、分辨測試,以及跑真 git 的探針
TMS 一個欄位一個檔——各自宣告 claimact,且不 import 任何東西
DMS git 印出來的 log,以及哪一個欄位本來可以分辨

重切加的只有一件事:每個欄位宣告自己記錄的是宣稱還是行為。 git 沒有這個區分——呼叫端讀 %an 拿到的是一個字串,而那個字串在「有人寫了這個 commit」與「有人打了那個人的名字」兩種情況下形狀完全一樣,介面沒有任何地方可以問是哪一種。

什麼不適合拆

git 沒有做錯,不要「修」這個。 一個分散式版本控制系統不可能有一個發放身分的權威——沒有中央,就沒有人能替 author 背書。簽章存在,正是因為 author 不是身分。

而這一則的發現就在那個「正是因為」的後面:

一個「可以」是行為的欄位,在有人真的執行它之前,並不是行為。

%G? 有八種取值(G/B/U/X/Y/R/E/N),而在沒有人簽的儲存庫裡它對每一個 commit 回報 N一個存在、而且沒有人行使的判別器——跟考古 011d[k] is d[k] 是同一個形狀。

這次沒有解決什麼

先講一個自我牽連的:這個儲存庫的每一個 commit 都帶著 Co-Authored-By: Claude Opus 5 量到的結果是:git 不會讀那一行回來。 它是內容裡的一句宣稱——跟我 08-12 寫下然後讀成同意的那三個檔案,是完全相同的形狀。

量得到但這次沒量: 真實儲存庫裡有多少 commit 帶著有效簽章;Co-Authored-By 裡有多少比例指的是真的碰過那個分支的人。

這一則量不到: 任何一個 commit 是不是誠實的。它量的是欄位「能」承載什麼,不是它們實際承載了什麼。distinct-provenance 那條路的盡頭也在這裡——把問題從工件搬到來源存放處,是搬移,不是終結。

重切原始碼

FMS

FMS/__init__.py
FMS/architecture.json
{
  "name": "013-git-authorship",
  "upstream": "git",
  "examined_version": "measured at run time",
  "license": "GPL-2.0-only (git itself; nothing of git's source is reproduced here)",
  "what_it_is": "The fields a commit carries about who made it, and which of them records an act rather than a claim.",

  "why_this_one": "On 2026-08-12 I built a consensus mechanism that read three identical files as three-party agreement; I had written all three. Example 013 the same day turns that into a measurement. This asks whether the most widely used provenance store in software has the distinction the example says is needed — and it is not CPython, because six consecutive entries from one standard library is a sampling habit rather than a finding.",

  "fields": {
    "author": {"kind": "claim", "set_by": "GIT_AUTHOR_NAME, a documented environment variable"},
    "committer": {"kind": "claim", "set_by": "GIT_COMMITTER_NAME, likewise"},
    "trailer": {"kind": "claim", "set_by": "typing a line in the commit message; nothing in git reads it back"},
    "signature": {"kind": "act", "set_by": "a cryptographic operation performed with a key"}
  },

  "the_finding": "A commit claiming to be anyone is the same kind of object as an honest one. `git log` prints them identically, the raw object contains nothing extra, and no exploit is involved. The only field that records an act rather than a claim is the signature — and when nobody signs, %G? reports N for the honest commit and the impersonation alike. A field that CAN be an act is not one until someone performs it.",

  "the_self_implication": "Every commit in this repository carries `Co-Authored-By: Claude Opus 5`. Measured here: nothing in git reads that line back. It is a claim in content, which is exactly the shape of the three branch files I wrote and then read as agreement.",

  "sets": {
    "FMS": "this file: the fields, what each records, and what the entry measures",
    "SCL": "which field this deployment would trust for identity",
    "SMS": "field resolution by id, the separation test, and the probes against a throwaway repository",
    "TMS": "one file per field — each declares claim or act, and reaches no sibling set",
    "DMS": "the log as git prints it, and which field could have told the difference"
  },

  "units": {"TMS/fields": ["author.py", "committer.py", "signature.py", "trailer.py"]},

  "non_goals": [
    "Saying git is wrong. A distributed VCS cannot have an authority that issues identities, and signing exists precisely because the author field is not one.",
    "Cryptography. No key is generated; the entry measures what the signature FIELD reports when unused, which is the finding.",
    "Any claim about commits in the wild. This measures what the fields can carry, not what they do carry."
  ]
}

SCL

SCL/__init__.py
SCL/policy.json
{
  "field_trusted_for_identity": "signature",
  "a_claim_field_used_as_identity_is_fatal": true,
  "_note": "main.py measures every field regardless of what this says."
}
SCL/policy.py
"""Which field this deployment would trust for identity."""
import json
import pathlib

_C = json.loads((pathlib.Path(__file__).parent / "policy.json").read_text(encoding="utf-8"))

trusted = lambda: _C["field_trusted_for_identity"]                                # noqa: E731
claim_as_identity_is_fatal = lambda: bool(_C["a_claim_field_used_as_identity_is_fatal"])  # noqa: E731

SMS

SMS/__init__.py
SMS/fields.py
"""The re-cut: every field declares whether it records a CLAIM or an ACT.

git has no such distinction. A caller reading `%an` gets a string with the same
shape whether a person authored the commit or typed someone's name, and nothing
in the interface offers to say which.
"""
import importlib

FIELDS = ["author", "committer", "trailer", "signature"]


def load():
    loaded, problems = {}, []
    for name in FIELDS:
        try:
            module = importlib.import_module(f"TMS.fields.{name}")
        except ModuleNotFoundError:
            problems.append(f'field "{name}" has no module - fail closed')
            continue
        for attribute in ("NAME", "KIND", "WHAT_IT_RECORDS"):
            if not hasattr(module, attribute):
                problems.append(f"{name} does not declare {attribute}")
        if getattr(module, "KIND", None) not in {"claim", "act"}:
            problems.append(f"{name}: KIND must be claim or act, not {getattr(module, 'KIND', None)!r}")
        loaded[module.NAME] = module
    return loaded, problems


def resolve(name, loaded):
    module = loaded.get(name)
    if module is None:
        return None, f'field "{name}" has no implementation - fail closed (known: {", ".join(sorted(loaded))})'
    return module, None


def separates(rows, field):
    """Does this field take different values for the honest and the impersonating commit?"""
    honest, impersonating = rows[0], rows[1]
    return honest[field] != impersonating[field]
SMS/upstream.py
"""What real git records, measured in a throwaway repository.

Nothing here is an exploit. GIT_AUTHOR_NAME and GIT_COMMITTER_NAME are
documented environment variables, and a Co-Authored-By trailer is a line of the
commit message.
"""
import os
import subprocess
import tempfile

IMPERSONATED = ("Linus Torvalds", "torvalds@linux-foundation.org")


def _git(cwd, *args, env=None):
    return subprocess.run(("git",) + args, cwd=cwd, env=env,
                          capture_output=True, text=True).stdout


def build_repository():
    """Three commits: honest, impersonating, and one with an unchecked trailer."""
    directory = tempfile.mkdtemp()
    _git(directory, "init", "-q")
    _git(directory, "config", "user.name", "Real Person")
    _git(directory, "config", "user.email", "real@example.com")
    _git(directory, "config", "commit.gpgsign", "false")

    open(os.path.join(directory, "a.txt"), "w").write("one\n")
    _git(directory, "add", "-A")
    _git(directory, "commit", "-q", "-m", "an ordinary commit")

    open(os.path.join(directory, "b.txt"), "w").write("two\n")
    _git(directory, "add", "-A")
    env = dict(os.environ, GIT_AUTHOR_NAME=IMPERSONATED[0], GIT_AUTHOR_EMAIL=IMPERSONATED[1],
               GIT_COMMITTER_NAME=IMPERSONATED[0], GIT_COMMITTER_EMAIL=IMPERSONATED[1])
    _git(directory, "commit", "-q", "-m", "a commit by someone who was not there", env=env)

    open(os.path.join(directory, "c.txt"), "w").write("three\n")
    _git(directory, "add", "-A")
    _git(directory, "commit", "-q", "-m",
         "work\n\nCo-Authored-By: Someone Who Never Saw This <nobody@example.com>")
    return directory


def commits(directory):
    rows = []
    for line in _git(directory, "log", "--reverse",
                     "--format=%h\t%an\t%cn\t%G?\t%s").strip().splitlines():
        short, author, committer, sig, subject = (line.split("\t") + [""] * 5)[:5]
        rows.append({"commit": short, "author": author, "committer": committer,
                     "signature_status": sig, "subject": subject})
    return rows


def raw_object(directory, index=1):
    sha = _git(directory, "log", "--reverse", "--format=%H").split()[index]
    return _git(directory, "cat-file", "-p", sha)


def trailer(directory):
    return _git(directory, "log", "-1", "--format=%(trailers)").strip()


def version():
    return _git(tempfile.mkdtemp(), "--version").strip().split()[-1]

TMS

TMS/__init__.py
TMS/fields/__init__.py
TMS/fields/author.py
"""git's `author` field.

whoever ran the command, or whatever GIT_AUTHOR_NAME said
"""
NAME = "author"
KIND = "claim"
WHAT_IT_RECORDS = "whoever ran the command, or whatever GIT_AUTHOR_NAME said"
TMS/fields/committer.py
"""git's `committer` field.

whoever ran the command, or whatever GIT_COMMITTER_NAME said
"""
NAME = "committer"
KIND = "claim"
WHAT_IT_RECORDS = "whoever ran the command, or whatever GIT_COMMITTER_NAME said"
TMS/fields/signature.py
"""git's `signature` field.

a cryptographic operation someone had to perform with a key
"""
NAME = "signature"
KIND = "act"
WHAT_IT_RECORDS = "a cryptographic operation someone had to perform with a key"

# The ceiling, and it is the finding of the entry: when nobody signs, %G? reports
# N for an honest commit and for an impersonation alike. A field that CAN be an
# act is not one until someone performs it.
UNIFORM_WHEN_UNUSED = "N"
TMS/fields/trailer.py
"""git's `trailer` field.

a line of the commit message; nothing in git reads it back
"""
NAME = "trailer"
KIND = "claim"
WHAT_IT_RECORDS = "a line of the commit message; nothing in git reads it back"

DMS

DMS/__init__.py
DMS/report.py
"""The log as git prints it, and which field could have told the difference."""


def log(rows, out):
    out(f"\n  {'commit':<9} {'author':<16} {'committer':<16} {'%G?':<5} subject")
    for row in rows:
        out(f"  {row['commit']:<9} {row['author']:<16} {row['committer']:<16} "
            f"{row['signature_status']:<5} {row['subject']}")


def fields(loaded, rows, separates, out):
    out(f"\n  {'field':<11} {'records':<7} {'separates honest from impersonating?':<38} value on both")
    for name, module in sorted(loaded.items()):
        if name in ("author", "committer"):
            # It differs, of course - but the difference is whatever the
            # impersonator typed. A field that varies is not a field that tells.
            answer = "it differs, and the difference is what was typed" if separates(rows, name) else "no"
            value = f"{rows[0][name]} vs {rows[1][name]}"
        elif name == "signature":
            answer = "no - both report N" if not separates(rows, "signature_status") else "yes"
            value = rows[0]["signature_status"]
        else:
            answer = "nothing in git reads it back"
            value = "-"
        out(f"  {module.NAME:<11} {module.KIND:<7} {answer:<38} {value}")


def gaps(out):
    out("\n  measurable, not measured here:")
    out("    - how many commits in a real repository carry a good signature")
    out("    - what fraction of Co-Authored-By trailers name someone who touched the branch")
    out("\n  not measurable by this entry at all:")
    out("    - whether git is wrong to work this way. A distributed VCS cannot")
    out("      have an authority that issues identities, and signing is offered")
    out("      precisely because the author field cannot be one.")
    out("    - whether any particular commit anywhere is honest. This measures")
    out("      what the fields CAN carry, not what they do carry.")

root

island_test.py
"""The island test.

    python src/island_test.py

Section 2 is the finding: the field that CAN record an act reports the same
value for the honest commit and the impersonation, because nobody signed.
"""
import json
import pathlib
import re
import sys

HERE = pathlib.Path(__file__).parent
sys.path.insert(0, str(HERE))

from SCL import policy  # noqa: E402
from SMS import fields, upstream  # noqa: E402

ARCH = json.loads((HERE / "FMS" / "architecture.json").read_text(encoding="utf-8"))
FAILURES = []


def check(label, ok, detail=""):
    print(f"  {'PASS' if ok else 'FAIL'}  {label}{' - ' + detail if detail else ''}")
    if not ok:
        FAILURES.append(label)


LOADED, PROBLEMS = fields.load()
DIRECTORY = upstream.build_repository()
ROWS = upstream.commits(DIRECTORY)

print("\n== 1. every field is an island, declares claim or act, and FMS matches the tree")
check("all four fields loaded with no problems", not PROBLEMS, "; ".join(PROBLEMS))
field_dir = HERE / "TMS" / "fields"
files = sorted(f.name for f in field_dir.iterdir() if f.suffix == ".py" and f.name != "__init__.py")
for name in files:
    reaches = re.findall(r"^\s*(?:from|import)\s+(\S+)", (field_dir / name).read_text(encoding="utf-8"), re.M)
    check(f"{name} reaches no sibling set", not reaches, ", ".join(reaches) or "no imports at all")
for where, expected in ARCH["units"].items():
    on_disk = sorted(f.name for f in (HERE / where).iterdir()
                     if f.suffix == ".py" and f.name != "__init__.py")
    check(f"{where}: FMS declares {len(expected)}, on disk {len(on_disk)}",
          on_disk == sorted(expected), ", ".join(on_disk))
check("exactly one field declares itself an act",
      sum(1 for m in LOADED.values() if m.KIND == "act") == 1,
      ", ".join(f"{m.NAME}={m.KIND}" for m in sorted(LOADED.values(), key=lambda m: m.NAME)))

print("\n== 2. the impersonating commit is the same kind of object")
honest, impersonating = ROWS[0], ROWS[1]
check("git reports a different author for it", honest["author"] != impersonating["author"],
      f"{honest['author']} vs {impersonating['author']}")
check("and that is the whole of what git knows - the raw object carries no signature",
      "gpgsig" not in upstream.raw_object(DIRECTORY))
check("the one field that could tell them apart reports the SAME value",
      honest["signature_status"] == impersonating["signature_status"],
      f"%G? = {honest['signature_status']} for both")
check("so a field that CAN be an act is not one until someone performs it",
      LOADED["signature"].KIND == "act"
      and honest["signature_status"] == LOADED["signature"].UNIFORM_WHEN_UNUSED)

print("\n== 3. the trailer is a line of the message")
check("a Co-Authored-By naming someone who never saw the branch is stored verbatim",
      "Someone Who Never Saw This" in upstream.trailer(DIRECTORY), upstream.trailer(DIRECTORY))
check("and it is declared a claim, not an act", LOADED["trailer"].KIND == "claim")

print("\n== 4. fail closed")
_, problem = fields.resolve("gpg-web-of-trust", LOADED)
check("an unresolvable field stops the run", problem is not None, problem or "resolved anyway")
check("SCL names a field that exists", policy.trusted() in LOADED, policy.trusted())
check("and the field it trusts is the one declared an act",
      LOADED[policy.trusted()].KIND == "act", f"{policy.trusted()} = {LOADED[policy.trusted()].KIND}")

print("\n== 5. what this entry cannot see")
print("        MEASURABLE, NOT MEASURED")
print("          - how many commits in a real repository carry a good signature")
print("          - what fraction of Co-Authored-By trailers name someone who was there")
print("        NOT MEASURABLE HERE")
print("          - whether git is wrong to work this way. A distributed VCS has no")
print("            authority to issue identities, and signing exists because the")
print("            author field is not one.")
print("          - whether any commit anywhere is honest. This measures what the")
print("            fields CAN carry, not what they do.")

print(f"\n{len(FAILURES)} failure(s)" if FAILURES else "\nall checks passed")
for f in FAILURES:
    print(f"  - {f}")
sys.exit(1 if FAILURES else 0)
main.py
"""git's fields about who made a commit, measured against a throwaway repository.

    python src/main.py            the log, the fields, and which one separates
    python src/main.py --strict   exit 1 if the trusted field is a claim
"""
import json
import pathlib
import sys

HERE = pathlib.Path(__file__).parent
sys.path.insert(0, str(HERE))

from DMS import report  # noqa: E402
from SCL import policy  # noqa: E402
from SMS import fields, upstream  # noqa: E402

ARCH = json.loads((HERE / "FMS" / "architecture.json").read_text(encoding="utf-8"))


def main(argv):
    out = lambda line="": sys.stdout.write(line + "\n")  # noqa: E731
    loaded, problems = fields.load()
    if problems:
        for problem in problems:
            out(f"  !! {problem}")
        return 1

    directory = upstream.build_repository()
    rows = upstream.commits(directory)

    out(f"\n== three commits, one of which was not made by who it says  [git {upstream.version()}]")
    report.log(rows, out)
    report.fields(loaded, rows, fields.separates, out)

    out("\n== the raw object of the impersonating commit")
    for line in upstream.raw_object(directory).splitlines()[:5]:
        out(f"    {line}")
    out(f"    contains a signature block: {'gpgsig' in upstream.raw_object(directory)}")

    out("\n== the trailer, and what reads it")
    out(f"    stored:  {upstream.trailer(directory)}")
    out("    read by: nothing in git. It is a line of the message.")
    out(f"    note:    {ARCH['self_implication'] if 'self_implication' in ARCH else ARCH['the_self_implication']}")

    trusted, problem = fields.resolve(policy.trusted(), loaded)
    if problem:
        out(f"\n  !! {problem}")
        return 1
    out(f"\n== this deployment would trust `{trusted.NAME}` for identity, which records {"an act" if trusted.KIND == "act" else "a claim"}")

    report.gaps(out)

    if "--strict" in argv and trusted.KIND == "claim" and policy.claim_as_identity_is_fatal():
        return 1
    return 0


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))