feat: record AI coding agent involvement in chalk marks - #765
Open
nettrino wants to merge 2 commits into
Open
Conversation
env_default_action defaults to "ignore", which drops rather than redacts, so agent env vars never reached INJECTOR_ENV. Adds them to env_always_show, ordered to match gh's own agent detection so chalk and gh agree on a build. Adds X_AI_AUTHORSHIP (ChalkTimeHost, conffile callback): build_agent from the environment, plus AI-authorship trailers and agent git identities on HEAD. Trailer and identity collection shells out to git guarded by find_exe, since no con4m builtin can read COMMIT_MESSAGE and chalk otherwise needs only libgit2. Aider needs the identity path: it defaults to rewriting the git author rather than adding a trailer. Keyspec and template subscriptions ship as one component because loading the subscriptions alone is a hard validation error. All signals are advisory and user-suppressible: presence is evidence of agent involvement, absence is not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Adds two config-only mechanisms for recording AI coding agent involvement in a build. No Nim changes, no recompile — both ship as loadable
.c4m.A — agent env vars reach
INJECTOR_ENV(configs/co/env_vars.c4m)env_default_actiondefaults to"ignore", andignoremeans dropped, not masked (src/plugins/system.nim:196-204). So today every AI-agent env var is silently absent fromINJECTOR_ENV, which ships only the five allowlisted vars. This adds the agent vars to~env_always_show, ordered to matchgh's own detection list.B — new
X_AI_AUTHORSHIPkey (configs/ai_provenance_key.c4m,configs/ai_provenance.c4m)A
ChalkTimeHostkey collected by theconffileplugin via a con4m callback, so it lands in the chalk mark. Three independent signals, emitted as newline-separatedfield=value:build_agent=ghtrailer=gitbinaryidentity=gitbinaryModelled on the two in-tree config-only key precedents,
configs/co/build_observables_key.c4mandconfigs/co/curiosity_logs_key.c4m.Design notes
COMMIT_MESSAGEalready carries the raw trailer.src/utils/git/chalk_git.c:1143calls libgit2'sgit_commit_message()— the full message, notgit_commit_summary()— trimmed only for whitespace (chalk_git.c:190-203). It'suse = truein all four major mark templates and six report templates, soCo-Authored-By: Claude …has been shipping in chalk marks already.X_AI_AUTHORSHIPadds structure, not new data.COMMIT_MESSAGE. There is no con4m builtin to read another collected key, so the callback shells out togitinstead. Chalk otherwise reads git through libgit2 and does not require the git binary, so this is guarded byfind_exe("git", [])and skipped when unavailable rather than becoming a dependency. If first-class trailer keys are wanted later, the right home ispackGitInfo()insrc/plugins/vctlGit.nim:153-187, whereinfo.commitMessageis already in hand — pure derivation, no subprocess.identity=signal. Itsattribute_co_authored_bydefaults tofalse; by default it rewrites the git author/committer instead. A trailer-only check misses it entirely.identity=matching is deliberately conservative — vendor addresses plus Aider's literalaider (<model>)name form, not bare product names. "Devin" is a common human first name.reproducable— the value derives from the environment and HEAD, so it isn't reproducible across builds. Also skipped:minimal,chalk_labels.X_AI_AUTHORSHIP(underscore) to match in-tree practice (_X_BUILD_OBSERVABLES,_X_CURIOSITY_LOGS), rather than theX-spelling in thechalk.c42specprose. Hyphens would need quoting inkey.<NAME>attribute paths. No validator enforces either form.AI_AGENT; reading the vars is uncontroversial, changing behaviour on them is not.Reliability — read before depending on this
Every signal here is high-precision, low-and-unknowable recall. Presence is strong evidence an agent was involved. Absence is no evidence either way. Do not gate policy on a missing value.
Suppression paths, all user-controlled: Claude Code's
attribution.{commit,pr,sessionUrl}(and legacyincludeCoAuthoredBy: false), Aider'sattribute_co_authored_by,CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1,CLAUDE_CODE_SUPPRESS_SESSION_ATTRIBUTION, or anycommit-msghook. Trailer stripping is widespread and well-tooled.Separately worth fixing (not in this PR)
src/configs/base_keyspecs.c4m:389documentsenv_default_actionas defaulting to"redact". It actually defaults to"ignore"(src/configs/chalk.c42spec:4358-4366), and the two behave differently —redactemits<<redact>>,ignoredrops the variable entirely. Same wording at:5581.Testing
Validated end-to-end against
crashappsec/chalk:latest, which is chalk 1.2.0 at commit8543bf008665a4b86971bd7a121444baf1a58240— exactly this branch's base.chalk load configs/ai_provenance.c4m→ "Configuration successfully validated."chalk help key X_AI_AUTHORSHIPthen reports it asChalk-Time, Host/stringwith the doc string, confirming the component takes effect rather than merely parsing.Behaviour matrix, asserted on the mark actually written into the artifact (not the report):
Co-Authored-By:+Assisted-by:build_agent=claude-code_2-1-220_agent, plus bothtrailer=linestrailer=Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>identity=author aider (gpt-4o) <human@example.com>Two incidental confirmations from that run: the published chalk image is distroless (no shell, no
git), and there thefind_exe("git", [])guard correctly degrades to emitting nothing rather than erroring — which is the intended behaviour in a minimal build container. And thekeyspecand its template subscriptions must ship as one component: loading the subscriptions alone fails hard with "Chalk mark template 'mark_default' contains a key: 'X_AI_AUTHORSHIP', which does not exist".No functional tests added to
tests/functional/— flagging as a reviewer decision, sincetest_git.py:164-184is the model for git-key assertions if wanted.Full research
The findings behind this PR follow in full, as requested. Method: local binary teardown of Claude Code 2.1.220, Codex 0.153.2 and Gemini CLI; chalk source audit; primary-source doc verification; community and policy survey.
AI-Authorship Provenance in Chalk — Research Findings
Research date: 2026-09-04. Chalk
main@8543bf00(v1.2.0).Method: local binary teardown (Claude Code 2.1.220, Codex 0.153.2, Gemini CLI), chalk source
audit, primary-source doc verification, community/policy survey.
Confidence labels: [VERIFIED] = I reproduced it locally or read it in a primary source.
[PRIMARY] = quoted from vendor docs/spec. [SECONDARY] = credible third party.
[CLAIMED] = single-source or anecdote.
1. Bottom line
Three findings drive everything below.
watermark, but it is statistical (server-side sampling), explicitly suppressed where code
correctness matters, detectable only via a private-preview API, and inactive on most
models in circulation. Nothing is embedded in the bytes.
trailer — inside
COMMIT_MESSAGE. It is unparsed. This is a parsing problem, not acollection problem.
involvement; absence proves nothing. Every mechanism is user-suppressible. Design for
advisory reporting, not enforcement.
2. What the vendors actually emit
2.1 Anthropic — statistical watermark, not steganographic
[PRIMARY] https://www.anthropic.com/news/claude-text-watermark (2026-08-14):
[PRIMARY] https://support.claude.com/en/articles/16266773-how-claude-marks-ai-generated-content:
Mechanism: SynthID-Text tournament sampling (Nature 634, 2024-10-24,
DOI
10.1038/s41586-024-08025-4; https://github.com/google-deepmind/synthid-text). Keyedg-values over preceding context bias sampling. Not Kirchenbauer green-list.
Why chalk cannot use it — four independent blockers:
claude-opus-5,claude-sonnet-5, Opus 4.x are all in the transition period → unmarked.[VERIFIED] Local teardown of
@anthropic-ai/claude-code/bin/claude.exev2.1.220(257 MB, 652k strings): zero hits for
c2pa,synthid,steg. All 176watermarkhits areNode's
highWaterMark. Build constants:VERSION:"2.1.220",BUILD_TIME:"2026-07-24T22:17:45Z",GIT_SHA:"4073f59596e272f39393db4f96abc5f4b10eff21".Client-side absence is expected and is not evidence about the server-side watermark.
2.2 C2PA — architecturally excluded from source files
[PRIMARY] https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool
(line 893 of fetched doc):
→ Do not build a C2PA reader for source artifacts. Code is unsignable under C2PA, by
format, not by omission. (Chalk's existing model codecs handle GGUF/safetensors — C2PA on
media artifacts could matter there, separate scope.)
2.3 Git trailers — the real, usable signal
Co-Authored-By: <model> <noreply@anthropic.com>🤖 Generated with [Claude Code](https://claude.com/claude-code)Rry()), deterministicClaude-Session: <claude.ai session URL>Ary(); cloud/Remote-Control sessions onlyCo-authored-by: Codex <noreply@openai.com>Generated with [Codex](https://openai.com/codex/).<git_attribution>system-prompt sectionCo-authored-by: Copilot <copilot@github.com>git.addAICoAuthor(defaultall)Co-authored-by: aider ({model_name}) <aider@aider.chat>— off by defaultattribute_co_authored_bydefaultsFalse; rewrites git author/committer insteadAssisted-by: LLM [TOOL1] [TOOL2]Documentation/process/coding-assistants.rstAssisted-by: <name of code assistant>off by default; by default it rewrites git author/committer identity instead. So the
Aider signal lands in chalk's existing
AUTHOR/COMMITTERkeys(
base_keyspecs.c4m:772/:809), notCOMMIT_MESSAGE. Any implementation must check both.[VERIFIED] Claude Code trailer construction, deobfuscated from the bundle:
[VERIFIED] Codex is instructed, not coded:
"Commit messages must end withCo-authored-by: Codex noreply@openai.com. Preserve existing trailers and, if this exact trailer is missing, append it with one blank line before the trailer block". Compliance-dependent → less reliable than Claude's.
Reliability caveats that must shape the regex:
Co-Authored-By:×195,Co-authored-by:×28. Match case-insensitively.Claude Sonnet 4.6×166,Claude Opus 4.8×22,Claude Opus 4.7 (1M context)×7.Co-Authored-By: Claude Codewhen the active model isn't a recognized Claude model (e.g.third-party models behind a custom
ANTHROPIC_BASE_URL)." → bareClaude Codeis alegitimate value.
https://claude.ai/code, newerhttps://claude.com/claude-code.Match both.
includeCoAuthoredByis deprecated in favour ofattribution.Suggested trailer regex (superset, covers kernel/Fedora conventions too):
2.4 Env vars — cross-vendor detection matrix
[VERIFIED] Measured inside a live Claude Code session:
[VERIFIED]
AI_AGENToriginates in the Claude Code binary (7 occurrences), not the user'sshell or
~/.claude/settings*.json(both checked). Construction:AI_AGENTis a de facto convention with no spec.detect-agent, not a standards body. The onlystandardization attempt,
agentsmd/agents.mdissue Mynameismeerkat/key backup howto #136 (opened 2026-01-08, still open),proposes
AGENT, notAI_AGENT. Goose and Amp implementAGENT.openai/codex#13416closed2026-04-03 ("hasn't received enough upvotes").
AI_AGENT; the docs bug(
anthropics/claude-code#53071) auto-closed unresolved 2026-08-13. Value format is notcontractually stable.
ghtelemetry attribution, not provenance.[VERIFIED]
cli/cliinternal/agents/detect.go— authoritative cross-vendor ordering,usable directly as chalk's detection matrix.
AI_AGENTis checked first, validated with^[a-zA-Z0-9_-]+$:Suppression flags to document as known blind spots:
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1,CLAUDE_CODE_SUPPRESS_SESSION_ATTRIBUTION,CLAUDE_CODE_ATTRIBUTION_HEADER=0(all three [VERIFIED] present in the 2.1.220 binary).2.5 Cryptographic agent identity — where the industry is heading
[VERIFIED] Codex 0.153.2 binary contains:
Public keys at a JWKS endpoint with a registration/bootstrap lifecycle → third-party-verifiable
signed agent claims. Categorically stronger than trailers or heuristics. Public documentation
for it: NOT FOUND as of research date.
Also [VERIFIED] in the Codex binary:
pdf_c2pa_create_request,pdf_c2pa_reservation—OpenAI applies C2PA to PDF uploads. Not code.
2.6 Prior steganography incident — relevant context
[VERIFIED via multiple independent sources] Claude Code v2.1.196 rewrote its own
system prompt steganographically: apostrophe in
Today's→ U+2019 / U+02BC / U+02B9, anddate separator
-→/. Triggered byANTHROPIC_BASE_URLset, plus timezoneAsia/Shanghai/Asia/Urumqior hostname matches against base64+XOR(key=91)-obfuscated lists.Anthropic confirmed it as an anti-distillation / unauthorized-reseller experiment and removed it
in 2.1.197 (2026-07-01). HN discussion id 48734373 (2,445 pts).
https://thereallo.dev/blog/claude-code-prompt-steganography
Scope: outbound requests, not artifacts on disk. Does not change artifact-side conclusions.
But it means "the vendor wouldn't embed hidden marks" is not a sound argument, and the removal
(not policy) explains a clean 2.1.220.
3. Detection accuracy — why heuristics are not evidence-grade
[SECONDARY] CodeMirage (Purdue, DL4C'25), across GLTR / Entropy / DetectGPT / GPTSniffer /
CodeXEmbed+RF / RAIDAR / BiScope:
Others: arXiv 2412.14611 — 84.1% ± 3.8% (10 languages, 121k snippets). SemEval-2026 Task 13
stylometric — macro-F1 67.35. Prose stylometry reaches ~97% but does not transfer to code.
[VERIFIED, this repo] Unicode heuristics produce real false positives on chalk itself:
src/configs/base_keyspecs.c4mhas 11U+00A0hits — copy-pasted AWS documentation, not AI.U+00A0is categoryZs, notCf, so a category-based check correctly ignores it while aloose "non-ASCII" check misfires.
[SECONDARY] Independent empirical disproof of Claude Unicode watermarking: 1,206 sessions,
7.2M prose characters audited pre/post-announcement — "no anomalous instances". Green/red-list
tests negative (p=0.677, p=0.556 Sonnet 5; p=0.886 Fable 5).
https://johnjwang.com/post/2026/08/12/how-claude-watermarking-probably-works/
[SECONDARY] The U+202F "ChatGPT watermark" (Rumi, Apr 2025) was debunked — OpenAI said
"not a watermark… a quirk of large-scale reinforcement learning"; Rumi retested and the
characters were gone.
Conclusion: statistical/stylistic AI detection is not evidence-grade for chalk. Trailers,
env vars, and signed attestations are.
4. Chalk integration — where the code is
4.1 The trailer is already collected [VERIFIED end-to-end]
src/utils/git/chalk_git.c:1143—git_commit_message(commit)src/utils/git/chalk_git.c:190-203—trim_cstrsrc/utils/git/chalk_git.h:9—char *commit_message;src/utils/git.nim:49,src/utils/git.nim:153src/plugins/vctlGit.nim:158src/configs/base_keyspecs.c4m:846(COMMIT_MESSAGE),:1064(_COMMIT_MESSAGE)src/configs/base_plugins.c4m:127,:136git_commit_message()returns the full message — libgit2 hasgit_commit_summary()forsubject-only and chalk deliberately does not use it. Only transform is whitespace trim: no
truncation, no trailer stripping. Contrast: tag messages are signature-stripped
(
chalk_git.c:297-311trim_tag_message()), which shows the omission for commits is intent.COMMIT_MESSAGEisuse = truein all 4 major mark templates(
base_chalk_templates.c4m:66,183,299,388) and 6 report templates(
base_report_templates.c4m:69,765,1329,1878,2333,2437).→
Co-Authored-By: Claude …ships in chalk marks and reports in production today.Two limits:
gitCollect()reads one commit; no history walk. Per-repo AI density overhistory is out of scope without new libgit2 work.
AUTHOR/COMMITTERcome from the git identity (chalk_git.c:1130-1139), not trailers.The AI co-author signal exists only inside
COMMIT_MESSAGE.4.2 No existing AI-authorship key [VERIFIED]
All 534 keyspecs enumerated; zero hits for AI/LLM/Claude/Copilot/agent/
generated_by.Best existing homes:
INJECTOR_ENV(:365),COMMIT_MESSAGE(:846),INJECTOR_ARGV(:350),BUILD_TRIGGER(:1601),CODE_OWNERS(:1253),SAST(:2102).4.3
INJECTOR_ENVdrops agent vars today — and a real doc bug [VERIFIED]env_default_actiondefault is"ignore"(src/configs/chalk.c42spec:4358-4366), butsrc/configs/base_keyspecs.c4m:389says "This defaults toredact". Andignoremeansdropped, not masked —
src/plugins/system.nim:196-204:Default
env_always_show=["PATH","PWD","XDG_SESSION_TYPE","USER","SSH_TTY"](
chalk.c42spec:4333). Every agent env var is absent today, not redacted.Worth fixing upstream independently: the
env_default_actiondoc atbase_keyspecs.c4m:389and:5581.4.4 Config-only extension path [VERIFIED]
The
conffileplugin (src/plugins/conffile.nim:18-49) evaluateskeyspec … callback:,enabling new keys with no Nim and no recompile. Two in-tree precedents:
configs/co/build_observables_key.c4m(_X_BUILD_OBSERVABLES) andconfigs/co/curiosity_logs_key.c4m(_X_CURIOSITY_LOGS).con4m builtins available in callbacks:
read_file,is_file,find_exe,env,run,system,parse_json,parse_jsonl,to_json,strip,split,starts_with,memoize,command_name,binary_sha256, plus chalk-specific ones (src/con4mfuncs.nim:255-383).Gotcha:
usedefaultstrueonly once akey.<NAME>subsection exists.registerKeys()(src/collect.nim:69-76) iterates existing subsections only, andhasSubscribedKey()(:20-29) then skips the whole plugin. Declaring a keyspec withouttouching a template is a silent no-op.
4.5 Chalk does not verify signatures — by documented design [VERIFIED]
docs/design-caller-attestation.md:258-261::358-359: "The trust model is process-spawning, not cryptographic. Signed attestations areout of scope."
Confirmed in code:
src/plugins/callerAttestation.nimreadsCHALK_CALLER_ATTESTATION(env orfile), parses JSON, checks a protocol version, warns on unknown top-level keys.
isHex64validates artifact-hash keys, not signatures. Zero JWT/JWKS/crypto verification.
→ Do not propose chalk verify Codex JWKS agent identity. Chalk should carry the claim;
a downstream verifier checks it.
callerAttestation.nim:117-118already passes through anyX--prefixed top-level key, so a caller can injectX-AI-Agenttoday, with zero chalkchanges.
4.6 Other relevant extension points
toolsections are the only user-instantiable object type (chalk.c42spec:446user_def_ok: true). Driven bysrc/plugins/externalTool.nim. Precedents:sastconfig.c4m(semgrep),sbomconfig.c4m(syft),secretscannerconfig.c4m(trufflehog).toolkindhas no off-switch.externalTool.nim:153-155hardcodes gates for
sbom/sast/secret_scanneronly; an unrecognized kind matches nobranch and runs unconditionally. Declare AI-fingerprint tools as
kind: "sast"to inheritthe
run_sast_toolsgate, theSASTkey, andcanonicalize_tools. Tools only run onbuild/insert(externalTool.nim:146).src/plugins/codecSource.nim:283(
stream.readAll()), with detected language + extension — near-zero marginal I/O for acontent scanner. Emit via
sourceGetChalkTimeArtifactInfo():377-382.chalk.c42spec:3349-3358discourages marking source inside a repository ("Git doesthat job well"). Embedding provenance into in-repo source cuts against documented intent;
metadata keys are grain-aligned.
doc:/shortdoc:fields, surfaced by
chalk help key <name>andchalk docgen.5. Recommendation
Ranked by effort. A + B cover the practical ask with no Nim, no recompile, no upstream PR.
~env_always_showinconfigs/co/env_vars.c4mCLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1_X_AI_AUTHORSHIPderived key: con4m callback parsing trailers out of data chalk already has.c4mattribution.*X-AI-Agent/ agent-identity JWT into the attestation envelopetoolkind:"sast"vctlGit.nim(packGitInfo():153-187)doc:inchalk helpA, concretely.
configs/co/env_vars.c4mis a 12-line~env_always_show = [...]overlay.Add, ordered per the
ghmatrix (§2.4):runtime dependency and silently changed output format on
AI_AGENT; serious backlash onconsent/least-privilege grounds, walked back. Reading these vars is uncontroversial;
changing chalk behavior based on them would not be. Report only.
Do not build
the generation key.
false-positives on chalk's own source.
6. Separate, better-founded opportunity: hidden-channel detection
Not AI attribution — supply-chain integrity, squarely chalk's existing mission
(Trojan Source, CVE-2021-42574). There is a production-grade, adversarially-reviewed reference
implementation available: Anthropic's own, [VERIFIED] extracted from the 2.1.220 bundle
(
FORBIDDEN_ANSWER_CHAR_RE/MAX_EXEMPT_INVISIBLE,src/frame/decisionBlocks.ts):Design properties worth copying, per their own comments:
\p{Cf},\p{Default_Ignorable_Code_Point}), not anenumerated codepoint list — covers "whatever the next Unicode version mints". Enumerated
blacklists rot.
byte-per-codepoint channel".
Cf).invisible to humans but legible to models."
Nim's PCRE backend supports
\p{Cf}in UTF mode → ports near-directly. FitscodecSource.nim(contents already in memory) or a
tool kind:"sast".Prior art to study: untrace (Go; decodes payloads, context-aware per filetype, git clean
filter), boundaryguard (CI-shaped, fail-closed exit 0/1/2, SARIF output),
guillaumemeyer/watermarks-remover(widest codepoint list incl. U+E0000 block, noncharacters,musical/format controls).
7. Policy landscape — why this matters commercially
Trailer-mandating (chalk could verify compliance, a sellable capability):
the significant part of the contribution is taken from a tool without changes." Recommended
mechanism:
Assisted-by: <name of code assistant>.Documentation/process/coding-assistants.rst): trailerAssisted-by: LLM [TOOL1] [TOOL2]. And: "AI agents MUST NOT add Signed-off-by tags.Only humans can legally certify the Developer Certificate of Origin (DCO)."
Assisted-by: AGENT_NAME:MODEL_VERSIONinstead.Diff the kernel tree before writing a parser.
Bans (chalk could detect violations):
include or derive from AI generated content."
been created with the assistance of Natural Language Processing artificial intelligence tools."
without prior written approval by core."
Permissive: Debian GR vote_002 (Aug 2026) — "Responsible use of generative AI" won ~64/36,
425/1045 DDs voting. LLVM allows but treats unreviewed AI submissions as "extractive".
Regulatory: EU AI Act Art. 50(2) — synthetic text must be "marked in a machine-readable
format and detectable as artificially generated", marks "effective, reliable, robust and
interoperable". Live 2026-08-02. Carve-out for systems performing "an assistive function
for standard editing" plausibly covers much of agentic code editing. Art. 50(4) does not
apply to code (not "published to inform the public on matters of public interest").
NOT FOUND: any Anthropic statement addressing code generation under Art. 50 specifically.
Copyright pressure against
Co-Authored-By:: U.S. Copyright Office, 88 Fed. Reg. 16190(2023-03-16), 37 CFR Part 202 §IV.A — "Applicants should not list an AI technology or the
company that provided it as an author or co-author simply because they used it." This is the
strongest argument that
Assisted-by:is the correct trailer andCo-Authored-By:is not.[SECONDARY] SLSA 1.2 covers build/source provenance but explicitly not AI authorship.
That gap is unclaimed and sits directly adjacent to chalk.
8. Prior art on line-level AI provenance
attribution in Git Notes linked to agent/model/session; migrates attributions through
squash/merge/reset/rebase/stash/cherry-pick. ~2k stars, Thoughtworks Radar Assess.
git commit, exits 2 ifAssisted-by:missing; rejectsCo-Authored-By: Claudeand AISigned-off-by:.Assisted-by:≤33% generated /Co-authored-by:35–67% /Generated-by:67%+, each paired with a humanSigned-off-by.Git Notes is the interesting divergence from chalk's model: it survives history rewrites and
carries line granularity, but it is not embedded in the artifact. Chalk marks the artifact.
The two are complementary, not competing.
9. Trailer prevalence — order-of-magnitude only
[CLAIMED — GitHub commit search is token-based and approximate, public repos only]
total_count"Co-Authored-By: Claude""noreply@anthropic.com""Generated with Claude Code""Assisted-by:""includeCoAuthoredBy"+false"Co-authored-by: Copilot"The 22.8M
noreply@anthropic.comfigure exceeding the 9.2M"Co-Authored-By: Claude"figure ismost likely a tokenization artifact of matching the bare email, not evidence of 13M commits
carrying the address without the trailer. Do not cite it as a superset.
Design consequence — the policy-endorsed trailer has ~2% of the vendor default's volume
(197,524 vs 9,194,319).
Assisted-by:is real but nowhere near displacingCo-Authored-By:.A chalk implementation must read both trailer families, and must tolerate at least three
Assisted-by:value shapes (§7 unresolved item).Stripping is widespread and well-tooled (
anthropics/claude-code#617, 22 comments, circulatesa global
core.hooksPath+commit-msgrecipe;#45137gives a one-linesed). Motivationis often explicitly framed as avoiding a usage-telemetry trail.
10. Open items
Items 1–3 below were resolved after the first draft; see §10.1. Remaining gaps follow.
403 on
api.reddit.com/oauth.reddit.com, 403 on redlib mirrors). Community signal camefrom GitHub issues, HN, and blogs instead.
COMMIT_MESSAGEoutput empirically — thein-repo
chalkbinary is Linux/aarch64 (2024-06-11) and won't execute on darwin/arm64.The code path is unambiguous, but an end-to-end run in Docker would close the loop.
10.1 Resolved after first draft
Aider [PRIMARY,
Aider-AI/aider/aider/repo.py] — trailer isCo-authored-by: aider ({model_name}) <aider@aider.chat>, i.e. the model name is embedded,same as Claude Code. Commit-message prefix
"aider: ". Flags and defaults:attribute_authorNone(treated as True)attribute_committerNone(treated as True)attribute_commit_message_authorFalseattribute_commit_message_committerFalseattribute_co_authored_byFalseidentity by default. So for Aider the signal lands in
AUTHOR/COMMITTER(
base_keyspecs.c4m:772/:809), notCOMMIT_MESSAGE. A trailer-only parser misses Aiderentirely. This is the one case where chalk's existing
AUTHOR/COMMITTERkeys carry the AIsignal.
GitHub Copilot [SECONDARY] —
Co-authored-by: Copilot <copilot@github.com>. Copilot codingagent co-authors all commits for traceability. Separately, VS Code's Git extension setting
git.addAICoAuthordefaults toall, adding the co-author line whenever Copilot features touchthe code — so this trailer appears from the IDE, not just the cloud agent.
https://docs.github.com/en/copilot/concepts/coding-agent/about-copilot-coding-agent,
https://github.com/orgs/community/discussions/179983
Linux kernel
Assisted-by:— discrepancy RESOLVED [PRIMARY,https://docs.kernel.org/process/coding-assistants.html] — canonical format is
Assisted-by: LLM [TOOL1] [TOOL2], where the optional tools are specialized analysistools (coccinelle, sparse, smatch, clang-tidy). Basic tooling (git, gcc, make, editors) must not
be listed. The third-party
Assisted-by: AGENT_NAME:MODEL_VERSIONshape reported in §7 isnot the kernel format — do not implement it as such. Confirmed:
"AI agents MUST NOT add Signed-off-by tags. Only humans can legally certify the Developer
Certificate of Origin (DCO)."
Co-developed-byis not discussed in the current doc.SBOM standards — decisive negative [SECONDARY] — neither SPDX 3.0 nor CycloneDX has a
field for recording that an AI agent authored code. SPDX 3.0's AI Profile and CycloneDX 1.7's
ML-BOM describe AI models and datasets as SBOM components (training environment, energy
consumption, performance metrics, safety risk classification, intended use) — an entirely
different problem. SPDX 3.0's new
Agentclass (replacing 2.3Creator/Supplier, coveringPerson / Organization / software tool) is the closest structural fit, and CISA's crosswalk
maps "SBOM Author Name" → CycloneDX
metadata.authors, but neither is specified forAI-authorship-of-code.
Combined with SLSA 1.2 explicitly not covering AI authorship (§7), the conclusion is:
no SBOM or provenance standard currently carries "an AI agent authored this code." The gap
is real, unclaimed, and directly adjacent to chalk's existing metadata-key model. Chalk's own
X-/_X-user-key namespace is available to define it without waiting on a standards body.🤖 Generated with Claude Code