Skip to content

attribution: a switch that turns codeaf's signing off (CODEAF_ATTRIBUTION) - #2537

Merged
AbirAbbas merged 4 commits into
devfrom
attribution-off
Nov 9, 2026
Merged

AbirAbbas merged 4 commits into
devfrom
attribution-off

Conversation

@AbirAbbas

Copy link
Copy Markdown
Collaborator

Why

People keep asking how to stop codeaf from adding Assisted-by: CodeAF / Co-Authored-By: CodeAF to their commits. Since #1412 there has been no way to: CODEAF_ATTRIBUTION and the attribution row were retired and only printed a "gone" warning. I checked this live on stable code before the change. CODEAF_ATTRIBUTION=0, =false and "attribution": false were each ignored, and both trailers still landed.

This brings the switch back. Signing stays on by default. Turning it off removes every mark codeaf adds. It can be found in /settings, the in-binary manual, docs/GUIDE.md and the headless env table, but nothing advertises it up front (no README section, first-run page or launch notice).

What changes

  • Setting: attribution row (General tab of /settings, shown as "sign commits, pull requests and issues"), env CODEAF_ATTRIBUTION. It resolves like attribution.model: a non-empty variable wins, a malformed one reads as on, then the profile row. A profile that still holds "attribution": false from before attribution: always sign, and name only the bare model #1412 is obeyed again.
  • Off means no marks anywhere:
    • The chat belt and every leaf-loop contract (do/run/exec/subharness doors) carry a one-sentence AttributionOffLaw instead of the attribution law. Models are told not to add trailers or "drafted with" footers of their own.
    • gitSignature gains an off state, and its zero value still signs. So task landings, kept work, WIP checkpoints and come-home commits stay unsigned.
    • codeaf do / codeaf run skip end-of-run worker-commit signing. Program folders persist unsigned, so a recovered run honours it.
  • Never strips: the harness never removes lines a person or model already wrote. A CONTRIBUTING ban still wins with the switch on.
  • Not self-service: the model cannot change attribution. It's guarded like attribution.model.
  • Cleanup: the retired-row note machinery, whose only entry was attribution, is removed.
  • Separate commit: registers CODEAF_RELAY_ADMIN_KEY as an operator pin. Hosted relay storage is off until an account is approved #2509 added the variable without registering it, so internal/config's env-completeness law fails on dev.

Validation contract

  1. Nothing set → identical to today: both trailers, and the law on the belt and in the leaf contract.
  2. CODEAF_ATTRIBUTION=off|0|false:
    • harness commits carry no trailers, and SignRunCommits leaves commits and hashes untouched;
    • the belt and the leaf prompt carry AttributionOffLaw and none of the trailer or footer constants.
  3. Profile "attribution": false (written by the /settings row) → same as 2; true restores 1.
  4. The env beats the profile both ways; a malformed env value reads as on.
  5. change_setting refuses attribution with the signature guard.
  6. Attribution on + attribution.model off → bare Assisted-by: CodeAF, as today.
  7. A CONTRIBUTING ban still yields no trailers.
  8. Neither the key nor the env var produces an unread-key or retired-row warning.
  9. Zero values (session.Config{}, gitSignature{}, a Linear with no setter) still sign.
  10. A program folder ordered while off finishes with an unsigned commit; folder JSON without the field still signs.
  11. The manual probes reach the page that explains the switch: "how do I remove Co-Authored-By CodeAF from my commits", "turn off attribution", "stop codeaf signing my commits", and three more.

Tests for each item are in internal/config, internal/exec, internal/session (attribution, run-commit signing, land-run-tree, program folder), cmd/codeaf (applyV3Governance wiring, the do engine contract with CODEAF_ATTRIBUTION=off), internal/tui3 (settings row) and internal/manual (probes).

Checks run

  • make pr-ready (light gate + fresh tests for the touched packages): exit 0. tui3, cmd/codeaf, config, exec, manual and run were green apart from flakes that passed on retry. In internal/session, TestSealedTreeCarriesTaskHistory, TestSealedTreeCarriesTheSessionTruth and TestUserBashChangesReachTheTurnEndSnapshot also fail on the dev base on this machine; two other session tests were flaky.
  • Focused internal/session attribution/sign/landing runs: green on three of four runs. One run that overlapped another heavy job on the laptop failed, and its failing test was not captured.

🤖 Generated with Claude Code

AbirAbbas and others added 4 commits November 9, 2026 10:39
The relay-admin tool reads CODEAF_RELAY_ADMIN_KEY for its seed file, but the
variable was never registered, so internal/config's law that every CODEAF_*
variable read in source is a settings row or an operator pin fails on dev.
It names a file for a standalone operator tool, so it is plumbing like
CODEAF_RELAY beside it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since #1412 codeaf signed every commit, pull request, issue and comment it
wrote, and CODEAF_ATTRIBUTION or a profile's `attribution: false` only
produced a "gone" warning. People keep asking how to turn the marks off, so
the switch comes back, on by default.

`attribution` (CODEAF_ATTRIBUTION) is a settings row again, beside
`attribution.model`, resolved the same way: a non-empty variable wins, a
malformed one reads as on, then the profile row. Off means codeaf adds no
marks anywhere:

- the chat belt and every leaf-loop contract carry a one-sentence
  AttributionOffLaw instead of the attribution law, so a model is told not to
  add trailers or footers of its own;
- gitSignature gains an off state (its zero value still signs), so task
  landings, kept work, WIP checkpoints and come-home commits stay unsigned;
- `codeaf do` / `codeaf run` skip end-of-run worker-commit signing, and a
  program folder persists `unsigned` so a recovered run honours it too.

The harness never strips lines already written, a CONTRIBUTING ban still
wins with the switch on, and the model cannot change the row (it is guarded
like attribution.model). The retired-row note machinery, whose only entry was
`attribution`, is removed. The chat manual's signing sections now explain the
switch under the words people search for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…able

GUIDE.md gains a short subsection under "Hand work to tasks" naming the marks
codeaf adds and how to turn them off (`/settings` → attribution,
CODEAF_ATTRIBUTION=off, CODEAF_ATTRIBUTION_MODEL=off for the model name only,
CONTRIBUTING bans). HEADLESS.md's environment table gains CODEAF_ATTRIBUTION.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AbirAbbas
AbirAbbas merged commit d2cd9be into dev Nov 9, 2026
9 checks passed
@AbirAbbas
AbirAbbas deleted the attribution-off branch November 9, 2026 16:18
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