Put the siGit Code version in the commit trailer
The co-author line now reads "siGit Code v1.5.10 <noreply@sigit.si>" rather than just the name. Which model wrote a commit changes from one session to the next and says little about the tool, while the harness version does. GitHub matches co-authors by address, so the credit still shows up. The trailer is built from CARGO_PKG_VERSION, and the system prompt spells out the same text with concat!. The existing test keeps the two matched. The safety net that amends a missing trailer still accepts any "Co-Authored-By: siGit Code" line, so a commit carrying the old, unversioned trailer doesn't get a second one. Closes #75
Seto Elkahfi committed
Sep 27, 2026 at 09:17 UTC
21b18a18cb0d360fb46c957b1165b1c473db78c3
3 files changed
+77
-6
CHANGELOG.md
+9
@@ -14,6 +14,15 @@
14
from the first user message — and a request may filter on `cwd` so one
15
project is never offered another's threads. Threads saved before this have no
16
sidecar and are not listed; they still reopen by id through `session/load`
17
+
18
+### Changed
19
+
20
+- **The commit trailer names the siGit Code version.** Commits siGit Code
21
+ makes now end with `Co-Authored-By: siGit Code v<version> <noreply@sigit.si>`
22
+ instead of the bare name. The model changes from session to session; the
23
+ version tells you which build of the agent wrote the commit. GitHub still
24
+ credits the co-author, since it matches on the address. A commit that
25
+ already carries a siGit Code trailer from an older version is left alone.
26
27
28
## 1.5.10
src/main.rs
+10
-3
@@ -99,7 +99,8 @@ use tracing_subscriber::{EnvFilter, fmt as tracing_fmt};
99
#[cfg(unix)]
100
use std::os::unix::io::{AsRawFd, FromRawFd};
101
102
-const SYSTEM_PROMPT: &str = "\
102
+const SYSTEM_PROMPT: &str = concat!(
103
+ "\
104
Your name is siGit — lowercase 's', uppercase 'G', no spaces. \
105
Not 'SiGit', not 'Sigit'. Only say your name if the user asks who you are.
106
@@ -155,7 +156,12 @@ Git operations — always use run_command:
156
- if a clone or init fails, check the error, fix the cause (wrong path, missing \
157
directory, permissions), and retry
158
- when you create a commit, always end the commit message with a blank line and \
158
- then this trailer on its own line: Co-Authored-By: siGit Code <noreply@sigit.si> \
159
+ then this trailer on its own line: ",
160
+ // Same text as tools::COMMIT_CO_AUTHOR_TRAILER; concat! takes only
161
+ // literals, so it is spelled out here and a test keeps the two in step.
162
+ "Co-Authored-By: siGit Code v",
163
+ env!("CARGO_PKG_VERSION"),
164
+ " <noreply@sigit.si> \
165
— GitHub reads that exact format and credits siGit as co-author. If a commit \
166
lands without it, siGit Code amends the trailer in automatically and the tool \
167
output says so; do not amend again yourself.
@@ -228,7 +234,8 @@ force smbCloud-specific advice into the answer. When it is about smbCloud, be \
234
specific and practical.
235
236
Be direct and brief. Write clean, idiomatic code. When debugging, go for the \
231
-root cause, not the symptom. Correct beats clever.";
237
+root cause, not the symptom. Correct beats clever."
238
+);
239
240
/// shorter prompt for models without tool calling (e.g. DeepSeek Coder v1).
241
/// the full [`SYSTEM_PROMPT`] wastes context and confuses them.
src/tools.rs
+58
-3
@@ -2009,9 +2009,16 @@ fn kill_shell_tree(child: &mut std::process::Child) {
2009
/// alongside the human author; `noreply@sigit.si`
2010
/// is the noreply address for the <https://github.com/sigitc> account
2011
/// ("siGit Code"), so the co-author is rendered with that account's avatar
2012
-/// and profile link. The system prompt asks the model to add this itself;
2013
-/// [`ensure_commit_co_author`] is the safety net when it forgets.
2014
-pub const COMMIT_CO_AUTHOR_TRAILER: &str = "Co-Authored-By: siGit Code <noreply@sigit.si>";
2012
+/// and profile link. GitHub matches on the address, so the name is free to
2013
+/// carry the harness version: the model behind a commit changes from one
2014
+/// session to the next, but the version says which siGit Code made it. The
2015
+/// system prompt asks the model to add this itself; [`ensure_commit_co_author`]
2016
+/// is the safety net when it forgets.
2017
+pub const COMMIT_CO_AUTHOR_TRAILER: &str = concat!(
2018
+ "Co-Authored-By: siGit Code v",
2019
+ env!("CARGO_PKG_VERSION"),
2020
+ " <noreply@sigit.si>"
2021
+);
2022
2023
/// Run `git <args>` in `cwd`, returning trimmed stdout on success.
2024
///
@@ -3360,6 +3367,54 @@ mod tests {
3367
let _ = fs::remove_dir_all(&remote);
3368
}
3369
3370
+ #[test]
3371
+ fn co_author_trailer_names_the_harness_version() {
3372
+ assert_eq!(
3373
+ COMMIT_CO_AUTHOR_TRAILER,
3374
+ format!(
3375
+ "Co-Authored-By: siGit Code v{} <noreply@sigit.si>",
3376
+ env!("CARGO_PKG_VERSION")
3377
+ )
3378
+ );
3379
+ }
3380
+
3381
+ #[test]
3382
+ fn run_command_keeps_a_trailer_from_an_older_version() {
3383
+ let dir = init_test_repo("coauthor_older");
3384
+ fs::write(dir.join("file.txt"), "two\n").unwrap();
3385
+ // Same cmd /C constraint as above: the trailer goes in with direct git
3386
+ // args. Commits made before the version was added, or by another
3387
+ // release, already credit siGit Code and must not get a second line.
3388
+ test_git(&dir, &["add", "file.txt"]);
3389
+ test_git(
3390
+ &dir,
3391
+ &[
3392
+ "commit",
3393
+ "-q",
3394
+ "-m",
3395
+ "Update file\n\nCo-Authored-By: siGit Code <noreply@sigit.si>",
3396
+ ],
3397
+ );
3398
+ let args = serde_json::json!({
3399
+ "command": "git commit --amend --no-edit",
3400
+ "cwd": dir.display().to_string(),
3401
+ })
3402
+ .to_string();
3403
+
3404
+ let result = exec_run_command(&args, None);
3405
+ assert!(
3406
+ !result.contains("[siGit Code]"),
3407
+ "no amend expected: {result}"
3408
+ );
3409
+ let message = git_stdout(&dir, &["log", "-1", "--format=%B"]).unwrap();
3410
+ assert_eq!(
3411
+ message.matches("Co-Authored-By: siGit Code").count(),
3412
+ 1,
3413
+ "trailer must not be duplicated: {message:?}"
3414
+ );
3415
+ let _ = fs::remove_dir_all(&dir);
3416
+ }
3417
+
3418
#[test]
3419
fn test_run_command_failure() {
3420
#[cfg(unix)]