On 9 June 2026 somebody opened issue #66504 against Anthropic’s claude-code repository with what reads, at first glance, like a style complaint. Claude Code was appending a session URL to every commit message and pull request description it produced. No prompt, no onboarding mention, no warning. Users found out when they read their own git log.
The issue gathered 21 comments over eleven weeks, was closed by a maintainer on 17 August with a pointer to the setting that disables it, and is still collecting replies. It reached the front page of Hacker News this week. Read past the irritation, because underneath sits a delivery problem that has little to do with Anthropic and will outlive this particular default: your version control history is a publishing surface, it is permanent in practice, and your AI toolchain now has write access to it with defaults chosen by a vendor.
TL;DR
- Claude Code appends a session URL of the form
claude.ai/code/session_...to commit messages and PR descriptions in web and Remote Control sessions by default. The documented off switch is{"attribution": {"sessionUrl": false}}. - The link is the small problem. The real one is that the off switch lives in a per-repo config file the surface generating the link cannot conveniently reach, so the default reasserts itself on every new repository.
- Telling the agent to stop did not work for the people who tried it, because the instruction appears to be re-injected on each commit. A prompt is not a control.
- Git history is append-only in practice and gets handed to the client at project close, so whatever your tooling stamps into it becomes a disclosure nobody reviewed.
- Enforce trailer policy where the artefact arrives, with a required CI check or a
pre-receivehook. Client-sidecommit-msghooks are not installed in the cloud containers where this actually happens.
What the thread actually establishes
Strip out the outrage and the facts are narrow. The maintainer’s closing comment states the link is added only in web and Remote Control sessions, and that attribution.sessionUrl: false removes it while keeping the Co-Authored-By trailer. Before that setting was documented, the community was passing round an undocumented environment variable found by reading the harness, and reporting that the more obvious attribution.commit: "" did not suppress the link on its own.
Two follow-up comments do more damage to the “only in remote sessions” reassurance than any of the complaints. Users on recent versions report Remote Control active in effectively every session they start, so the narrowing clause has quietly stopped narrowing much. And a commenter requesting the issue be reopened made the point that matters most: the trailer is added in exactly the sessions with no shell in which to edit ~/.claude/settings.json, and web sessions start in a fresh container, so a home-directory preference does not persist. The setting is account-level in nature and per-project in storage.
On the question everyone jumped to, be precise. Nobody demonstrated that a third party can open one of those links, and the sensible reading is that it resolves only for the owning account. That is a reassurance about a vendor’s current access-control policy, not a property of the URL you published, and only one of those is under your control.
The off switch is in the wrong building
This is the transferable lesson, and it generalises past one tool. A configuration file committed to a repository is not a policy. It is a policy applied once, to one repository, by whoever remembered. Every new repo starts from the vendor’s default, and defaults win by attrition: they need only be forgotten once, and nobody notices, because the artefact carrying the consequence is a commit message no reviewer reads to the bottom.
It is the same failure that leaves Dependabot configured on half your repositories. If a setting must be present everywhere, the only mechanisms that hold are the ones running without human memory: a repository template that emits the file at creation time, an organisation-level baseline, and a check that fails when it is missing. A note in the onboarding wiki is not a mechanism.
A prompt is not a control
The most instructive complaint comes from a user who asked Claude not to add the link, repeatedly, across many sessions, and watched it return every time. The explanation is mundane: the attribution instruction is re-injected around each commit, so an earlier conversational request is outranked.
Take the general form, because it applies to every agent you deploy. In-conversation instructions are advisory: they compete with system-level instructions you did not write, and they decay over long sessions. Anything you would be embarrassed to explain to a client has to be enforced at a boundary the agent cannot talk its way past.
The original reporter half-solved this: a commit-msg hook can strip the trailer, but as they noted, it “doesn’t always fire reliably in remote/cloud environments”. That is exactly right, and structural. Client-side hooks live in .git/hooks, are not cloned, and a fresh cloud container has never run your setup script. The enforcement point that works is the one every commit must pass regardless of where it was authored: a required status check on the pull request, or a pre-receive hook if you run your own forge. Server-side, or it does not count.
What is actually exposed
Be unsentimental about the risk, because overstating it is how these conversations get dismissed. The session link is an identifier, not an open transcript. You are publishing four things.
- Method. Every commit declares which vendor’s agent wrote the code and, in aggregate, how much of the codebase it touched. Under an NDA, or a contract with an AI usage clause, that is a contractual fact disclosed without a review step.
- Correlatable structure. A stable per-session identifier partitions your history into work sessions: who was working, when, for how long, and which repositories were touched together. Metadata channels are queryable at scale across public forges.
- Durability. A policy change applies from today. The back catalogue is a separate and more expensive decision.
- Someone else’s terms. The link’s reachability is governed by a vendor’s product decisions for as long as the URL exists, which is longer than the tool, the contract, or possibly the vendor.
The handover question nobody asks until due diligence
When a project closes, the repository goes to the client and the metadata goes with it. We have written before about what a proper handover includes, and the honest update is that commit history is now a disclosure document as well as a technical asset.
If a client’s contract restricts third-party AI services, or their acquirer’s due diligence asks how the code was produced, the answer is already written into every commit in a form nobody agreed a wording for. The fix is not to hide it. It is to have the conversation before the first commit, agree the position in writing, and configure the toolchain to match. Fifteen minutes at kickoff, or an uncomfortable hour in a data room three years later.
In defence of the trailer
The unpopular side, because the thread is short on it: labelling machine-authored code is defensible and probably inevitable, provenance obligations are tightening across EU software regulation, and we keep the Co-Authored-By trailer on our own work deliberately. The objection is not to labelling. It is that a label carrying a unique, resolvable, per-session identifier is not a label, it is an identity, which is precisely the distinction we drew about invisible watermarks in image pipelines earlier this month. Same thesis, different pipeline. Keep the trailer. Drop the link.
What to do this week
- Get the number before you form an opinion. Run
git log --all --grep='claude.ai/code/session' --oneline | wc -lacross active repositories, andgh pr list --state all --limit 1000 --json body --jq '[.[]|select(.body|test("session_"))]|length'for pull request bodies. The answer is usually near zero or considerably worse than expected, and both change what you do next. - Set the policy where new repositories inherit it. The config file belongs in your repository template and scaffolding tool, not a runbook. Anything depending on somebody remembering stays right for about a quarter.
- Enforce it server-side. A required CI check that fails a pull request containing disallowed trailers, or a
pre-receivehook. Client-side hooks and polite requests to the model both fail in cloud sessions, which is where the behaviour occurs. - Decide the back catalogue on purpose. For most teams, rewriting shared history costs more than the exposure justifies. That is a legitimate answer, provided it is written down as a decision with a reason rather than rediscovered as a surprise by whoever runs the next audit.
- Move AI attribution into the contract and the handover checklist. One clause covering permitted tooling, what appears in delivered artefacts and who decides, agreed at kickoff and verified at delivery.
- Audit the rest of the pipeline for the same class of default. Commit trailers are the visible instance. Generated code comments, PR templates, image provenance manifests and telemetry in shipped bundles follow the same pattern: a vendor default writing into an artefact you hand to somebody else.
The general case
Defaults are decisions made on your client’s behalf by somebody who has never met them. That was tolerable when tooling wrote to build directories. It is a different proposition now that it writes to the permanent record. The question for your next architecture review is not whether this particular trailer bothers you, but what your toolchain stamps onto the things you hand over, and whether anyone decided that.
REPTILEHAUS builds and operates delivery pipelines for teams who would rather answer that question before a client does. If you want your AI tooling governed at the boundary rather than by convention, get in touch.
📷 Photo by MIKE STOLL on Unsplash
