# MadeBy > MadeBy records who wrote each commit (a person, a person with AI, or an AI) as plain git trailers, following ACO, the Authorship Certificate of Origin, an open standard. It never guesses whether code is AI; it records what the author discloses. Disclosure, not detection. The CLI and MCP server are the `madeby` npm package (v0.3.12, MIT). ## If you are an agent working in a repo that uses MadeBy A repo uses MadeBy when it has an "Authorship disclosure (ACO)" section in AGENTS.md or CLAUDE.md, or a `.madeby/policy.json`. After you commit, disclose the honest category for that commit: - An AI (you) wrote it: `npx madeby@latest ai ""` adds `Authored-by-ai: ` - A person wrote it with your help: `npx madeby@latest me --with-ai ""` adds `Authored-by-human:` and `Assisted-by:` - A person wrote it alone: `npx madeby@latest me` adds `Authored-by-human:` - If `.madeby/policy.json` has `"recordModel": true`, madeby reads your model from Cursor, Copilot CLI or Claude Code itself. Otherwise add `--model ` only if you know it. Never guess. - If your platform makes or rebuilds the commit (a cloud coding agent pushing through its own tool), amending afterwards can be lost. Put the trailer in the message instead: `git commit -m "" -m "$(npx madeby@latest ai "" --print)"` Each command amends HEAD's message only, never its content, and refuses when changes are staged. ## Setting up or measuring a repo - `npx madeby@latest init` writes AGENTS.md (the disclosure rule), `.madeby/policy.json` (advisory: reports, never blocks) and a GitHub pull-request check. Flags: `--host azure-devops`, `--required`, `--record-model`, `--update`. - `npx madeby@latest coverage` shows how much of the history is disclosed, the human / with_ai / ai mix, and the agents and model versions named. Undisclosed commits are unknown, never assumed human. - `npx madeby@latest check []` is the gate: it evaluates commits against `.madeby/policy.json` and fails only under `"mode": "required"`. ## MCP server - Run it over stdio: `npx -y madeby mcp` - Client config: `{ "mcpServers": { "madeby": { "command": "npx", "args": ["-y", "madeby", "mcp"] } } }` - MCP registry: `io.github.MadeByFYI/madeby` - Tools: `init`, `check`, `coverage`, `who`, `disclose`, `ai` - Resources: `madeby://guide/aco`, `madeby://guide/align`, `madeby://guide/enforce`, `madeby://guide/backfill`, `madeby://schema/policy` (all included in llms-full.txt) ## Docs - [Home page as Markdown](https://madeby.fyi/index.md): the madeby.fyi walkthrough (also served at `/` to `Accept: text/markdown`) - [llms-full.txt](https://madeby.fyi/llms-full.txt): the MCP guides, the AGENTS.md convention, the policy schema, the CLI reference and the ACO spec in one file - [AGENTS.md](https://madeby.fyi/AGENTS.md): the exact disclosure rule `madeby init` writes, to copy into a repo - [ACO specification](https://raw.githubusercontent.com/MadeByFYI/MadeBy/main/ACO.md) - [CLI reference](https://raw.githubusercontent.com/MadeByFYI/MadeBy/main/packages/cli/README.md) - [Source code](https://github.com/MadeByFYI/MadeBy) ## Optional - [Agent adoption experiment](https://raw.githubusercontent.com/MadeByFYI/MadeBy/main/experiments/aco-adoption/RESULTS.md): whether Claude Code, Cursor and Copilot disclose unprompted when a repo carries the convention ============================================================================== # The AGENTS.md convention Source: what `npx madeby@0.3.12 init` writes ============================================================================== # AGENTS.md ## Authorship disclosure (ACO) When you author or modify content here, **disclose who authored it** — per [ACO, the Authorship Certificate of Origin](https://github.com/MadeByFYI/MadeBy/blob/main/ACO.md). After you commit, run the command for the honest category (no install, no setup): - **ai** — an AI authored it (the committer stays accountable): `npx madeby@latest ai [tool]` - **with_ai** — a human authored it with AI assistance: `npx madeby@latest me --with-ai [tool]` - **human** — a human authored it: `npx madeby@latest me` If your platform makes the commit for you (a cloud coding agent that pushes through its own tool), amending afterwards can be lost — put the disclosure in the message instead, with `--print`: `git commit -m "" -m "$(npx madeby@latest ai [tool] --print)"`. Disclose per commit, honestly. Undisclosed content stays *unknown*, never guessed. ============================================================================== # madeby://guide/aco Source: MCP resource from `npx madeby@0.3.12 mcp` ============================================================================== # ACO — the Authorship Certificate of Origin ACO is the open standard MadeBy implements and verifies: a signed, content-bound, tiered statement of which of {human, with_ai, ai} authored a unit of work. **Disclosure, not detection** — it records what a party PUT ON THE RECORD, never inferring authorship from source. Full spec: https://github.com/MadeByFYI/MadeBy/blob/main/ACO.md ## The three categories - **human** — a human authored it, no AI involvement. - **with_ai** — a human authored it with disclosed AI assistance. - **ai** — an AI agent authored it (a human remains accountable). ## How an agent discloses its OWN work (asserted tier, no keys) - After you commit, call **disclose** with the honest `category` and your `tool` name (e.g. "Claude Code"): - `ai`: you wrote it; the committer stays accountable. Adds `Authored-by-ai: `. - `with_ai`: a human wrote it with your help. Adds `Authored-by-human` + `Assisted-by: `. - `human`: a human wrote it alone. Adds `Authored-by-human`. If you wrote the code and a human is only committing it, that is `ai`, not `with_ai`. - **The model version.** If the repo's `.madeby/policy.json` has `"recordModel": true`, madeby reads your model from the tool's own record of the session (Cursor, Copilot CLI, Claude Code) and writes `:`. Elsewhere pass `model` only if you know your exact model version. Never guess. - **If your platform makes or rebuilds the commit** (a cloud coding agent that pushes through its own tool), a trailer amended in afterwards can be lost. Call disclose with `print: true` to get the trailer lines instead, and put them in the commit message's last paragraph. - Fully AI-authored spans recoverable from your session log -> call **ai** (records structurally-verified spans, local-only). - Read what's already disclosed -> **who**; measure a repo -> **coverage** (also lists the agents and models named). Align a whole repo -> **init** (also scaffolds an AGENTS.md ACO convention so any agent working there discloses). Disclose per commit, honestly. Undisclosed content stays *unknown*, never guessed. ============================================================================== # madeby://guide/align Source: MCP resource from `npx madeby@0.3.12 mcp` ============================================================================== # Aligning a repository with MadeBy MadeBy is **disclosure, not detection** — it records what a commit *states* about its origin, never guesses whether code is AI. To align a repo: 1. **Assess** — call `coverage` for the scoreboard (known vs unknown, the human / with_ai / ai mix, and the agents and model versions named), `check` for the gate's verdict, or `who` with no path for a repo-wide map. 2. **Set up** — call `init`: it writes `.madeby/policy.json` (advisory), the AGENTS.md disclosure rule, and the CI disclosure check (`host: "azure-devops"` for Azure Pipelines). Idempotent; it never clobbers an existing policy or workflow (`mode: "required"` only ever raises an advisory policy to required). Add `record_model: true` if the repo should also record which model version did the work (opt-in; a project's choice). Then commit the created files. 3. **Disclose going forward** — contributors disclose origin with an `Authored-by-ai` trailer (an AI wrote it; `madeby ai` adds it), `Authored-by-human` plus `Assisted-by` (a human wrote it with AI; `madeby me --with-ai`), `Authored-by-human` alone (`madeby me`), a Co-Authored-By / Generated-by AI trailer, a DCO Signed-off-by, a signed commit, or witnessed spans from an AI session log (`madeby ai --witness`). Human and AI disclosure ride the same ladder. 4. **Account for existing history honestly** — do NOT fabricate disclosure for past commits. Read the `madeby://guide/backfill` resource: recognize what's already disclosed, attach recoverable evidence, and set an adoption boundary — pre-boundary history is labeled *unknown*, never invented. 5. **Enforce when ready** — set the policy mode to `required`, then make the check required on the protected branch. That last step is the host's control plane (your credentials), so MadeBy doesn't do it for you — the exact commands are in the `madeby://guide/enforce` resource. 6. **Verify** — call `check` again. Nothing is hosted; nothing leaves the CI. The maintainer owns the policy. ============================================================================== # madeby://guide/enforce Source: MCP resource from `npx madeby@0.3.12 mcp` ============================================================================== # Enforcing the MadeBy disclosure check MadeBy sets the policy (mode: required) but does NOT change your repository's protection settings — that needs your credentials and is the host's control plane, so you (or an agent acting as you) make the check required. MadeBy deliberately keeps this an explicit, reviewable action. ## GitHub (needs repo admin + the gh CLI, authenticated) 1. Set the policy to required (or run: madeby init --required): in .madeby/policy.json set "mode": "required". 2. Find the check's name: open any pull request and read the Checks tab. For the generated workflow the job name is "madeby". 3. Add it as a required status check on the protected branch (e.g. main). If protection already exists, add the context: echo '["madeby"]' | gh api -X POST \ repos/OWNER/REPO/branches/main/protection/required_status_checks/contexts --input - If the branch has no protection yet, create it with a required_status_checks block that lists "madeby" (PUT repos/OWNER/REPO/branches/main/protection --input protection.json). Confirm against the GitHub REST docs for "branch protection" and verify with the actual check name from a PR. ## Azure DevOps (build validation branch policy) Project Settings -> Repositories -> (repo) -> Policies -> Branch (main) -> Build Validation -> Add: point it at the pipeline that includes azure-pipelines-disclosure.yml; set trigger automatic and required. CLI equivalent: az repos policy build create ... --branch main --blocking true. ============================================================================== # madeby://guide/backfill Source: MCP resource from `npx madeby@0.3.12 mcp` ============================================================================== # Honest backfill for an existing repo You cannot retroactively disclose past commits by inventing origin — that is fabrication, and MadeBy refuses it. But you CAN make an honest, verifiable statement about history. Backfill in layers, and never raise a commit's origin above its evidence — unknown stays unknown, just explicitly so. 1. **Recognize what's already there** (free, pure evidence). Run `check` over FULL history: existing Co-Authored-By AI trailers, DCO Signed-off-by, signed commits, and bot authorship are recognized now even though they predate adoption. Much of your history may already be disclosed. 2. **Attach recoverable evidence** (opt-in, evidence-grade): - Old AI-tool session logs -> `ai` attaches structurally-verified spans to their commits (it only matches content actually present, so it cannot over-claim). Pass the transcript + the ref. - Committed AI-tool configs (.cursor/, CLAUDE.md, ...) are repo-level evidence the repo used AI. 3. **Set the adoption boundary** (the watermark). The commit that introduced .madeby/policy.json is your dated adoption boundary: git log --diff-filter=A --format=%H -- .madeby/policy.json | tail -1 Report coverage RELATIVE to it: commits after the boundary are in-regime and measured; commits before are UNKNOWN-origin (never "human", never "AI") unless independently disclosed by step 1/2. This makes the gap explicit and dated instead of hidden. 4. **Optionally self-attest** what you can stand behind (asserted tier). The author may assert specific pre-boundary facts they honestly know ("I solo-authored the initial import"; "vendor/ is third-party"). It is labeled self-reported (asserted) — never proof — and is contestable. The invariant: backfill adds only evidence you can point to, or an explicitly-labeled assertion; it never fabricates disclosure or upgrades origin beyond its evidence. ============================================================================== # madeby://schema/policy Source: MCP resource from `npx madeby@0.3.12 mcp` ============================================================================== ```json { "$schema": "http://json-schema.org/draft-07/schema#", "title": ".madeby/policy.json", "type": "object", "required": [ "version", "mode" ], "properties": { "version": { "const": 0 }, "mode": { "enum": [ "advisory", "required" ], "description": "advisory: report only (the default, and the safe degrade); required: fail on any undisclosed commit" }, "accept": { "type": "array", "items": { "type": "string" }, "description": "restrict what satisfies the policy (e.g. dco-signoff, ai-trailer, commit-signature); omit ⇒ any recognized disclosure counts" }, "recordModel": { "type": "boolean", "description": "ask AI disclosures to name the model version too (tool:model, e.g. Assisted-by: Cursor:gpt-5.3-codex); madeby reads it from the tool's own session record where it can. Set by init --record-model. A request, not a gate" } } } ``` ============================================================================== # CLI reference Source: https://raw.githubusercontent.com/MadeByFYI/MadeBy/main/packages/cli/README.md ============================================================================== # madeby **Disclose AI authorship of code. Disclosure, not detection.** If you are an **AI coding agent** (Claude Code, Copilot, Cursor, Codex, …) and you authored or modified code, disclose it in one command after you commit: ```sh npx madeby ai # adds an `Authored-by-ai:` trailer to HEAD — you (the committer) stay accountable ``` That's the honest **`ai`** disclosure (asserted tier, no session log needed). The three authorship categories of the open **ACO standard** (Authorship Certificate of Origin): | Category | Command | What it records | |-----------|----------------------------------|----------------------------------------| | `ai` | `npx madeby ai [tool]` | `Authored-by-ai:` — an AI authored it | | `with_ai` | `npx madeby me --with-ai [tool]` | `Authored-by-human:` + `Assisted-by:` | | `human` | `npx madeby me` | `Authored-by-human:` | A repo invites this with an [`AGENTS.md`](https://github.com/MadeByFYI/MadeBy/blob/main/AGENTS.md) convention (drop one in with `npx madeby init`); agents that read it disclose unprompted — in a [reproducible experiment](https://github.com/MadeByFYI/MadeBy/tree/main/experiments/aco-adoption), three AI coding agents did so in **12 of 12 trials, 0 of 14 without the convention.** `madeby` also **recognizes disclosure already in the wild** — `Co-Authored-By:` / `Assisted-by:` trailers, DCO sign-offs, SPDX AI-disclosure tags — and lets a project **gate PRs** on it (`madeby check`). It never guesses whether code is AI; no tool can do that honestly. It reports only what contributors **put on the record**. Zero hosted infrastructure — runs against your local git history, on a laptop or in any CI. Nothing leaves your machine. ## Install ```sh npx madeby@latest ai # no install needed # or npm i -g madeby ``` ## Usage ``` madeby init Set MadeBy up: write .madeby/policy.json + the CI disclosure check. --record-model (opt-in) also asks agents to name the model version. madeby check [] The gate: do commits meet .madeby/policy.json? (a verdict — exit code gates). e.g. origin/main..HEAD — a PR's own commits. --json too. madeby coverage [] The scoreboard: how much of the repo's authorship is disclosed (known) vs unknown, the human/with_ai/ai mix, and the asserted/verified split. madeby who [] Made by whom? What's on the record about who made this — one file's (alias: whom) origin, or the whole repo with no path. --lines=A-B to scope. --json too. madeby ai [tool] Made by AI: attest AI authorship of HEAD (an Authored-by-ai trailer). --model names the model too (Authored-by-ai: :). `--witness [log]` instead records witnessed spans from a session log. madeby me [--with-ai [t]] Made by me: affirm you authored HEAD (Authored-by-human); --with-ai adds Assisted-by → with_ai. --model names the model too. --print (me / ai) print the trailer lines instead of amending HEAD — for a platform that makes the commit itself (a cloud coding agent): git commit -m "" -m "$(madeby ai --print)". madeby mcp Run the MCP server (stdio) — the tools, agent-callable. madeby help ``` The surface is your product thesis — **"made by ___"**: `who` reads it, `ai` and `me` write the two sides of it, and `init`/`check` are the setup and the gate. ### `madeby check` — the disclosure gate Reads `.madeby/policy.json`, recognizes each commit's disclosure signals, and reports coverage. A commit **discloses its origin** if it carries any of: - an **AI-authorship trailer** — `Co-Authored-By:` / `Generated-by:` / `Assisted-by:` naming an AI tool (Claude Code, Copilot, Cursor, aider, … already emit these); - an **affirmative human-authorship trailer** — `Authored-by-human: ` (see below); - a **DCO `Signed-off-by:`** line; - a **commit signature**; - a **`madeby ai`** attestation (your own AI session's witnessed spans). Exit codes: **0** = pass · **1** = a `required` policy failed on an undisclosed commit · **2** = not a git repository. Under `advisory` it only reports (always exit 0) — so it's safe to add to CI before you decide to enforce anything. In CI, omit `` — on a pull-request build `madeby check` **auto-scopes to the PR's own commits** from the CI environment (GitHub today; other hosts via their adapter). Pass an explicit `` to override. ### `madeby coverage` — the authorship scoreboard `check` is the gate; `coverage` is the picture. Run it in any repo to see how much of your history's authorship is **on the record** — no policy, no config: ```sh madeby coverage # scores recent history madeby coverage origin/main..HEAD # or a range ``` ``` authorship coverage — last 500 commits (estimate · disclosure, not detection) known 62% ████████████░░░░░░░░ disclosed — on the record unknown 38% ███████░░░░░░░░░░░░░ no disclosure — origin unknown, never guessed of the 310 known: human 41% · with_ai 38% · ai 21% trust: asserted 88% · verified 12% — self-reported; sign commits to verify agents & models named in the 183 AI commits: Claude Code 121 66% Claude Opus 5.5 98 54% Cursor 62 34% → 38% unknown. Require disclosure going forward: madeby init --required ``` It is a **labeled estimate**, honest by construction: an undisclosed commit is **unknown**, never inferred as human — disclosure, not detection. The human/with_ai/ai mix is reported *of the known*, never of the whole repo, and the asserted-vs-verified split shows how much is signed. The agents and model versions are listed exactly as the AI commits name them — a commit naming a tool and its model (`Assisted-by: Claude Code` + `Co-Authored-By: Claude Opus 5.5`) counts under both, so those rows can sum past 100%. `--json` emits counts only (percentages are derived at the edge, never stored). A plain merge authors nothing and isn't scored; a merge that changes content of its own (a conflict resolution) is, like any other commit — chosen by what it changes, never by whether it discloses. Use it to see your gap, then `madeby init --required` to close it going forward. ### `madeby me` — affirm human authorship Disclosure runs both ways: if you wrote code yourself, affirm it so your work is *disclosed-human*, not lumped into unknown. `madeby me` adds an `Authored-by-human` trailer to your last commit — the symmetric human claim to `madeby ai`. (The "tool" underneath is just git; if you prefer it at commit time, `git commit --trailer "Authored-by-human: …"` does the same thing.) ```sh madeby me # affirms human authorship of HEAD ``` Human and AI disclosure ride the **same ladder** — a trailer is *asserted*; sign the commit and it's *verified* (the signature authenticates *who* affirmed it, not the human-vs-AI content — equally true of AI disclosure); a sworn declaration is *sworn*. The one asymmetry is evidence, not tier: AI can leave a re-checkable artifact (a session log, `madeby ai`); human authorship is your firsthand testimony. If you used AI, disclose the AI — don't claim human. **The policy file is optional.** With no `.madeby/policy.json`, `check` defaults to **advisory** — it reports coverage and never blocks, so you can run it (or add the CI check) with zero config. Add the file only when you want to enforce: ```json // .madeby/policy.json { "version": 0, "mode": "required" } ``` Two modes, nothing more: - `advisory` — report coverage on each run; never fails. **The default** (and what you get with no file). - `required` — fail on any commit that discloses nothing your policy accepts. - optional `"accept": ["dco-signoff", "ai-trailer", …]` — restrict what satisfies the policy (omit ⇒ any recognized disclosure counts). - optional `"recordModel": true` — written by `madeby init --record-model`: the repo asks AI disclosures to name the model version as well as the tool. It adds one line to the AGENTS.md rule, and `me --with-ai` / `ai` then read the model from the **tool's own record of the session** — Cursor's `CURSOR_MODEL` or its chat store, the Copilot CLI and Claude Code session logs (locally; only the model id is read) — which wins over an agent's `--model`, since an agent routed by "Auto" may not know which model served it. Elsewhere `--model ` is used, never guessed. So `coverage` can list each **agent · model** pairing (`Cursor · gpt-5.3-codex` vs `Claude Code · claude-sonnet-5`). A request, not a gate — an AI disclosure without a model still satisfies the policy. Opt-in because naming models is a project's call: the Linux kernel, for one, asks only that an LLM was used, not which. (There's no "off" — that's just not running the check. Advisory is the floor.) Fail-safe by design: a missing or malformed policy degrades to `advisory`. `madeby` never blocks a PR on its own error, and never invents a stricter gate than the maintainer wrote. ## Use it as a PR check A ready-made GitHub Action, an Azure DevOps Pipelines template, and a GitLab CI job wrap `madeby check` — nothing hosted, nothing leaves your CI. See [`packages/action`](https://github.com/MadeByFYI/MadeBy/tree/main/packages/action#readme). ## Extend it anywhere — primitives you run, not code you ship MadeBy is composable primitives, not a plugin host. To support a **new CI host, a custom gate, or your own dashboard**, you don't register code with us — you run the primitives **in your own environment**: - **`madeby check --json`** — the gate's structured result (`pass`, `mode`, `undisclosed[]`); the exit code still gates, so CI can use either. - The raw recognizer as a library: [`@madeby/core`](https://www.npmjs.com/package/@madeby/core) (`commitDisclosureKinds`, `evaluateDisclosurePolicy`) — per-commit disclosure kinds, no policy. Build any view or gate on top, in your own runtime. **A new host needs no adapter from us** — compute the range however that host exposes it and pass it. Any CI without a built-in adapter ships nothing to MadeBy; e.g. a Jenkins pipeline: ```groovy sh 'npx --yes madeby check "origin/${CHANGE_TARGET}...HEAD"' ``` We ship built-in adapters (GitHub, Azure DevOps, GitLab) so those hosts are turnkey — the CI env auto-scopes the range with no arguments — but they're a *convenience, not the extension path*. Whatever you compose can only report what the primitives permit, so the trust guarantees hold no matter who runs them. ## Agent-native — the MCP server `madeby mcp` runs a [Model Context Protocol](https://modelcontextprotocol.io) server over stdio, so an AI agent can use MadeBy with no human in the loop. It exposes the same primitives as typed tools: - **`init`** `{ path?, mode?, host? }` — set a repo up: create `.madeby/policy.json` + the CI check (idempotent). The one-call setup. *write* - **`check`** `{ path?, range? }` — the gate: do commits meet the policy? Returns `pass`, `mode`, `undisclosed[]`. *read (verdict)* - **`who`** `{ path?, repo?, startLine?, endLine?, prefix?, commitLimit? }` — made by whom? With a `path`: what's *on the record* about that file's origin — witnessed AI spans (model/tool) where captured, last-touch commit disclosure elsewhere, unknown otherwise. With no `path`: the repo-wide map an agent reads *before* it works (the witnessed AI surface + commit-level coverage; cheap). The line range is the contract — for a symbol, turn it into a range with your own tooling (tree-sitter/LSP); MadeBy never parses code. *read (attribution)* - **`disclose`** `{ path?, category?, tool? }` — made by ___: disclose authorship on HEAD per ACO. `category: "ai"` (an AI authored it; the committer is the accountable human) adds `Authored-by-ai`; `"with_ai"` adds `Authored-by-human` + `Assisted-by`; `"human"` adds `Authored-by-human`. The agent-native disclosure for the work you just did. *write* - **`ai`** `{ path?, log?, ref? }` — the evidence upgrade for the `ai` category: record witnessed AI spans from the agent's own session log into `.madeby/spans` (asserted→verified, local; only spans structurally present are kept). *write* The server is also **self-teaching** via MCP resources, so an agent can discover *how* to align a repo, not just which verbs exist: - **`madeby://guide/align`** — the step-by-step alignment workflow. - **`madeby://guide/enforce`** — the exact commands to make the check *required* on a protected branch (GitHub / Azure) — the host's control plane, so MadeBy doesn't do it for you, but it's not left to the reader either. - **`madeby://guide/backfill`** — how to account for pre-adoption history *honestly*: recognize what's already disclosed, attach recoverable evidence, set an adoption boundary; unknown stays unknown, never fabricated. - **`madeby://schema/policy`** — the `.madeby/policy.json` schema. So "align my repo with MadeBy" is fully agent-serviceable: the agent reads the guide, calls **`init`** to write the policy + CI check, discloses its own work with **`disclose`** (and optionally upgrades it to witnessed spans with **`ai`**), and verifies with **`check`** — no human in the loop. (Two things stay outside the tools, by design: turning on branch protection is the *host's* setting, and historical commits are never backfilled — disclosure is going-forward. `ai` cannot claim a higher tier or attribute to anyone else, and nothing leaves the machine.) Point an MCP client at the command (e.g. a `claude_desktop_config.json` / `.mcp.json` entry): ```json { "mcpServers": { "madeby": { "command": "npx", "args": ["-y", "madeby", "mcp"] } } } ``` Dependency-free and self-contained: stdout carries only protocol messages, an unreadable repo or bad input comes back as a tool error (the agent sees it, never a crash), and — like every surface — the tools can only report what the primitives permit. ## Honest scope Disclosure and accountability, **not** an AI slop-blocker or detector. A `required` gate deters low-effort drive-bys (as the DCO does) and gives a basis to triage — it does not, and will never, claim to detect AI. MIT · part of [MadeBy](https://github.com/MadeByFYI/MadeBy) ============================================================================== # ACO — the Authorship Certificate of Origin (specification) Source: https://raw.githubusercontent.com/MadeByFYI/MadeBy/main/ACO.md ============================================================================== # ACO — the Authorship Certificate of Origin **Status:** v0.1 draft · open standard · comments welcome (open an issue) **Reference implementation & canonical verifier:** [MadeBy](https://github.com/MadeByFYI/MadeBy) ACO is an open, tool-independent standard for **verifiable authorship disclosure** of code and other content — a signed, content-bound, tiered statement of *which of {human, with_ai, ai}* authored a unit of work. It is the authorship-era companion to the [Developer Certificate of Origin (DCO)](https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin): where the DCO attests you have the *right* to contribute, ACO attests *who — and what — authored* the contribution, in a form a machine can verify. > **Agents adopt it on their own.** In a [reproducible experiment](./experiments/aco-adoption/), three > independent AI coding agents — Claude Code, GitHub Copilot, and Cursor — each given an ordinary coding > task with no mention of disclosure, read an `AGENTS.md` ACO convention and disclosed their authorship > unprompted in **12 of 12 trials; 0 of 14 without the convention.** See > [experiments/aco-adoption/RESULTS.md](./experiments/aco-adoption/RESULTS.md). The standard is deliberately separate from any one tool. MadeBy is its reference implementation and canonical verifier, but ACO is a spec anyone may implement, and its claims are verifiable by anyone — that independence is the point. ## 1. What ACO certifies — and what it does not ACO certifies a **claim, not a fact.** For a specific unit of content it records *which category the signer states authored it*, bound to that exact content, attributable to an identified signer, tamper- evident, and carrying a **tier** that says how well-corroborated the statement is. - It certifies *that a disclosure was made, by whom, over exactly this content, and how much stands behind it.* - It does **not** claim the statement is metaphysically true, and it does **not** detect authorship by inspecting source. Undisclosed content stays **unknown** — never a guess. Truth is approached *asymptotically through the tiers* (§4): corroborating evidence can raise a claim from *asserted* toward *bound*, but the standard never manufactures certainty, and it **fails safe** — an implementation degrades to *asserted* or *unknown*, never to falsely-verified. This is the DCO move: certify a signed, attributable *statement* the ecosystem can converge on, rather than fight an unwinnable authorship-detection arms race. ## 2. The taxonomy Authorship is disclosed as one of three categories (the "three-way taxonomy"): | Category | Meaning | Badge | |------------|------------------------------------------------------|-----------| | `human` | Authored by a human, no AI involvement disclosed | `human` | | `with_ai` | Human-authored with disclosed AI assistance | `hi + ai` | | `ai` | Authored by an AI agent (with human accountability) | `ai` | The category is a property of the **disclosure**, not an inference. `with_ai` is a first-class middle state, not an afterthought: a human is accountable **and** the AI is disclosed. ## 3. The claim (semantic core, carrier-independent) Every ACO claim, in any carrier (§5), carries the same semantic core: - **Subject** — *what* content, anchored by a **reference to a native content hash** (`{alg, target, value}`) at one or more resolutions (exact: git blob/tree/commit SHA, `sha256`; structural: AST-normalized / fuzzy fingerprints). The subject is a *reference* to a native hash, never a re-hash of content into an ACO-specific envelope (see §6, invariant 1). - **Attribution** — the **category** (§2) plus, for AI, the **provider / model / version as open fields** (never a closed enum), plus the **operator**: the human or org whose key stands behind the claim. In a commit trailer the agent and model version are two fields, `tool:model` — e.g. `Assisted-by: Cursor:gpt-5.3-codex` — the form the Linux kernel used for `AGENT_NAME:MODEL_VERSION`. Naming the model is the project's choice (`recordModel` in the policy); the tool alone is a complete disclosure. - **Evidence + tier** — the corroboration level (§4) and its source (self-report, tool session log, signed commit, Sigstore, C2PA, sworn declaration). - **Signature** — the operator key and timestamp, computed over the **canonical form of the claim** (§6, invariant 2) — independent of carrier. - **Optional overlays** — a sworn legal/rights assertion; lineage (`derived-from`). ## 4. Trust tiers A claim resolves to exactly one tier, and **no claim is elevated beyond what its carrier and signature support**: - **asserted** — a self-report (e.g. a commit trailer). The floor. Always available; requires no keys. - **verified** — backed by corroborating evidence whose canonicalization is known (e.g. witnessed tool-session spans, structural match), signature-checkable. - **sworn** — carries a legal/rights declaration overlay by an accountable party. - **bound** — cryptographic hard binding: the claim incorporates an existing *signed* content hash (signed git commit, C2PA hard binding, Sigstore), so signer and content are cryptographically joined. **Degradation rule:** a recognized carrier with known canonicalization can reach its full tier; a self-describing carrier is readable and, if its canonicalization is declared, verifiable; a fully unrecognized carrier is parsed and displayed but **capped at *asserted*** with a "binding not recognized" flag. An unknown implementation degrades gracefully; it never breaks verification. ## 5. Carriers (bindings) — subsume, don't compete ACO separates *what a claim says* (the semantic core, §3) from *how it is serialized* (the carrier). The signature is over the canonical claim, so the same claim in two carriers verifies identically. A **carrier registry** lists recognized bindings, each with a parser and a stable identifier. ACO's posture toward the disclosure conventions that already exist is to **recognize and verify them, not replace them** — an existing disclosure is ingested as a carrier at its supported tier: - **DCO sign-off** (`Signed-off-by:`) — recognized; ACO adds the authorship category and the verifiable tiering the DCO alone doesn't express. - **SPDX 3.0 AI profile / SPDX-AI-Disclosure tags** — recognized (interop / BOM export). - **Commit trailers** — the canonical asserted-tier carrier (see §7). - **in-toto predicate** — signing-native; composes with the Sigstore / SLSA rails. - **git-notes**, **commit signatures**, and **witnessed AI-span evidence** (`.madeby/spans`). - **Self-hosted sworn declarations** — detected and pointed to, never re-hosted. Unknown carriers are handled by self-description + tier-capped degradation (§4). The format is open and governed lightly (media-type-registry style: who may claim a binding identifier). ## 6. Invariants (any conformant implementation must hold these) 1. **The subject of a claim is a *reference* to a native content hash, never a re-hash of content into the standard's own envelope.** 2. **Signatures cover the canonical claim payload, independent of carrier.** 3. **Unrecognized carriers / unverifiable signatures cap at the *asserted* tier.** 4. **"Percent authored" is a computed *view*, never stored ground truth.** 5. **The system fails safe** — degrade to asserted / unknown, never to falsely-verified. 6. **Aggregate indices are labeled estimates** with a surfaced tier distribution. ## 7. Conformance - **Emit (asserted tier)** — the floor is a commit trailer, and requires no keys or infrastructure: - `human`: `Authored-by-human: ` - `with_ai`: `Authored-by-human: ` **and** `Assisted-by: ` - `ai`: an `Authored-by-ai: ` trailer (`madeby ai`) — an AI authored it, the committer is the accountable human — optionally upgraded with witnessed AI-span evidence (`madeby ai --witness`). A producer is ACO-conformant at the asserted tier if it emits a recognized carrier (§5) that expresses a §2 category over a §3 subject. - **Verify** — a verifier is conformant if it resolves claims through the tier and degradation rules of §4, honors every invariant in §6, and never elevates a claim beyond its carrier + signature. - **Higher tiers** (`verified` / `sworn` / `bound`) layer onto the same claim as evidence, signatures, and identity anchoring become available — the asserted claim is never invalidated, only corroborated. **Adopting the convention (repos):** drop an [`AGENTS.md`](./AGENTS.md) disclosure convention into your repository so any agent working there discloses at the asserted tier with no setup (`npx madeby …`). This repository's [`AGENTS.md`](./AGENTS.md) is the reference convention. ## 8. Relationship to neighboring standards ACO **rides** where a standard exists and **extends into the gap** where none does: | Neighbor | Relationship | |----------|--------------| | **DCO** | ACO is the authorship-era companion; ACO recognizes and verifies DCO sign-offs as a carrier. | | **SPDX 3.0 AI profile** | Recognized carrier for interop / BOM export. | | **Sigstore / SLSA / in-toto / npm provenance** | Identity + signing rails ACO rides for the `bound` tier; ACO adds the human/AI authorship semantics they don't carry. | | **C2PA / Content Credentials** | The media-provenance analog; ACO focuses on code and text authorship. | Identity in ACO **anchors existing roots** (OIDC / keyless / domain control, Sigstore-shaped) rather than minting a new PKI. ## 9. Governance & status ACO is an **open standard**. This is a **v0.1 draft** and will version explicitly. The standard is carrier-open and lightly governed; the reference implementation and canonical verifier is MadeBy, and the standard is federatable — anyone may implement, verify, or self-host, and that exit is real by design. Public feedback (issues / PRs) is welcome and expected to shape v1.