Development record
A Project Declares Once How It Wants AI Acknowledged — And Every Commit, PR, And Record Follows
Press Release
abcd asks how you want AI credited, then makes every artefact obey. When you set up a project, abcd now asks a single question — how should AI assistance be acknowledged? — and offers the honest options: not at all, a kernel-style
Assisted-by:trailer, aCo-Authored-By:line, aGenerated-bynote, or your own wording. Your answer is recorded once, in the repo, and from then on every commit trailer, pull-request body, and generated record uses exactly that convention. No more a policy that lives only in a contributor's memory and drifts PR by PR; no more a tool stamping its own name where a project never asked it to.
"We'd written the rule down in CONTRIBUTING, and it still drifted — half our PRs said one thing, half said another, and one tool kept adding its own footer we never agreed to," said Carol, a tech lead standardising a team's repos. "Now it's a setup question. I pick kernel-style once, and everything downstream is consistent. When a teammate preferred no attribution at all on their fork, they picked that, and abcd just honoured it. The convention stopped being folklore."
Why This Matters
abcd already has an opinion about AI attribution — Assisted-by: Claude:<model>, the kernel format, as disclosure not authorship, never Co-Authored-By: (which asserts an authorship the tool does not hold and inflates the contributor graph). That opinion is written in CONTRIBUTING.md and this repo's own CLAUDE.md, and it is right for this project. But it lives as prose a human has to remember and apply by hand, and this session proved the cost: PR bodies drifted to a tool's default "Generated with" footer, and a sweep of 78 pull requests was needed to reconcile them — some carrying a model, some none, one carrying the wrong model entirely.
Two problems compound. First, the convention is unenforced: nothing at commit or PR time checks that the acknowledgement matches what the project decided, so it degrades with every contributor and every tool that has its own idea. Second, the convention is not portable: a project adopting abcd inherits abcd's preference by reading its docs, but has no first-class way to declare its own — a team that wants Co-Authored-By:, or wants no attribution at all, or wants a house style, has to fork the prose.
An onboarding step (/abcd:init or prepare-this-repo) is the right moment to resolve both. Setup is already where a project's conventions are established; adding "how do you want AI acknowledged?" makes the choice explicit, records it as durable per-repo config, and lets the rest of abcd — commit-trailer guidance, PR-body composition, record generation, and any attribution lint — read that one source of truth instead of assuming a default. The project decides once; the tooling obeys everywhere.
What's In Scope
- A setup question in the onboarding surface (
/abcd:init/prepare-this-repo) offering a selection of acknowledgement conventions: none, kernel-styleAssisted-by:(the current abcd default),Co-Authored-By:,Generated-by, and a custom free-form template. - Durable per-repo config capturing the choice (and, for the trailer styles, whether a model identifier is included), stored in the repo so it travels with it and is not a contributor's memory.
- A single read seam the rest of abcd consults when it composes a commit trailer, a PR body, or a generated record — so the recorded preference is actually applied, not merely stored.
- An honest default and honest framing. The default remains the disclosure-not-authorship position (kernel
Assisted-by:), and theCo-Authored-By:option carries the caveat that it asserts authorship — the selector informs the choice, it does not hide the trade-off.
What's Out of Scope
- Rewriting history. This governs artefacts produced after the choice is made; reconciling a repo's existing commits/PRs to a new convention is a separate, deliberate migration (this session did the PR-body form of it by hand), not something setup performs.
- A commit/PR-time enforcement lint. Checking that a produced trailer matches the recorded preference is a natural follow-up (an attribution rule in the record-lint family), but this intent is the declaration and application seam; the gate can build on it later.
- Deciding abcd's own house policy. abcd keeps its
Assisted-by:stance for its own repo (CONTRIBUTING.md); this intent gives adopting projects a way to choose theirs, it does not relitigate abcd's. - Attribution beyond AI. Human
Signed-off-by:(DCO) and theACKNOWLEDGEMENTS.mdcredit ledger are their own conventions; this intent is scoped to how AI assistance is acknowledged.
Acceptance Criteria
Given-When-Then per the itd-1 discipline.
- Given a project running the onboarding surface, when the attribution question is presented, then it offers at least {none, kernel
Assisted-by:,Co-Authored-By:,Generated-by, custom} and records the chosen convention as durable per-repo config. - Given a recorded preference of "none", when abcd composes a commit trailer or PR body, then it adds no AI-attribution line at all.
- Given a recorded preference of kernel
Assisted-by:with a model identifier, when abcd composes an artefact, then the artefact carries exactlyAssisted-by: Claude:<model>and noCo-Authored-By:or "Generated-by" line. - Given a recorded
Co-Authored-By:preference, when it is selected, then the selector surfaces the caveat that it asserts an authorship the tool does not hold — the trade-off is disclosed, not buried. - Given no recorded preference (a repo predating this feature), when abcd composes an artefact, then it falls back to the documented default (kernel
Assisted-by:) rather than a tool's own footer.
SOTA
Surveyed on 2026-10-23; sources, evidence tiers and the local fit risks are in the sources-provenance SOTA note. The repository's ATTRIBUTION rules settle abcd's own policy; this surveys only the configurable-preference gap.
- The field has forked three ways and all three are current. Disclosure trailer: the Linux kernel's document at 7.2 reads
Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2](exampleAssisted-by: Claude:claude-3-opus coccinelle sparse); the current document (7.3) readsAssisted-by: LLM [TOOL1] [TOOL2]and drops the model; Rocky Linux makes disclosure MUST for unchanged tool output and SHOULD otherwise, withAssisted-by:as the recommended method; LLVM asks contributors to label substantial tool-generated content and givesAssisted-by:as its example trailer, with no MUST/SHOULD split. Co-authorship: Claude Code's default isCo-Authored-By: <model> <noreply@anthropic.com>, VS Code'sgit.addAICoAuthorwent fromoff(1.110) to on by default for chat and agent workflows (1.118), and GitHub's cloud agent makes Copilot the author with the human as co-author. Prohibition: Gentoo (council vote 14 April 2024), QEMU (DCO grounds, exceptions by list approval), NetBSD (presumed tainted, core approval), and git's SubmittingPatches (no trailer; rejects what "looks AI generated"). - Hosts already expose the preference as configuration. Claude Code's
attributionkey takescommit(string, empty hides),pr(string, empty hides) andsessionUrl(Boolean; aClaude-Sessiontrailer), orfalse, settable in any file including the committed project settings file;includeCoAuthoredByis deprecated since v2.0.62. User and local settings sit above the committed file, so a committed preference is a default, not an enforcement;sessionUrlapplies only to cloud and Remote Control sessions; and the host tells the model that a CLAUDE.md or memory rule about attribution takes precedence over these commit and PR lines unless they are managed settings, so abcd's own instruction-file rule is itself one of the compile targets (Claude Code settings reference). - git has the application machinery:
trailer.<alias>.key,ifExists(replace,doNothing, defaultaddIfDifferentNeighbor),ifMissing,trailer.<alias>.cmd, and the manual's owncommit-msghook runninggit interpret-trailersover the message file, which is the one place a human's owngit commitis reached. - "None" is two stances. The draft's
nonecovers both "do not disclose" and "AI use is prohibited"; Gentoo, QEMU and NetBSD show the second is a policy of its own. - Where the research contradicts the record: the house rule names "kernel format" with a
Vendor:modelvalue, and the kernel's current document has moved toLLMplus tools without the model. The ruling stands; the selector should name the two value forms separately rather than call either "kernel-style". - Path 1 for the surfaces, Path 2 for the record: one small structure in
.abcd/config.json(stanceofnone | disclose | coauthor | custom | prohibit,trailer_key,value_form,pr_text;Generated-byis adisclosepreset withtrailer_key: Generated-by, so the criterion's five offered options stay and the stance set is the stored form, not the menu), compiled outward in the same act to the host'sattribution.commit,attribution.prandattribution.sessionUrl: false, totrailer.*git config plus acommit-msghook that normalises whatever the host or human wrote into the declared form, and to the PR-body composer. The seam is the compiler: a new host adds one target. No Go dependency. The independent fit-challenge runs at plan time.
Open Questions
- (SOTA 2026-10-23) A project that picks
coauthorchooses to fail abcd's own attribution gate; does the selector disable that gate for the project, or state the conflict and keep the gate abcd-only? - (SOTA 2026-10-23) Writing
attributioninto the host's committed settings file is writing into a directory abcd does not own; is it a marked block with consent, as theAGENTS.mdconventions section is, or a printed instruction? - (SOTA 2026-10-23) Does
prohibitcompile to anything beyond the hook refusing a disclosure trailer, such as a refusal of a known tool footer in a PR body? - Where does the preference live? A dedicated key in an existing per-repo config (e.g.
.abcd/config/…) versus a new file; and whether it is one setting or a small structure (style + include-model + custom-template). - How is it applied to commits abcd does not author? abcd can compose its own PR bodies and records, but a human's
git commitis outside its control — is the mechanism a documented trailer the human/agent is told to use, a prepare-commit-msg hook, or guidance only? - One convention or per-artefact? A project might want
Assisted-by:on commits but nothing in PR bodies; whether the selector is a single global choice or per-artefact granularity is a design call (start single, likely). - Does the custom template need variables? A free-form template implies placeholders (
{model},{date}); how much templating to support before it becomes its own small language. - Relationship to a future enforcement lint. If an attribution record-lint rule follows, this config is its source of truth — the schema should be chosen with that consumer in mind even though the lint is out of scope here.
Frontmatter
| id | itd-91 |
|---|---|
| type | intent |
| lifecycle | drafts |
| severity | minor |
.abcd/development/intents/drafts/itd-91-ai-attribution-preference.md
open on GitHub ↗ · commit history ↗
Referenced by8
- iss-2610262031466884Context names `/abcd:ahoy install` as the install surface, but itd-91 puts its setup question in `/abcd:init` / `prepare-this-repo`.related
- iss-2610262033022683itd-91 adds a setup question that chooses an AI-acknowledgement convention; the ahoy page already has the install's attribution opt-in, a hook that asks each commit to declare assistance.related
- iss-2610262034182114itd-91 puts its setup question in `/abcd:init` / `prepare-this-repo`; the board chapter says the `prepare-this-repo` page retired into the install.related
- iss-2610262037372402itd-91 has every commit trailer follow the project's chosen AI-credit convention; the announce brief requires an announcement's Assisted-by to be abcd's own label and nothing elserelated
- iss-2610262039224536itd-91 puts its setup question in `/abcd:init` / `prepare-this-repo`, but the register says repository preparation moved into ahoy's install sectionrelated
- iss-2610262041065877The attribution draft puts its setup question in `/abcd:init` / `prepare-this-repo`; the build sequence says there is no `abcd init` and install is `abcd ahoy install`.related
- iss-2610262044429007The attribution-preference draft puts its setup question in `/abcd:init` / `prepare-this-repo`, surfaces the verb split retired or never hadrelated
- itd-131The managed-repo identity gate: the human is the author of record on every commit, before the first onerelated
mentions14
- dcn-26081700000000042026-08-17 — The attribution gate's list-container fence limit is ACCEPTED as a
- iss-85Managed attribution config: AI-disclosure attribution (prepare-commit-msg hook adding the kernel-style trailer, hooksPath wiring, AGENTS.md section) is installed by the interim prepare-this-repo skill from a private template directory. No intent covers the configuration layer owning attribution setup in managed repos; it should, so the per-repo attribution policy is declared and enforced by the tool rather than a hand-copied hook.
- iss-211Multi-project adoption raises the priority of itd-91 (AI-attribution preference) and itd-92 (branch-protection verification) from 'good hygiene' to 'the product claim'. What abcd-cli has today is its OWN answer hard-coded: scripts/check-attribution.sh names specific banned footers and a fixed required trailer, and .github/workflows/attribution.yml is a hand-written file in one repo. Neither is portable, which is exactly the gap itd-91 already states — a project adopting abcd inherits abcd's preference by reading its docs but has no first-class way to declare its own (Co-Authored-By, none at all, or house style). The durable home is a rule in internal/core/lint beside deliverystate, indexdrift and citations: reachable from CLI and plugin, run in any managed repo, reading a declared per-repo preference rather than a constant. Two further observations from the 2026-08-11 session. (1) SCAFFOLD IS THE DELIVERY MECHANISM. internal/core/launch/scaffold renders exactly three artefacts into a managed repo today (release.yml, auto-release.yml, the runbook); an attribution workflow becomes the fourth, so every managed repo inherits the gate from one template instead of someone copying a file. It would automatically gain the self-scaffold parity property — and with it the dependabot pin problem of iss-209, which the sync tool merged in PR #215 already handles. The work just landed is the delivery rail for making this portable. (2) ITD-92 GATES EVERYTHING ELSE. A scaffolded gate that no repo adds to its required status checks is decoration; across N repos the required-check wiring and the enforce_admins policy stop being settings a maintainer clicks and become policy abcd asserts and verifies. That makes itd-92 arguably the higher-leverage of the pair: it is what converts every abcd-scaffolded check, present and future, from advisory into binding. itd-92's own capture note already says this in miniature — 'captured 2026-07-17, the day abcd-cli's own main was protected by hand — work the tool should carry for every repo it manages'. Both intents are still ungrilled drafts.
- iss-215The attribution gate is provider-asymmetric: its POSITIVE check is vendor-agnostic while its NEGATIVE check and the prose it enforces are Claude-specific, so the gate stops the failure it was built for only as long as the assisting model is Claude. Verified 2026-08-11 against scripts/check-attribution.sh: TRAILER_RE accepts any '<Vendor>:<version>' pair, so 'Assisted-by: OpenAI:gpt-5' and 'Assisted-by: Google:gemini-3' both PASS — correct and desirable. But GENERATED_RE bans only 'Generated with [', the robot-emoji 'Generated with', and 'Co-authored-by: Claude' / 'Co-Authored-By: Claude', so a body carrying 'Co-authored-by: ChatGPT <bot@openai.com>' alongside a valid trailer PASSES. That is precisely the failure mode the workflow header says it exists to stop — itd-91 records a reconciliation sweep across 78 pull requests after PR bodies picked up a tool's default footer — merely wearing a different vendor's name. The AI-co-authorship objection AGENTS.md:132 states is about authorship the tool does not hold and contributor-graph inflation, neither of which is Claude-specific. Second half of the same asymmetry: the documented convention hardcodes one vendor in the template — CONTRIBUTING.md:31 writes 'Assisted-by: Claude:<model-version>' and AGENTS.md:132 gives 'Assisted-by: Claude:claude-opus-4-8' — so prose names a vendor the gate does not require, leaving a contributor using another provider without a stated correct form even though the gate would accept one. Fix direction is itd-91's, whose scope is a per-repo declared attribution preference every surface reads; .github/workflows/attribution.yml calls itself a stopgap until that lands, and iss-211 already raises itd-91's priority on multi-project adoption. Two things this record asks of that work specifically: make the co-authorship ban match on the TRAILER KEY rather than on a vendor name, so 'Co-authored-by:' naming any AI is refused; and state the convention as '<Vendor>:<model-version>' with Claude as an example rather than as the literal.
- iss-270The attribution gate's fence handling reads a fence's indent in ABSOLUTE columns, but CommonMark measures the three-space opener limit relative to the enclosing container. That diverges in BOTH directions inside a list item, and the dangerous direction is the one this record originally stated backwards.
- iss-2608210738363966The attribution gate (scripts/check-attribution.sh) is CI-only: no local hook mirrors it, so a commit whose git AUTHOR/COMMITTER is an AI identity (Claude <noreply@anthropic.com>) is only caught in CI, where it presents as an unmergeable-looking PR (a failing required check), not a merge conflict. The pre-commit hook runs only the name-guard; make preflight / the pre-push hook run record-lint + docs-lint + reviews-charter but NOT check-attribution. This cost a full diagnosis on #391 (AI-authored cloud-routine commits) and a reauthor+new-branch repair (#402), because force-push to fix in place is refused by policy. Fix: mirror check-attribution into the pre-push gate (as make preflight already mirrors record-lint), so an AI author identity or a forbidden Generated-by/Co-Authored-By footer fails locally before the round-trip. See memory cloud-routine-git-identity; relates itd-91.
- iss-2608210738367948New-repo / ahoy setup does not establish the git identity autonomous routines commit under. ahoy DETECTS a mismatch between the working git user.name/user.email and the committed identity pin (.abcd/config/identity.json, iss-62) but never SETS the identity, and nothing configures the human identity for an autonomous cloud routine's environment — so a routine defaults to Claude <noreply@anthropic.com> and every commit it makes fails the attribution gate (see attribution-gate-has-no-local-mirror). The ahoy/onboarding gap for a repo that will run routines: scaffold or verify the routine-environment git identity (git config user.name/email, or GIT_AUTHOR_*/GIT_COMMITTER_* env) so routine commits are authored by the human of record from the start. Bridges iss-62 (identity pin), itd-91 (declared AI-attribution preference), and the cloud-routine-git-identity memory. Candidate ahoy-install sub-step or a new-repo setup check.
- iss-2608270539033662abcd should propagate its convention DEFAULTS to the repos it manages, not only enforce them in its own repo. The AI-attribution footer (the kernel 'Assisted-by: Claude:<model>' trailer prescribed in AGENTS.md and enforced by .github/workflows/attribution.yml + scripts/check-attribution.sh) is the motivating example: ahoy install / prepare-this-repo do not currently write the attribution convention or its CI gate into a managed repo (a grep of internal/core/ahoy and internal/core/repolint for 'Assisted-by' is empty). The same holds for other defaults abcd owns (the rules-loader domains, the commit gates). Narrower existing records: iss-193 (attribution-identity enforcement belongs in abcd for every managed repo) and itd-91 (ai-attribution-preference, draft intent) cover the attribution slice specifically; this record is the general defaults-propagation capability those are instances of — candidate for promotion to an intent.
- iss-2608270550201935Ship an advisory-dedup echo into 'abcd capture': on write, run a NON-BLOCKING similarity scan over open/ issues plus draft intents, and when a strong match is found return it in the capture result (e.g. 'captured iss-N; possible overlap: itd-91, iss-193 — review?') WITHOUT gating the write. This gives the user immediate 'this area is already tracked' reassurance while keeping capture one-line and friction-free — verifier-selects/gates-decide: the tool proposes the overlap, the human disposes (keep / wontfix / promote). Distinct from itd-84's capture-time VALIDATOR (a deterministic pre-pass that decides INTENT decomposition FILE-AS-IS/SPLIT/HOLD, not issue-duplicate detection) and from itd-87 (recurrence-escalation in capture). The deeper cross-corpus combine — merging issue clusters and promoting to intents — is a separate periodic step (e.g. a 'capture list --dedupe' view), not per-capture. Motivated 2026-08-27 by a session that recorded a duplicate of itd-91 and caught it only after the write; until this ships, the documented protocol (agent recall-checks the ledger before recording) is the gate. Candidate for promotion to an intent.
- itd-1Every Intent Has Acceptance Criteria; Every Audit Verifies Them
- itd-178Every record written through a command carries its origin and its production mode — stamped by the command, never typed by hand
- itd-2609231013154443Every release arrives with a press release composed from what shipped
- spc-34The managed-repo identity gate — detect the wrong author/committer, establish only on confirm
- spc-56Origin and production-mode keys, stamped by the command