Skip to content

Model names refused in three layers: the tool's default, the commit-msg hook, the gate (#169) - #282

Open
Hafeok wants to merge 21 commits into
mainfrom
claude/dazzling-darwin-8irixp-169
Open

Hafeok wants to merge 21 commits into
mainfrom
claude/dazzling-darwin-8irixp-169

Conversation

@Hafeok

@Hafeok Hafeok commented Nov 11, 2026 •

Copy link
Copy Markdown
Owner

Completes: none

What this changes, and why

#169, all three layers from the maintainer's comment of 2026-11-11, implementing ADR 0241. It is stacked on 3da8929c, the approved head of #259–#261, where ADR 0241 is accepted, so it lands after them. Its own commits are the last five. #169 stays open for its last box, the port to the analyzer repository (#65), so this PR completes no issue.

  1. One pattern, held once: eng/model-names.cs and eng/model-families.txt.
    • A name is a family word (Opus, Sonnet, Haiku, Fable, Mythos), optionally after Claude, followed by a version.
    • It is matched regardless of case, and only standing alone. So the hyphenated API identifier, the bare Claude, a family word without a version, and a version without a family word all pass.
  2. The tool's default: .claude/settings.json. It sets attribution.commit to Co-Authored-By: Claude <noreply@anthropic.com> and attribution.pr to the link line. That is the shape the current settings reference documents; it replaces the deprecated includeCoAuthoredBy.
  3. The commit: eng/hooks/commit-msg.
    • It runs eng/model-names.cs --message first, for every author and tool.
    • A Co-Authored-By: trailer naming a model becomes the allowed one, and a repeat folds.
    • A name anywhere else refuses the commit, with the line quoted.
    • Without an SDK it warns and leaves the message to the gate.
  4. The gate: model-names in eng/ci.cs.
    • It checks every commit a pull request or a land/ push adds over main, merges included. The range is worked out as eng/issue-refs.cs works it out.
    • Commits reachable from 2cad18d5, the lower bound in the delegate's comment, are left out.
    • Each finding names the commit and the line.
    • model-names-fixtures proves the failure path on every build, and ci.yml's release call skips the range gate, as it skips the others.
  5. Documents:
    • AGENTS.md's Every commit says where the rule is held, and names no tool's settings file (ADR 0033);
    • docs/rules/ gains a commit-gate section and model-names.md;
    • a traceability record.

What was measured

  • dotnet run eng/model-names.cs -- --fixtures tests/fixtures/model-names: 13 cases, 0 judged wrong. The versions are fictional, so no real model's identifier is in the repository.
  • Scratch commits through the real hook, not pushed:
    model-names: a co-author trailer named a model; it now reads `Co-Authored-By: Claude <noreply@anthropic.com>` (ADR 0241).
    commit exit 0
    model-names: the message names a model: "Written with Sonnet 9.9."
    refused commit exit 1
    
  • The gate on a commit made with --no-verify:
    FAIL: 1 line(s) name a model (ADR 0241: a commit message never names a model; its identifier is allowed):
      b59e4ebe: "Co-Authored-By: Claude Haiku 9.9 <noreply@anthropic.com>"
    gate exit 1
    
  • The lower bound: --range 2cad18d5~4..3da8929c reads 16 commits, none naming a model, which agrees with the delegate's count on Commit gate: a commit message that names a model fails (names refused, ids allowed) #169.
  • eng/ci.cs with only licence-headers, decision-sets, issue-refs, dco, model-names, model-names-fixtures, changelog, release, status and land: all pass.

What was found

  • A cloud session honours the project-level setting in a single-repository session. A fresh cloud session started from this branch was told to end commits with Co-Authored-By: Claude <noreply@anthropic.com> plus the session link, and wrote exactly that, with the hook switched off. The session that built this PR started without the file, and was told a trailer naming the model. The documentation says nothing about attribution in a project's cloud threads. A managed, command-line or local setting also wins over the shared file, and so does any other tool's default. That is where the hook and the gate take over. The details are on Commit gate: a commit message that names a model fails (names refused, ids allowed) #169.

What is left


Checklist

  • Issue referenced: Refs #169 on every commit.
  • ADR cited: implements ADR 0241.
  • Specification updated, or n/a: n/a; docs/rules/model-names.md.
  • API baseline updated, or n/a: n/a.
  • Conformance baseline updated, or n/a: n/a.
  • Tests: fixtures on every eng/ci.cs run, and the hook exercised on scratch commits.
  • A new gate's failure path was proven by running it: quoted above.
  • Signed off: by the hook, which also ran the new check on each of these commits.
  • A traceability record exists: docs/traceability/2026-11-11-issue-169-model-names-in-three-layers.md.
  • dotnet run eng/ci.cs passes locally: the process gates and fixtures were run; the full test pipeline is left to CI.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NbWSYQ7rmZCcSgsvBFhZMm

Hafeok and others added 21 commits November 10, 2026 13:29
…fier is allowed

The maintainer's ruling of 2026-10-27, which #169's gate implements,
reverses the commit-message half of ADR 0033's amendment of 2026-10-02.
A reversal is a change of meaning, so under ADR 0068 point 2 it is a
supersession: ADR 0241 supersedes that one ruling, and
ModelNamedInTheRecordNotTheCommit moves to 0241's set under its key,
filed unaccepted (ADR 0066). 0033's Status names the supersession, and
AGENTS.md (Every commit, Never) and CONTRIBUTING.md state the ruling.
The record still names the tool and the model exactly.

Refs #257
Refs #169

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
A section after Every commit: work starts from an issue, decisions and
blockers go on it when they arise, found work is filed at once, the pull
request lists every issue it touches, closings are checked after landing,
and abandoned work is closed as not planned. As the prompt's note of
2026-11-10 asks, "the session" in Landing and After landing is whichever
session lands: the delegate lands and checks (ADR 0239), and a cloud
session posts its head, lists the issues and asks.

Refs #257

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
The prompts, the plan's correction from an amendment to ADR 0241's
supersession, what changed and what was found (#258). The model is left
for the maintainer to fill in, as ADR 0033 provides.

Closes #257
Refs #169

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…in moves

At both steps land.cs lists every issue a Closes, Fixes or Resolves
trailer line in main..head closes, with its title, recognising a trailer
as eng/issue-refs.cs does. A pull request's Completes: line is required:
missing, malformed, or naming an issue no pushed trailer closes, the
landing is refused, and a body it cannot read is refused too rather than
skipped. A release descriptor's trailer is a commit's trailer, so it
counts. After --main moves main, an issue a pushed trailer names that is
still open is printed with its commit and the exit is 1; GitHub unread
is 2. It closes nothing itself. Nine fixtures under tests/fixtures/land/,
run by eng/ci.cs's land-fixtures job.

Refs #209

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
The template opens with `Completes: none` and says what the line is and
that it is not a closing keyword (#108). AGENTS.md's Landing and After
landing bullets name the line, land.cs's refusal and its check after
main moves, so the rule and the script say the same thing.

Refs #209

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…landing

Closes #209
Refs #257

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…ogether

Under ADR 0224 point 2 the SBOMs are created at the descriptor's date, so
the two move together. --sbom runs eng/sbom.cs created at the current UTC
day (or --today), replaces the sbom: block with its sbom.txt and sets
date: to that day in one edit, then regenerates CHANGELOG.md. --from
takes SBOMs already written and refuses them unless each was created on
that day; --out says where eng/sbom.cs writes. A tagged version and a
descriptor with no sbom: block are refused. --draft points at it.

Gates: four fixtures under tests/fixtures/release-sbom/, run by eng/ci.cs's
release-sbom-fixtures job, and a ci.yml step that rewrites the newest
format-2 descriptor, renamed and backdated, in a scratch directory and
requires every SBOM created at the new date and eng/sbom.cs --descriptor
to match.

Refs #248

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…fore landing

At both steps, each release descriptor the head adds or changes is judged
against the landing day (UTC): a date: more than three days earlier, or
none, is refused, printing the release.cs --sbom command that writes the
digests and the date again. Three fixtures join tests/fixtures/land/: four
days refused, three days passing, no date refused.

Refs #248

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
docs/releases.md rule 3, amended 2026-11-10 with the old text struck and
kept, and rule 11's "written, not typed" naming release.cs --sbom. ADR 0102
gets a dated amendment, add-only, saying the same, since rule 3 restates its
line on date; no ruling changes, and ADR 0224 is untouched. AGENTS.md's
close-out names the command and land.cs's refusal.

Refs #248

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…s its digests

Closes #248

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
The three pull requests and their order, ADR 0241 and ADR 0102's
amendment, the issues opened, closed and touched, the fixture counts, the
questions for the maintainer, and #258 deferred.

Refs #257
Refs #209
Refs #248

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Brings in what landed since 81fba3d, the Web UI among it, so that the
workflows main runs on the pull request find what they build.

Refs #257

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Refs #209

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Refs #248

Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Main is at 2cad18d. This branch is the top of three pull requests that land as one fast-forward: #259 (issues are the work log, ADR 0241), #260 (land.cs checks closing trailers) and #261 (a descriptor's date follows its digests). One file met: docs/adr/README.md, where main had added the section for ADR 0223 and this branch the section for ADR 0241 at the same place. Both are kept, 0223's first. eng/ci.cs merged by itself: main's sdk-pin jobs beside this branch's.

Refs #257
Refs #209
Refs #248

Delegated-by: Emil Okkels Klein <emil@okkels-klein.dk>
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
…entifiers allowed

The maintainer read ADR 0241 on #259 and directed it accepted on 2026-11-11. ModelNamedInTheRecordNotTheCommit, as this ADR restates it, gains accepted-by and accepted-at, its statement unchanged, and the ADR's Status line opens Accepted, as eng/release.cs reads it. Written by his delegate at his word (ADR 0239), on the top of the three pull requests that land together.

Refs #257

Delegated-by: Emil Okkels Klein <emil@okkels-klein.dk>
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
eng/model-names.cs holds ADR 0241's pattern once, with the families in
eng/model-families.txt: a family word, optionally after the product name,
followed by a version, matched regardless of case and only standing alone,
so the hyphenated API identifier and the bare product name pass. Over a
range it checks every commit a pull request or a land/ push adds over
main, merges included, after 2cad18d, the last commit on main that names
a model; each finding names the commit and the line. --message is the
hook's mode, and --fixtures runs thirteen cases under
tests/fixtures/model-names/, with fictional versions. eng/ci.cs runs both
as model-names and model-names-fixtures, and ci.yml's release call skips
the range gate as it skips the others.

Refs #169

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
Before the sign-off, for every author and every tool, the hook runs
eng/model-names.cs --message: a Co-Authored-By: trailer that names a
model becomes the allowed one, a repeat folds, and a name anywhere else
refuses the commit with the line quoted. When the script cannot run, the
hook says so and leaves the message to the gate.

Refs #169

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
.claude/settings.json sets attribution.commit to the co-author trailer
ADR 0241 allows and attribution.pr to the tool's link line, so a Claude
Code session in this repository writes them by default. It is one tool's
way of meeting the rule; AGENTS.md states the rule.

Refs #169

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
AGENTS.md's Every commit says the hook rewrites or refuses and the gate
checks the range, naming no tool's settings file (ADR 0033). docs/rules/
gains a commit-gate section and model-names.md: what it reports, the
three places it is held, how to satisfy it, its failure path.

Refs #169

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>
… layers

Refs #169

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Emil Okkels Klein <emil@okkels-klein.dk>

Hafeok commented Nov 11, 2026

Copy link
Copy Markdown
Owner Author

Head for approval: 402a4e06b15ba2e74aaf2ed1c64c21616d879387. All 72 other checks are green or skipped, including the publish dry run. The one not green is agent review, which waits on the approval. #259–#261 are on main now, so this pull request sits directly on main with its own five commits. It completes no issue, because #169 stays open for the port to the analyzer repository (#65).


Generated by Claude Code

This branch was successfully deployed

1 active deployment
gates — 402a4e06 Deployed Nov 11, 2026 by Hafeok via agent review (judge) #1116
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant