Development record
A managed repo commits under whatever identity git happens to resolve, and when
A managed repo commits under whatever identity git happens to resolve, and when
user.email is unset git invents one — the OS account's full name plus
$USER@$(hostname), silently, on the first commit. This repo's own history
carried 25 such commits before the 2026-08-06 rewrite, all authored and
committed under a fabricated <user>@<host>.local pair no one ever typed. The
same gap let autonomous harness runs commit under a tool identity: nothing in a
managed repo declares who its commits belong to, so every machine and every
harness answers the question differently.
Scope, settled by the maintainer (2026-08-06): abcd enforces exactly one thing — that a managed repo commits under the user's own GitHub identity, and that git can never fabricate a substitute. Nothing more. Rejecting AI co-author trailers, allowlisting authors, and gating pushes on trailer presence are out of scope here: those belong to the forge's own rules (a server-side ruleset) and to iss-119, not to abcd.
What that means concretely:
ahoy installpins the identity. It resolves the user's canonical GitHub name and email (the account's no-reply address is the safe default — it is what the forge already attributes to them, and it leaks no personal mailbox) and writes both into the managed repo's local git config. Repo-local, not global: abcd configures the repos it manages and leaves the rest of the machine alone.- Fabrication is disabled, not merely overridden. The repo also sets
user.useConfigOnly, so a checkout whose identity is missing or cleared fails the commit with an error instead of quietly deriving one from the host. A refusal is recoverable; a fabricated commit is already in the history. - The state is observable. A managed repo whose identity is unset, or set to something the install did not pin, is reported — the same fail-loud posture the guard and audit rules take, so the gap surfaces before a commit rather than after a rewrite.
The privacy half matters as much as the attribution half: an auto-derived
identity embeds the machine's hostname in every commit it touches
(alice@alice-laptop.local in the persona shape), which is the same
never-commit-hostnames class the v0.5.0 security half closes in scanning and
redaction. Prevention at the commit boundary is where that leak is cheapest to
stop — the scanner can only find it once it is already written.
Likely intent-scale: a user-facing capability across every managed repo, so it
wants an intent and a spec rather than a bare fix. Reconcile with, rather than
duplicate, iss-84 (managed pre-commit gates — the hook seam this would use),
iss-85 (managed attribution config — the nearest neighbour; check whether this
supersedes it or lands inside it) and iss-119 (Assisted-by declared but
unenforced — the trailer half, deliberately left out of this scope).
Deferral 2026-09-29
Deferred past v0.11.1: The product thinker's ruling M2 of 2026-09-23 folds this into itd-131 and spc-34, but itd-131 shipped and spc-34 closed without it: nothing in internal/ pins an identity at install or sets user.useConfigOnly. Owed: a successor intent for the pinning half, which needs the product thinker's adoption, and one ruling: may ahoy install look up the canonical GitHub identity although adr-38 keeps implicit paths disk-only, since install is an explicit act?
Remedy grounds (2026-09-29)
- git's own documentation: user.useConfigOnly makes git 'avoid trying to guess defaults for user.email and user.name' and retrieve them only from configuration (git-config(1), https://git-scm.com/docs/git-config, consulted 2026-09-29); that half needs no ruling and closes the fabrication, so the remedy separates it from the lookup question (B).
- Rejected: a global useConfigOnly, which reaches beyond the repositories abcd manages.
Frontmatter
| id | iss-193 |
|---|---|
| type | issue |
| lifecycle | open |
| severity | major |
.abcd/work/issues/open/iss-193-attribution-identity-enforcement-belongs.md
open on GitHub ↗ · commit history ↗
mentions9
- adr-38Implicit checks are disk-only — the network answers only an explicit ask
- iss-84Managed pre-commit gates: the interim prepare-this-repo skill offers the secrets and absolute-path pre-commit config from a private template directory outside the repo. The gate belongs to the configuration layer itself: a core-owned surface should install and maintain commit gates in managed repos, replacing the template copy. Seeded from the scaffold-repo retirement analysis; relates to the pluggable safety gate draft (itd-62).
- 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-119AGENTS.md declares the Assisted-by trailer for AI-assisted commits, but nothing enforces it: the repo commits only pre-commit and pre-push hooks, and the global hooks are pure dispatchers. The ad3fc38 merge commit landed on a PR branch without the trailer and no gate objected. Per one-writer-per-file's sibling lesson (a convention without an armed check is silently violated under load), either a commit-msg check validates the trailer on AI-assisted commits or the miss rate is accepted explicitly.
- iss-2608210923437502The bundled COMMITTING rules domain (the defaults every managed repo inherits from the binary) says Assisted-by-not-Co-Authored-By but omits the two attribution failures that keep recurring operationally and are currently patched by per-agent memory and per-routine prompt text: (1) the harness auto-appends a Generated-by footer plus session link to PR bodies and issue comments it creates — the domain should instruct the post-write read-back-and-strip (iss-178 remedy a, as an injected rule rather than every routine prompt re-carrying it); (2) autonomous runs default their git identity to the tool, which the attribution gate rejects (iss-193's class) — the domain should name the commit-as-the-human requirement. Prevention rung, complementing iss-178's detection remedy b; prompt-carried and memory-carried safety is the anti-pattern itd-114 just retired for minting
- 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-131The managed-repo identity gate: the human is the author of record on every commit, before the first one
- spc-34The managed-repo identity gate — detect the wrong author/committer, establish only on confirm