fix(approval): a trailer with a blank or padded name is refused

Review finding 8420915b.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-13 14:40:10 +02:00
commit 1621352e67
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
2 changed files with 28 additions and 2 deletions

View file

@ -49,6 +49,10 @@ const REFUSED = [
['a value without <email>', 'Co-Authored-By: Claude Opus 5.5'],
['a non-Co-Authored-By key', 'Signed-off-by: Claude Opus 5.5 <noreply@anthropic.com>'],
['the unfilled {model} placeholder', 'Co-Authored-By: Claude {model} <noreply@anthropic.com>'],
['an empty {model} (two spaces before the address)', 'Co-Authored-By: Claude <noreply@anthropic.com>'],
['a name of three spaces', 'Co-Authored-By: <noreply@anthropic.com>'],
['two spaces after the colon', 'Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>'],
['two spaces inside the name', 'Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>'],
];
for (const [name, value] of REFUSED) {
@ -66,6 +70,25 @@ for (const [name, value] of REFUSED) {
});
}
// Guard rows: these must stay accepted (review 8420915b tightened the name).
const ACCEPTED = [
['the session trailer', TRAILER],
['a name with a parenthesis', 'Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>'],
];
for (const [name, value] of ACCEPTED) {
test(`accepted and committed as the last line: ${name}`, () => {
const { d, brief } = artifactRepo({ prefix: 'artifact-trailer-', project: '2026-10-12-trailer' });
try {
const r = run(['--store', 'local', '--artifact', brief, '--message', 'x', '--trailer', value], d);
assert.equal(r.status, 0, r.stdout + r.stderr);
assert.equal(JSON.parse(r.stdout).committed, true);
const body = git(d, 'log', '-1', '--format=%B').stdout.trimEnd().split('\n');
assert.equal(body[body.length - 1], value, 'the trailer is the last line of the message');
} finally { rmSync(d, { recursive: true, force: true }); }
});
}
test('a call without a trailer exits 1 with HEAD unchanged', () => {
const { d, brief } = artifactRepo({ prefix: 'artifact-trailer-', project: '2026-10-12-trailer' });
try {