You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(commit): let an agent author stand in for its co-author #402
A project can require each agent commit to name its agent in a Co-authored-by trailer (required = "agents" on the coauthors variable). Some callers make the agent harness the commit's git author instead, for work that no person asked for. The author line already names the agent, so a trailer repeats it. Today devkit commit refuses that commit: devkit commit needs --coauthor=... (required for agents).
Make a commit whose git author is the agent satisfy a co-author requirement for agents. A commit with a person as the author still needs --coauthor as today. The other agent-only requirements, such as proof and done_when, stay as they are.
Done when
An agent caller whose git author is set to the agent (GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL or user.name/user.email) runs devkit commit without --coauthor in a project with coauthors required for agents, and the commit succeeds with no Co-authored-by trailer (proof: test)
An agent caller whose git author is a person still gets the --coauthor refusal (proof: test)
The docs for template variables say how an agent author meets a co-author requirement (proof: diff)
Stop and ask if
Recognizing an agent author needs a new config key: ask before adding it.
Context
Blocked by: none
Found by AbysmalBiscuit/workcell#268, whose runs can make the harness the commit author. That ticket waits on this one.
Decide how devkit recognizes an agent author (for example a known agent identity list, or the caller's own declared identity) and say which in the PR.
stage 1: implementing. An agent author satisfies a co-author requirement for agents. Session 01a14bcd-7bc3-7661-a2da-ca49c55f3052.
stage 2: review roles deferred until midnight UTC (box Claude quota spent). Implementer commit 5fb255e. Opening the PR with local checks next. Session 01a14bcd-7bc3-7661-a2da-ca49c55f3052.
ask-1 answered: hold at stage 2. Senior reviews PR feat(commit): let an agent author stand #412 at 5fb255e on the laptop. No push until the rows land on issue 402. Session 01a14bcd-7bc3-7661-a2da-ca49c55f3052.
stage 2: still holding for the laptop review of PR feat(commit): let an agent author stand #412 at 5fb255e. Next round runs review roles as herdr Codex workers. No push meanwhile. Session 01a14bcd-7bc3-7661-a2da-ca49c55f3052.
stage 5: round 1 of 3. Laptop review of PR feat(commit): let an agent author stand #412 at 5fb255e has 4 majors, 2 minors, 1 nit. Receiving those rows, then fixing them. Session 01a14bcd-7bc3-7661-a2da-ca49c55f3052.
stage 5: round 2 of 3. Head c4a07b8 fixes the round 1 rows. Starting Codex code-reviewer and verifier. Session 01a14bcd-7bc3-7661-a2da-ca49c55f3052.
stage 5: round 3 of 5. Head fe98aa7 keeps required=always. Starting Codex code-reviewer and verifier. Session 01a14bcd-7bc3-7661-a2da-ca49c55f3052.
#412#412
Head: 5fb255e
Reviews: deferred to senior (box Claude quota spent)
Local checks on that head:
cargo nextest run --workspace --all-features --locked --no-fail-fast: exit 100. 4283 tests, 4281 passed, 2 failed. Failures, same panic on origin/main at e3ffce0:
devkit::issue_create without_a_kind_only_the_detected_trackers_table_is_checked at tests/issue_create.rs:691: [ticket.fields.linear.team] has no type and where.
devkit::ticket_fields both_tables_without_a_kind_use_the_detected_trackers at tests/ticket_fields.rs:40: the same error.
The branch does not touch those files. Confirm them on the laptop.
devrun task fmt-check: skipped. This box has no nightly toolchain.
No review role ran. It is 21:51 UTC, before midnight. Code review and verification are yours on the laptop. Post the rows on this issue. I will receive them as the reviewers' findings.
The PR is ready, not a draft. I will not merge it.
Rule: an agent author is the commit author devkit commit would record, and that email is a GitHub bot address (<digits>+<name>[bot]@users.noreply.github.com). GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL win when both are set. Otherwise user.name and user.email. That address is the caller's own declared identity, the form a harness uses when it authors the commit. No new config key and no identity list. A person address, a blank half, a human caller, and a project's own commit_message still need --coauthor. proof and done_when are unchanged.
Commit: 5fb255e feat(commit): let an agent author stand. Rebased onto origin/main (already current) and published. No force-push. No herdr test panes left open.
Question for senior: stage 2 cannot end, and review roles cannot start until midnight UTC.
The stop hook refuses to end this turn while the run is at gate_work. It is 21:55 UTC. Your extra instructions say not to start code-reviewer, verifier, receiver or pr-reviewer until midnight UTC, then only as Claude opus workers.
Senior answer to ask 402-1: the question is the open ask, so stop at gate_work and wait. Round 1 review of PR #412 at 5fb255e is running on the laptop, with nightly fmt and the full nextest run. I post the rows here when done.
Senior review, PR #412 round 1 at 5fb255e (Codex reviewer, laptop). Verdict: FIX. 4 majors, 2 minors, 1 nit. Repro script and logs: ~/senior-files/devkit-402/ (revdk412-r1-*). The 207 nextest failures also fail on main in the reviewer's environment; none are PR-only.
Senior decision on row 6: make it in scope. Recognize an agent author by the GitHub bot form plus a built-in list of the harness identities workcell uses: Claude noreply@anthropic.com and Codex noreply@openai.com. Use no new config key. Parse the bot form strictly (row 5). Add entry-point tests for Grok, Claude and Codex authors.
PR #412 at 5fb255e95ee7a598f1e07a54f910287b96f6ff17 needs changes. This review found four major defects, two minor defects, and one formatting nit.
The contract is issue #402, its comments, and the supplied review brief. Workcell #268 supplies the downstream requirements.
Run python3 /tmp/revdk412-r1-cases.py /tmp/revdk412-r1-devkit to reproduce the runtime findings. The script uses disposable repositories and the saved PR binary. The recorded results contain each exit result, recorded author, and commit message. The Claude and Codex expectations describe downstream coverage beyond the chosen GitHub bot rule.
#
file:line
severity
finding
evidence
suggested fix
1
crates/devkit-ports/src/templates.rs:236
major
Amendment checks the prospective author, although Git retains the existing commit's author. This bypasses the requirement for a person author.
Case amend person commit with bot environment succeeds without a trailer. The recorded author remains Prior person <person@example.invalid>. The reverse case refuses an amendment whose retained author is the bot.
Resolve the retained author for --amend before rendering. Pass the commit selection into that decision. Test both amendment cases through devkit commit.
2
crates/devkit-git/src/backend.rs:371
major
Reading only user.name and user.email misses Git's author.name and author.email overrides. A person author can pass the bot exemption.
Case author.email overrides bot user.email clears both author environment variables. It configures bot user.email and person author.email. The commit succeeds without a trailer and records Person <person@example.invalid>. The reverse configuration wrongly refuses the bot.
Resolve the effective Git author, including author.*, before granting the exemption. Preserve the intended refusal for incomplete environment identities explicitly. Add both override cases.
3
crates/devkit-ports/src/templates.rs:214
major
The exemption bypasses a project's custom commit template. The condition checks [templates].commit_message but misses [templates.custom.commit_message], which takes precedence.
Case custom template override declares a custom template that reads coauthors, with coauthors required for agents. The bot commit succeeds without --coauthor. The recorded message contains only fix: example. This contradicts the documented custom-template exception.
Check the resolved template and both override forms. Apply the exemption only to the unchanged built-in template. Add a custom-template refusal test.
4
crates/devkit-ports/src/templates.rs:260
major
Removing trailers from the complete rendered message deletes caller-supplied body text. The filter removes matching lines anywhere in the body.
Case retain supplied body supplies Before\n\nCo-authored-by: Ada <ada@example.invalid>\n\nAfter. The recorded body contains only Before\n\nAfter. The supplied line is an interior body line, followed by another paragraph.
Satisfy the requirement without inserting a synthetic co-author into the rendered message. Suppress only the generated trailer. Test exact preservation of the supplied body.
5
crates/devkit-ports/src/templates.rs:252
minor
The classifier accepts more than the stated <digits>+<name>[bot]@users.noreply.github.com form. Substring matching accepts absent numeric IDs and a marker inside a name.
Cases no digits, nonnumeric id, marker in middle, and empty name all succeed without trailers. Examples include grok[bot]@users.noreply.github.com and 123+grok[bot]human@users.noreply.github.com.
Parse the numeric prefix, separator, nonempty name, terminal [bot], and domain. Keep explicit tests for accepted case normalization and surrounding spaces.
6
crates/devkit-ports/src/templates.rs:252
minor
The chosen rule leaves the Claude and Codex authors unsupported. Workcell's harness-author requirement therefore remains incomplete.
Cases Claude author and Codex author both receive the exact agent --coauthor refusal. Their emails are noreply@anthropic.com and noreply@openai.com. Grok's specified bot address succeeds. These identities also appear in this checkout's coauthors description.
Define support for the harness identities workcell uses and add entry-point tests. The issue permits an identity-list decision. If recognition needs a new config key, stop and ask before adding it, as the issue requires.
The required nightly formatting check fails on both changed files.
The formatting log shows the doc-comment wrap and assertion rewrite. The command exits 1.
Apply nightly rustfmt to the changed files and run the formatting check again.
The first Done when item passes for Grok through both complete GIT_AUTHOR_* values and user.* configuration. Both commits omit the trailer. Claude and Codex remain the minor design gap above. The second item passes for ordinary person identities, but findings 1 and 2 expose bypasses. The third item has documentation changes. Findings 3 and 5 identify behavior that contradicts those descriptions.
The adversarial script ran 30 cases through devkit commit. Incomplete author environment pairs and a person environment identity over bot user.* configuration retain the exact agent refusal. Missing [bot] and another domain also retain that refusal. Uppercase domains, surrounding spaces, and a + inside the name succeed. Uppercase [BOT] does not succeed. A human caller with an agents-only requirement succeeds as before. A human caller with an always-required co-author still receives a refusal. The CLI has no --author option. An explicit --coauthor keeps its trailer. A project override under [templates].commit_message still refuses the omitted co-author.
The script also confirms that a template reading proof and done_when still refuses both missing agent requirements. The changed code does not alter their requirement checks. The new VersionControl::author method has one production call site, in the commit-template logic. Existing user_email callers retain their implementation. The new integration tests use the real CLI, temporary directories, and per-process environment changes. Source inspection found no new Windows-specific dependency; this review ran on Linux.
The required checks used the prescribed isolated HOME, TMPDIR, Cargo homes, and shared target directory. Commands used --manifest-path from /tmp. The local hook required the task wrapper, but that wrapper refused the repository-free export. The checks then used Cargo directly with the explicit manifest.
Both manager-reported failures reproduce on the actual main export: issue_create without_a_kind_only_the_detected_trackers_table_is_checked and ticket_fields both_tables_without_a_kind_use_the_detected_trackers. The other 205 failures also reproduce on main. The linked failure table names each one.
The prescribed TMPDIR lies below the exported devkit.toml. Configuration-discovery tests inherit that file. For example, resolve_errors_when_no_config_found resolves the export's project config, and a_checkout_with_no_config_stays_silent prints its tasks. This explains additional environment-related failures without assigning them to this PR.
The first main attempt reused PR artifacts from the shared target. Its test list included PR-only tests. The review discarded that comparison, refreshed source timestamps in the main export, and rebuilt with the compiler wrapper disabled. The valid main run contains the expected 4,276 tests and no PR-only commit tests.
The review removed the isolated exports. The shared target directory, saved PR binary, reproduction scripts, and logs remain available.
#412#412
Head: fe98aa7
Reviews: code-reviewer Codex (code-reviewer-00cf), verifier Codex (verifier-1057). No pr-reviewer: the repo lists no review skill. Receiver not spawned: the only finding was dropped.
Local checks on that head:
cargo nextest run --workspace --all-features --locked --no-fail-fast: exit 100. 4309 tests, 4307 passed, 2 failed. Same two as origin/main at e3ffce0: devkit::issue_create without_a_kind_only_the_detected_trackers_table_is_checked, devkit::ticket_fields both_tables_without_a_kind_use_the_detected_trackers.
devrun task fmt-check: skipped. This box has no nightly toolchain.
Round 1 was the laptop Codex review of 5fb255e. All 7 rows applied in c4a07b8. Round 2 Codex review of c4a07b8 found that the exemption also covered required = "always". Fixed in 4e18b6d. Author lookup docs landed in fe98aa7.
Round 3 found one low finding, the stale PR body. check_review.py dropped it because it cites no file. I rewrote the PR body from the pr_body template so it names the strict bot form, Claude noreply@anthropic.com, Codex noreply@openai.com, author.* before user.*, and the required = "agents" limit.
Verifier: all 3 Done when items verified. 52 commit tests passed.
I will not merge. Laptop CI, Windows, and the merge stay with you.
Senior handover: a local senior session is taking over PR #412. It will rebase #412 onto main after #417 merges, run the gate, and merge it. Please make no further pushes to the branch.
Activity
AbysmalBiscuit commentedon Oct 17, 2026
Workcell progress
AbysmalBiscuit commentedon Oct 17, 2026
#412 #412
Head: 5fb255e
Reviews: deferred to senior (box Claude quota spent)
Local checks on that head:
cargo nextest run --workspace --all-features --locked --no-fail-fast: exit 100. 4283 tests, 4281 passed, 2 failed. Failures, same panic on origin/main at e3ffce0:devkit::issue_create without_a_kind_only_the_detected_trackers_table_is_checkedat tests/issue_create.rs:691:[ticket.fields.linear.team]has notypeandwhere.devkit::ticket_fields both_tables_without_a_kind_use_the_detected_trackersat tests/ticket_fields.rs:40: the same error.The branch does not touch those files. Confirm them on the laptop.
cargo test --workspace --doc: exit 0.cargo clippy --workspace --all-targets -- -D warnings: exit 0.devrun task fmt-check: skipped. This box has no nightly toolchain.No review role ran. It is 21:51 UTC, before midnight. Code review and verification are yours on the laptop. Post the rows on this issue. I will receive them as the reviewers' findings.
The PR is ready, not a draft. I will not merge it.
Rule: an agent author is the commit author
devkit commitwould record, and that email is a GitHub bot address (<digits>+<name>[bot]@users.noreply.github.com).GIT_AUTHOR_NAMEandGIT_AUTHOR_EMAILwin when both are set. Otherwiseuser.nameanduser.email. That address is the caller's own declared identity, the form a harness uses when it authors the commit. No new config key and no identity list. A person address, a blank half, a human caller, and a project's owncommit_messagestill need--coauthor.proofanddone_whenare unchanged.Commit: 5fb255e feat(commit): let an agent author stand. Rebased onto origin/main (already current) and published. No force-push. No herdr test panes left open.
Session: 01a14bcd-7bc3-7661-a2da-ca49c55f3052
AbysmalBiscuit commentedon Oct 17, 2026
Question for senior: stage 2 cannot end, and review roles cannot start until midnight UTC.
The stop hook refuses to end this turn while the run is at gate_work. It is 21:55 UTC. Your extra instructions say not to start code-reviewer, verifier, receiver or pr-reviewer until midnight UTC, then only as Claude opus workers.
PR #412 is open and ready: #412
Head: 5fb255e
Report: #402 (comment)
How should I hold stage 2 until you post the review rows, or until midnight UTC?
Stage asked: gate_work
AbysmalBiscuit commentedon Oct 17, 2026
Senior answer to ask 402-1: the question is the open ask, so stop at gate_work and wait. Round 1 review of PR #412 at 5fb255e is running on the laptop, with nightly fmt and the full nextest run. I post the rows here when done.
AbysmalBiscuit commentedon Oct 17, 2026
Senior review, PR #412 round 1 at 5fb255e (Codex reviewer, laptop). Verdict: FIX. 4 majors, 2 minors, 1 nit. Repro script and logs: ~/senior-files/devkit-402/ (revdk412-r1-*). The 207 nextest failures also fail on main in the reviewer's environment; none are PR-only.
Senior decision on row 6: make it in scope. Recognize an agent author by the GitHub bot form plus a built-in list of the harness identities workcell uses: Claude
noreply@anthropic.comand Codexnoreply@openai.com. Use no new config key. Parse the bot form strictly (row 5). Add entry-point tests for Grok, Claude and Codex authors.PR #412 at
5fb255e95ee7a598f1e07a54f910287b96f6ff17needs changes. This review found four major defects, two minor defects, and one formatting nit.The contract is issue #402, its comments, and the supplied review brief. Workcell #268 supplies the downstream requirements.
Run
python3 /tmp/revdk412-r1-cases.py /tmp/revdk412-r1-devkitto reproduce the runtime findings. The script uses disposable repositories and the saved PR binary. The recorded results contain each exit result, recorded author, and commit message. The Claude and Codex expectations describe downstream coverage beyond the chosen GitHub bot rule.crates/devkit-ports/src/templates.rs:236amend person commit with bot environmentsucceeds without a trailer. The recorded author remainsPrior person <person@example.invalid>. The reverse case refuses an amendment whose retained author is the bot.--amendbefore rendering. Pass the commit selection into that decision. Test both amendment cases throughdevkit commit.crates/devkit-git/src/backend.rs:371user.nameanduser.emailmisses Git'sauthor.nameandauthor.emailoverrides. A person author can pass the bot exemption.author.email overrides bot user.emailclears both author environment variables. It configures botuser.emailand personauthor.email. The commit succeeds without a trailer and recordsPerson <person@example.invalid>. The reverse configuration wrongly refuses the bot.author.*, before granting the exemption. Preserve the intended refusal for incomplete environment identities explicitly. Add both override cases.crates/devkit-ports/src/templates.rs:214[templates].commit_messagebut misses[templates.custom.commit_message], which takes precedence.custom template overridedeclares a custom template that readscoauthors, withcoauthorsrequired for agents. The bot commit succeeds without--coauthor. The recorded message contains onlyfix: example. This contradicts the documented custom-template exception.crates/devkit-ports/src/templates.rs:260retain supplied bodysuppliesBefore\n\nCo-authored-by: Ada <ada@example.invalid>\n\nAfter. The recorded body contains onlyBefore\n\nAfter. The supplied line is an interior body line, followed by another paragraph.crates/devkit-ports/src/templates.rs:252<digits>+<name>[bot]@users.noreply.github.comform. Substring matching accepts absent numeric IDs and a marker inside a name.no digits,nonnumeric id,marker in middle, andempty nameall succeed without trailers. Examples includegrok[bot]@users.noreply.github.comand123+grok[bot]human@users.noreply.github.com.[bot], and domain. Keep explicit tests for accepted case normalization and surrounding spaces.crates/devkit-ports/src/templates.rs:252Claude authorandCodex authorboth receive the exact agent--coauthorrefusal. Their emails arenoreply@anthropic.comandnoreply@openai.com. Grok's specified bot address succeeds. These identities also appear in this checkout'scoauthorsdescription.crates/devkit-vcs/src/lib.rs:292;tests/commit.rs:282The first Done when item passes for Grok through both complete
GIT_AUTHOR_*values anduser.*configuration. Both commits omit the trailer. Claude and Codex remain the minor design gap above. The second item passes for ordinary person identities, but findings 1 and 2 expose bypasses. The third item has documentation changes. Findings 3 and 5 identify behavior that contradicts those descriptions.The adversarial script ran 30 cases through
devkit commit. Incomplete author environment pairs and a person environment identity over botuser.*configuration retain the exact agent refusal. Missing[bot]and another domain also retain that refusal. Uppercase domains, surrounding spaces, and a+inside the name succeed. Uppercase[BOT]does not succeed. A human caller with an agents-only requirement succeeds as before. A human caller with an always-required co-author still receives a refusal. The CLI has no--authoroption. An explicit--coauthorkeeps its trailer. A project override under[templates].commit_messagestill refuses the omitted co-author.The script also confirms that a template reading
proofanddone_whenstill refuses both missing agent requirements. The changed code does not alter their requirement checks. The newVersionControl::authormethod has one production call site, in the commit-template logic. Existinguser_emailcallers retain their implementation. The new integration tests use the real CLI, temporary directories, and per-process environment changes. Source inspection found no new Windows-specific dependency; this review ran on Linux.The required checks used the prescribed isolated
HOME,TMPDIR, Cargo homes, and shared target directory. Commands used--manifest-pathfrom/tmp. The local hook required the task wrapper, but that wrapper refused the repository-free export. The checks then used Cargo directly with the explicit manifest.cargo +nightly fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningsRUSTC_WRAPPERempty.zccachewrapper withmultiple input filenames provided. Initial log.cargo nextest run --workspace --all-features --locked --no-fail-fastcargo test --workspace --docorigin/mainate3ffce0a383d5e21f3b82309eb90b653b0b214f3Both manager-reported failures reproduce on the actual main export:
issue_create without_a_kind_only_the_detected_trackers_table_is_checkedandticket_fields both_tables_without_a_kind_use_the_detected_trackers. The other 205 failures also reproduce on main. The linked failure table names each one.The prescribed
TMPDIRlies below the exporteddevkit.toml. Configuration-discovery tests inherit that file. For example,resolve_errors_when_no_config_foundresolves the export's project config, anda_checkout_with_no_config_stays_silentprints its tasks. This explains additional environment-related failures without assigning them to this PR.The first main attempt reused PR artifacts from the shared target. Its test list included PR-only tests. The review discarded that comparison, refreshed source timestamps in the main export, and rebuilt with the compiler wrapper disabled. The valid main run contains the expected 4,276 tests and no PR-only commit tests.
The review removed the isolated exports. The shared target directory, saved PR binary, reproduction scripts, and logs remain available.
VERDICT: FIX
AbysmalBiscuit commentedon Oct 17, 2026
#412 #412
Head: fe98aa7
Reviews: code-reviewer Codex (code-reviewer-00cf), verifier Codex (verifier-1057). No pr-reviewer: the repo lists no review skill. Receiver not spawned: the only finding was dropped.
Local checks on that head:
cargo nextest run --workspace --all-features --locked --no-fail-fast: exit 100. 4309 tests, 4307 passed, 2 failed. Same two as origin/main at e3ffce0:devkit::issue_create without_a_kind_only_the_detected_trackers_table_is_checked,devkit::ticket_fields both_tables_without_a_kind_use_the_detected_trackers.cargo test --workspace --doc: exit 0.cargo clippy --workspace --all-targets -- -D warnings: exit 0.devrun task fmt-check: skipped. This box has no nightly toolchain.Round 1 was the laptop Codex review of 5fb255e. All 7 rows applied in c4a07b8. Round 2 Codex review of c4a07b8 found that the exemption also covered
required = "always". Fixed in 4e18b6d. Author lookup docs landed in fe98aa7.Round 3 found one low finding, the stale PR body.
check_review.pydropped it because it cites no file. I rewrote the PR body from thepr_bodytemplate so it names the strict bot form, Claudenoreply@anthropic.com, Codexnoreply@openai.com,author.*beforeuser.*, and therequired = "agents"limit.Verifier: all 3 Done when items verified. 52 commit tests passed.
I will not merge. Laptop CI, Windows, and the merge stay with you.
Session: 01a14bcd-7bc3-7661-a2da-ca49c55f3052
AbysmalBiscuit commentedon Oct 18, 2026
Senior handover: a local senior session is taking over PR #412. It will rebase #412 onto main after #417 merges, run the gate, and merge it. Please make no further pushes to the branch.