From fd56079fa3eef58a4be47a5432f3ac35b461d30b Mon Sep 17 00:00:00 2001 From: forrestlinfeng Date: Mon, 26 Oct 2026 10:48:10 +0800 Subject: [PATCH] Read "1 failed, 0 errors" as a failure and a question as no correction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two misreadings, found while porting this logic to the Codex and WorkBuddy plugins: - verificationFailed dropped every output line holding a zero count, so `Tests: 1 failed, 0 errors` lost its failure with the line and read as a pass whenever the exit code was gone (output piped through `tail`). Only the zero counts themselves are dropped now. - looksLikeCorrection took `不行吗?`, `这样不对吧` or `不对吧。` for a correction, which revised a reuse report and dropped a valid distillation candidate. `不行` and `不对` no longer count when what follows asks for an opinion (吗/嘛/么, a question mark, or a closing 吧). Co-Authored-By: Claude Opus 5.5 --- src/dissatisfaction.js | 9 +++++---- src/verification.js | 10 ++++------ test/feedback-label.test.js | 8 ++++++++ test/verification.test.js | 5 +++++ 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/dissatisfaction.js b/src/dissatisfaction.js index 9282f01..d009ce2 100644 --- a/src/dissatisfaction.js +++ b/src/dissatisfaction.js @@ -6,11 +6,12 @@ // a report of some other error — must not revise a verdict, because the Hub // counts every report and there is no way to take one back. // -// `X不X` questions are the trap this has to survive: `行不行` and `对不对` are -// requests for an opinion and contain `不行` and `不对` verbatim. +// Questions are the trap this has to survive: `行不行`, `对不对`, `不行吗` and +// a closing `不对吧` ask for an opinion and contain `不行` and `不对` verbatim. +const ASKS_FOR_OPINION = /\s*(?:[吗嘛么]|吧?\s*[??]|吧\s*[。.!!~~]*\s*$)/; const CORRECTION_PATTERNS = [ - /(? !ZERO_COUNT.test(line)) - .join('\n'); + const evidence = textOf(result).replace(ZERO_COUNT, ''); return detectSignals(evidence).some((signal) => FAILURE_SIGNALS.has(signal)); } diff --git a/test/feedback-label.test.js b/test/feedback-label.test.js index 5855ab1..49b28b2 100644 --- a/test/feedback-label.test.js +++ b/test/feedback-label.test.js @@ -15,6 +15,14 @@ test('a correction wins over politeness', () => { assert.equal(feedbackLabelOf("thanks, but it still doesn't work"), 'correction'); }); +test('a question asking whether it is wrong is not a correction', () => { + for (const text of ['不行吗?', '这样不对吧', '不对吧。', '这样不行吗', '这样不对吧?']) assert.equal(feedbackLabelOf(text), null, text); +}); + +test('a plain statement that it is wrong still is', () => { + for (const text of ['这样不对', '不行,还是报错', '不对吧,你再看看', '这样不行!']) assert.equal(feedbackLabelOf(text), 'correction', text); +}); + test('a new request carries no label', () => { for (const text of ['now add a logout button', '这个行不行?', '', undefined]) assert.equal(feedbackLabelOf(text), null, String(text)); }); diff --git a/test/verification.test.js b/test/verification.test.js index 658432b..5c4d2d5 100644 --- a/test/verification.test.js +++ b/test/verification.test.js @@ -25,6 +25,11 @@ test('failure output fails it even when bash reported success', () => { assert.equal(verificationFailed(output("ℹ pass 0\nℹ fail 1\n\n✖ failing tests:\n\ntest at test:1:1\n✖ test (59.9ms)\n 'test failed'\n")), true); }); +test('a zero count beside a failure does not hide it', () => { + assert.equal(verificationFailed(output('Tests: 1 failed, 0 errors')), true); + assert.equal(verificationFailed(output('failures: 0, errors: 2 — test failed')), true); +}); + test('a passing summary that counts zero failures passes', () => { assert.equal(verificationFailed(output('ℹ tests 78\nℹ pass 78\nℹ fail 0')), false); assert.equal(verificationFailed(output('Tests: 0 failed, 12 passed')), false);