appendCommitCoAuthorNote
appendCommitCoAuthorNote(
systemPrompt,coAuthor?,modelIdentity?,filesystem?):string
Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/utils/systemPromptNotes.ts:165
GS2-35/EXT-83: append the commit-writing rules to the composed code-mode system prompt.
Gaunt Sloth has no dedicated git-commit tool — the agent commits by calling
run_shell_command with git commit, composing the message (including any trailer) itself. That
leaves three things it must be told, and all three live here because all three are about
committing:
- WHO the co-author is. Left unguided, models emit their own model name from trained habit,
which is factually wrong: the commit was produced by Gaunt Sloth, not by the model. The note
states the exact trailer to emit. EXT-83 — rather than enumerate model names not to write (a
denylist is stale the day a new vendor ships, and an enumeration beside a catch-all teaches the
model that the list is the rule), the correct name is SUPPLIED: the resolved
ResolvedModelIdentity decorates the DEFAULT name as
Gaunt Sloth (provider:model), so the real model is named while the authorship stays Gaunt Sloth’s. - HOW the message reaches git. A commit message passed inline in a double-quoted shell argument is EXPANDED BY THE SHELL before git runs, so a message that quotes code the way ordinary technical prose does is executed as a command. The note states that mechanism rather than merely forbidding the construct — naming a construct without its mechanism has been measured not to work. A file path carries no shell metacharacters, so the file form removes the failure mode instead of asking the model to avoid it.
- HOW the change is staged. Rule 2 leaves the message file untracked in the working tree at
git addtime, so an unscopedgit add -A/git add ./git commit -asweeps it into the commit and onto the pull request. The note states that mechanism, steers staging to named paths, and allows the last resort for a change too large to enumerate only once the message file is out of the tree — an escape hatch that kept the file would reintroduce exactly the defect the rule closes. It binds atgit addtime, MID-flow while the model is still acting, because the tidy-up step at the end is the one that gets dropped. The scratchpad sentence beside it names NO path: the write tool refuses any path outside the working folder at every approval mode, so naming one buys a refused call. EXT-97 is the interim mitigation; the mechanism that owns the file end to end is EXT-93.
The clause that names the writing tool is gated on filesystem (EXT-84), through the one
shared derivation isWriteFileToolRegistered — the same interpretation that decides which
tools are actually registered. Naming an unregistered tool while forbidding both the shell
fallback and the inline flag leaves the model NO compliant path, and its likeliest recovery is
the inline form this note exists to prevent. So when the write tool is registered the note names
it literally (the overwhelmingly common case, and a literal name is what makes the instruction
actionable); when it is not, the note names no tool, keeps both prohibitions and the file form,
and supplies the compliant path that remains: do not commit, and hand the message back to the
user. That branch states no availability claim of its own — registering filesystem tools is the
agent’s decision, made from the same filesystem value, so a note asserting “you have no
file-writing tool” could be flatly false.
The note’s prose carries no backtick and no other markup — including no angle-bracket
placeholder: it is the one piece of guidance whose subject is how to write a commit message, so
quoting its own examples in backticks would demonstrate the exact style rule 2 exists to stop, and
an angle-bracket placeholder copied literally is itself a shell input redirect. The <email> of
the trailer line is the exception the RFC form requires, and is scoped out of the scan.
The identity is config-driven (commit.coAuthor in import(‘#src/config/types.js’).GthConfig).
Each field falls back INDEPENDENTLY to the Gaunt Sloth account
(DEFAULT_COMMIT_CO_AUTHOR_NAME / DEFAULT_COMMIT_CO_AUTHOR_EMAIL) — so a partial
override (name only, or a config that bypassed the loader) still yields a complete trailer, and a
fully-absent config yields the default account. Blank/whitespace values are treated as unset. An
EXPLICITLY CONFIGURED name is emitted verbatim, with no identity spliced in — the user asked for
that string; the identity decorates only the default. An unresolvable identity (undefined) falls
back to the plain default name, never to a placeholder.
Backend-agnostic: composed through the shared code path, so any backend injects it (the
git-commit capability rides on run_shell_command, exposed in code mode). Returns the note alone
when there is no base prompt.
Parameters
Section titled “Parameters”systemPrompt
Section titled “systemPrompt”string | undefined
coAuthor?
Section titled “coAuthor?”modelIdentity?
Section titled “modelIdentity?”filesystem?
Section titled “filesystem?”Returns
Section titled “Returns”string