reviewflow 3.42.2 → 3.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,12 +5,32 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.43.1](https://github.com/DGouron/review-flow/compare/reviewflow-v3.43.0...reviewflow-v3.43.1) (2026-07-15)
9
+
10
+
11
+ ### Fixed
12
+
13
+ * **webhook:** soften the oversized-MR split message tone ([#342](https://github.com/DGouron/review-flow/issues/342)) ([27a967f](https://github.com/DGouron/review-flow/commit/27a967f6e129998e3d6049269770a221ebf0c68f))
14
+
15
+ ## [3.43.0](https://github.com/DGouron/review-flow/compare/reviewflow-v3.42.2...reviewflow-v3.43.0) (2026-07-14)
16
+
17
+
18
+ ### Added
19
+
20
+ * **templates:** add review-advanced and followup-advanced skill templates ([#337](https://github.com/DGouron/review-flow/issues/337)) ([f4aa52e](https://github.com/DGouron/review-flow/commit/f4aa52e77555a13e93492010a8bd165a3bfc6bbd))
21
+
22
+
23
+ ### Fixed
24
+
25
+ * [#339](https://github.com/DGouron/review-flow/issues/339) dashboard loading state stuck after successful fetch ([#340](https://github.com/DGouron/review-flow/issues/340)) ([45bce47](https://github.com/DGouron/review-flow/commit/45bce4789215cb24dd556800932734e3fa6dc0e8))
26
+
8
27
  ## [3.42.2](https://github.com/DGouron/review-flow/compare/reviewflow-v3.42.1...reviewflow-v3.42.2) (2026-07-13)
9
28
 
10
29
 
11
30
  ### Fixed
12
31
 
13
32
  * **claude-invocation:** strip ANSI codes before parsing --bg session id ([#334](https://github.com/DGouron/review-flow/issues/334)) ([88c66e3](https://github.com/DGouron/review-flow/commit/88c66e31b07988b3f275c803722474048e4e82a9))
33
+ * **setup:** write the project review-config shape the review engine actually expects ([#333](https://github.com/DGouron/review-flow/issues/333)) ([34c6c8b](https://github.com/DGouron/review-flow/commit/34c6c8b7cd6478f7aa036aca3a8c750ea8865716))
14
34
 
15
35
  ## [3.42.1](https://github.com/DGouron/review-flow/compare/reviewflow-v3.42.0...reviewflow-v3.42.1) (2026-07-13)
16
36
 
@@ -1046,11 +1046,11 @@
1046
1046
  const response = await fetch(url);
1047
1047
  const data = await response.json();
1048
1048
  currentData.reviewFiles = data.reviews || [];
1049
- updateReviewFilesUI();
1050
1049
  } catch (error) {
1051
1050
  console.error('Error fetching review files:', error);
1052
1051
  } finally {
1053
1052
  setLoadingFlag('reviewFiles', false);
1053
+ updateReviewFilesUI();
1054
1054
  }
1055
1055
  }
1056
1056
 
@@ -1990,11 +1990,11 @@
1990
1990
  currentData.pendingApproval = data.pendingApproval || [];
1991
1991
  currentData.merged = data.merged || [];
1992
1992
  }
1993
- updateMrTrackingUI();
1994
1993
  } catch (error) {
1995
1994
  console.error('Error fetching MR tracking:', error);
1996
1995
  } finally {
1997
1996
  setLoadingFlag('mrTracking', false);
1997
+ updateMrTrackingUI();
1998
1998
  }
1999
1999
  }
2000
2000
 
@@ -1 +1 @@
1
- {"version":3,"file":"guardDiffSize.usecase.d.ts","sourceRoot":"","sources":["../../../../src/modules/platform-integration/usecases/guardDiffSize.usecase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4EAA4E,CAAC;AAE3H,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,UAAU,kBAAkB;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,UAAU,yBAAyB;IACjC,wBAAwB,EAAE,wBAAwB,CAAC;CACpD;AAYD,qBAAa,oBAAqB,YAAW,OAAO,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;IAChF,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,yBAAyB;IAEpE,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,oBAAoB;IAuBxD,OAAO,CAAC,iBAAiB;CAU1B"}
1
+ {"version":3,"file":"guardDiffSize.usecase.d.ts","sourceRoot":"","sources":["../../../../src/modules/platform-integration/usecases/guardDiffSize.usecase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4EAA4E,CAAC;AAE3H,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAEnE,UAAU,kBAAkB;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,UAAU,yBAAyB;IACjC,wBAAwB,EAAE,wBAAwB,CAAC;CACpD;AAeD,qBAAa,oBAAqB,YAAW,OAAO,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;IAChF,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,yBAAyB;IAEpE,OAAO,CAAC,KAAK,EAAE,kBAAkB,GAAG,oBAAoB;IAuBxD,OAAO,CAAC,iBAAiB;CAU1B"}
@@ -1,10 +1,13 @@
1
1
  import { evaluateDiffSizeGate } from '../../../modules/shared-kernel/entities/diffSizeGate/diffSizeGate.js';
2
2
  function buildSplitMessage(countedLines, budget) {
3
- return (`Revue refusée : cette merge request fait ${countedLines} lignes comptées ` +
4
- `(budget ${budget}). Pour faciliter la revue, découpez-la : ` +
3
+ return (`Petite pause avant la revue : cette merge request compte ${countedLines} lignes ` +
4
+ `(budget ${budget}), un peu trop pour une revue de qualité en une seule fois. ` +
5
+ 'Découpée en plus petits morceaux, elle sera revue plus vite, plus finement, ' +
6
+ 'et bien plus simple à corriger si besoin. Une piste pour la découper : ' +
5
7
  '1) séparez les refactorings des nouvelles fonctionnalités, ' +
6
8
  '2) extrayez les changements indépendants dans des MR dédiées, ' +
7
- '3) limitez chaque MR à une seule intention.');
9
+ '3) limitez chaque MR à une seule intention. ' +
10
+ 'Merci pour le travail, hâte de la relire découpée !');
8
11
  }
9
12
  export class GuardDiffSizeUseCase {
10
13
  dependencies;
@@ -1 +1 @@
1
- {"version":3,"file":"guardDiffSize.usecase.js","sourceRoot":"","sources":["../../../../src/modules/platform-integration/usecases/guardDiffSize.usecase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,+DAA+D,CAAC;AAiBrG,SAAS,iBAAiB,CAAC,YAAoB,EAAE,MAAc;IAC7D,OAAO,CACL,4CAA4C,YAAY,mBAAmB;QAC3E,WAAW,MAAM,4CAA4C;QAC7D,6DAA6D;QAC7D,gEAAgE;QAChE,6CAA6C,CAC9C,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,oBAAoB;IACF;IAA7B,YAA6B,YAAuC;QAAvC,iBAAY,GAAZ,YAAY,CAA2B;IAAG,CAAC;IAExE,OAAO,CAAC,KAAyB;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,oBAAoB,CAAC;YAC/D,KAAK;YACL,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QAED,OAAO;YACL,IAAI,EAAE,SAAS;YACf,YAAY;YACZ,MAAM;YACN,OAAO,EAAE,iBAAiB,CAAC,YAAY,EAAE,MAAM,CAAC;SACjD,CAAC;IACJ,CAAC;IAEO,iBAAiB,CAAC,KAAyB;QACjD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,YAAY,CAAC,wBAAwB,CAAC,iBAAiB,CACjE,KAAK,CAAC,iBAAiB,EACvB,KAAK,CAAC,kBAAkB,CACzB,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"guardDiffSize.usecase.js","sourceRoot":"","sources":["../../../../src/modules/platform-integration/usecases/guardDiffSize.usecase.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,+DAA+D,CAAC;AAiBrG,SAAS,iBAAiB,CAAC,YAAoB,EAAE,MAAc;IAC7D,OAAO,CACL,4DAA4D,YAAY,UAAU;QAClF,WAAW,MAAM,8DAA8D;QAC/E,8EAA8E;QAC9E,yEAAyE;QACzE,6DAA6D;QAC7D,gEAAgE;QAChE,8CAA8C;QAC9C,qDAAqD,CACtD,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,oBAAoB;IACF;IAA7B,YAA6B,YAAuC;QAAvC,iBAAY,GAAZ,YAAY,CAA2B;IAAG,CAAC;IAExE,OAAO,CAAC,KAAyB;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,oBAAoB,CAAC;YAC/D,KAAK;YACL,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QAED,OAAO;YACL,IAAI,EAAE,SAAS;YACf,YAAY;YACZ,MAAM;YACN,OAAO,EAAE,iBAAiB,CAAC,YAAY,EAAE,MAAM,CAAC;SACjD,CAAC;IACJ,CAAC;IAEO,iBAAiB,CAAC,KAAyB;QACjD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,YAAY,CAAC,wBAAwB,CAAC,iBAAiB,CACjE,KAAK,CAAC,iBAAiB,EACvB,KAAK,CAAC,kBAAkB,CACzB,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Regression test for issue #339 — Priority Lanes and Completed Reviews stuck
3
+ * on "Loading..." forever.
4
+ *
5
+ * Structural assertions on src/dashboard/index.html via raw-string + regex,
6
+ * matching the precedent of dashboardLayout.test.ts (no jsdom dependency).
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=dashboardLoadingRace.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardLoadingRace.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/units/dashboard/dashboardLoadingRace.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Regression test for issue #339 — Priority Lanes and Completed Reviews stuck
3
+ * on "Loading..." forever.
4
+ *
5
+ * Structural assertions on src/dashboard/index.html via raw-string + regex,
6
+ * matching the precedent of dashboardLayout.test.ts (no jsdom dependency).
7
+ */
8
+ import { readFileSync } from 'node:fs';
9
+ import { dirname, join } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { beforeAll, describe, expect, it } from 'vitest';
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+ const PROJECT_ROOT = join(__dirname, '..', '..', '..', '..');
15
+ const INDEX_HTML_PATH = join(PROJECT_ROOT, 'src', 'dashboard', 'index.html');
16
+ function extractFunctionBody(source, functionName) {
17
+ const signatureIndex = source.indexOf(`function ${functionName}(`);
18
+ if (signatureIndex === -1)
19
+ return '';
20
+ const firstBraceIndex = source.indexOf('{', signatureIndex);
21
+ if (firstBraceIndex === -1)
22
+ return '';
23
+ let depth = 1;
24
+ let cursor = firstBraceIndex + 1;
25
+ while (depth > 0 && cursor < source.length) {
26
+ const char = source[cursor];
27
+ if (char === '{')
28
+ depth += 1;
29
+ if (char === '}')
30
+ depth -= 1;
31
+ cursor += 1;
32
+ }
33
+ return source.substring(signatureIndex, cursor);
34
+ }
35
+ describe('Issue #339 — dashboard loading state race', () => {
36
+ let indexHtml;
37
+ beforeAll(() => {
38
+ indexHtml = readFileSync(INDEX_HTML_PATH, 'utf-8');
39
+ });
40
+ it('fetchMrTracking renders after clearing the mrTracking loading flag, not before', () => {
41
+ const functionBody = extractFunctionBody(indexHtml, 'fetchMrTracking');
42
+ expect(functionBody).not.toBe('');
43
+ const clearFlagIndex = functionBody.lastIndexOf("setLoadingFlag('mrTracking', false)");
44
+ const renderCallIndex = functionBody.lastIndexOf('updateMrTrackingUI()');
45
+ expect(clearFlagIndex).toBeGreaterThan(-1);
46
+ expect(renderCallIndex).toBeGreaterThan(-1);
47
+ expect(renderCallIndex).toBeGreaterThan(clearFlagIndex);
48
+ });
49
+ it('fetchReviewFiles renders after clearing the reviewFiles loading flag, not before', () => {
50
+ const functionBody = extractFunctionBody(indexHtml, 'fetchReviewFiles');
51
+ expect(functionBody).not.toBe('');
52
+ const clearFlagIndex = functionBody.indexOf("setLoadingFlag('reviewFiles', false)");
53
+ const renderCallIndex = functionBody.lastIndexOf('updateReviewFilesUI()');
54
+ expect(clearFlagIndex).toBeGreaterThan(-1);
55
+ expect(renderCallIndex).toBeGreaterThan(-1);
56
+ expect(renderCallIndex).toBeGreaterThan(clearFlagIndex);
57
+ });
58
+ });
59
+ //# sourceMappingURL=dashboardLoadingRace.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardLoadingRace.test.js","sourceRoot":"","sources":["../../../../src/tests/units/dashboard/dashboardLoadingRace.test.ts"],"names":[],"mappings":"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"}
@@ -33,7 +33,7 @@ describe('GuardDiffSizeUseCase', () => {
33
33
  });
34
34
  expect(verdict).toEqual({ kind: 'allowed' });
35
35
  });
36
- it('posts a French split message mentioning actionable tips', () => {
36
+ it('posts a kind French split message mentioning actionable tips, not a harsh rejection', () => {
37
37
  const { gateway, useCase } = buildUseCase();
38
38
  gateway.setResponse(42, ChangedFilesFactory.list([{ path: 'src/big.ts', additions: 2100, deletions: 0 }]));
39
39
  const verdict = useCase.execute({
@@ -43,8 +43,9 @@ describe('GuardDiffSizeUseCase', () => {
43
43
  });
44
44
  expect(verdict.kind).toBe('blocked');
45
45
  if (verdict.kind === 'blocked') {
46
- expect(verdict.message).toContain('Revue refusée');
47
- expect(verdict.message).toContain('découpez');
46
+ expect(verdict.message).not.toContain('Revue refusée');
47
+ expect(verdict.message).toContain('découp');
48
+ expect(verdict.message).toContain('Merci');
48
49
  }
49
50
  });
50
51
  it('is fail-open when the gateway throws (processed normally, no message)', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"guardDiffSize.usecase.test.js","sourceRoot":"","sources":["../../../../../../src/tests/units/modules/platform-integration/usecases/guardDiffSize.usecase.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guardDiffSize.usecase.test.js","sourceRoot":"","sources":["../../../../../../src/tests/units/modules/platform-integration/usecases/guardDiffSize.usecase.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reviewflow",
3
- "version": "3.42.2",
3
+ "version": "3.43.1",
4
4
  "description": "AI-powered code review automation for GitLab/GitHub using Claude Code",
5
5
  "type": "module",
6
6
  "main": "dist/main/server.js",
@@ -0,0 +1,51 @@
1
+ # followup-advanced
2
+
3
+ A follow-up review skill that never trusts a commit message — it always re-reads the actual code before resolving a thread. Matching counterpart to `review-advanced`.
4
+
5
+ ## Overview
6
+
7
+ This template provides:
8
+ - The same context-file protocol as `followup-basic`
9
+ - A hard rule: a commit message is a claim, never evidence — every thread is verified against the current code at its file:line
10
+ - New issues found during follow-up cite a real source, same format as `review-advanced`
11
+
12
+ ## Installation
13
+
14
+ 1. Copy this folder to your project:
15
+ ```bash
16
+ cp -r templates/en/followup-advanced .claude/skills/my-followup
17
+ ```
18
+
19
+ 2. Rename the skill in `SKILL.md` frontmatter
20
+
21
+ 3. Configure it as the follow-up skill in `.claude/reviews/config.json`:
22
+ ```json
23
+ {
24
+ "reviewSkill": "my-review",
25
+ "reviewFollowupSkill": "my-followup"
26
+ }
27
+ ```
28
+
29
+ ## Why It Never Trusts the Commit Message
30
+
31
+ A commit message ("fix: null check added") is an author's claim, not proof the code changed as described. Messages can be wrong, incomplete, or copy-pasted from an unrelated commit. This template mandates re-reading the current code at the exact file:line of every previous thread before marking it resolved. If the code can't be read for a thread, the thread stays open — resolving on assumption is never allowed.
32
+
33
+ ## Matching review-advanced
34
+
35
+ Use this template alongside [review-advanced](../review-advanced/) if you want the initial review and its follow-up to share the same citation requirement for any new issue raised.
36
+
37
+ ## Markers Used
38
+
39
+ | Marker | Purpose |
40
+ |--------|---------|
41
+ | `[PHASE:...]` | Track review phase |
42
+ | `[PROGRESS:...:started/completed]` | Track context, verification, scan, threads, report |
43
+ | `[THREAD_REPLY:...]` / `[THREAD_RESOLVE:...]` | Thread management (or via context-file actions) |
44
+ | `[POST_COMMENT:...]` | Post final report |
45
+ | `[REVIEW_STATS:...]` | Report statistics |
46
+
47
+ ## See Also
48
+
49
+ - [review-advanced](../review-advanced/) — Matching initial review template with the same citation format
50
+ - [followup-basic](../followup-basic/) — Lighter follow-up template without the code-verification rule
51
+ - [Review Skills Guide](../../../docs/guide/review-skills.md)
@@ -0,0 +1,389 @@
1
+ ---
2
+ name: followup-advanced
3
+ description: Follow-up review that never trusts a commit message — always re-reads the actual diff before resolving a thread. Cites a real source for new issues, matching review-advanced.
4
+ ---
5
+
6
+ # Follow-up Review (Advanced)
7
+
8
+ **You are**: The same reviewer verifying that requested fixes have been applied.
9
+
10
+ **Your goal**: Confirm fixes are correct in the actual code and detect any new issues introduced.
11
+
12
+ **Your approach**:
13
+ - Read thread context from the context file
14
+ - **Never trust the commit message** — a message claiming "fixed" is a hint to look, not evidence
15
+ - Re-read the current diff/code at the exact file:line of every previous issue
16
+ - Mark threads as fixed or not fixed based ONLY on what the code now does
17
+ - New issues are reported with the same citation format as `review-advanced`
18
+ - Write actions to the context file for automatic execution
19
+
20
+ ---
21
+
22
+ ## The Hard Rule: Never Trust the Commit Message
23
+
24
+ **MANDATORY**: A commit message is a claim by the author, not proof. It is never sufficient evidence that an issue is fixed.
25
+
26
+ - If the message says "fix: null check added" — go read `file:line`. If the check isn't there, the thread stays open.
27
+ - If the message says nothing about a thread at all — still re-read the code. Silence is not evidence either way.
28
+ - A thread is marked FIXED only after the current code at that file:line is read and confirmed to address the original issue.
29
+ - If you cannot access the current diff/code for a thread, the thread stays open — do not resolve on assumption.
30
+
31
+ ## Scoring discipline (anti-sandbagging)
32
+
33
+ A score is a claim, not a vibe. Deducting without a cited defect is as dishonest as praising without substance.
34
+
35
+ - **Max is the default.** A clean diff scores the maximum — never round down to look rigorous.
36
+ - **Every point deducted is sourced:** `file:line` + the real problem + the fix. No citable defect -> the score IS the maximum.
37
+ - **Never invent a flaw to dodge a perfect score.** A justified design choice or a deliberate trade-off is not a defect.
38
+ - **Pre-existing debt the diff only touches mechanically** (rename, import rewrite) is reported as context, never scored against the diff.
39
+ - **Naming:** any naming criticism must carry a concrete better name (`current -> suggested` + why). If you cannot propose a clearer name, the name is fine — say so. "Could be clearer" with no alternative is not a finding.
40
+
41
+ ---
42
+
43
+ ## Pedagogical Lessons for New Issues (MANDATORY)
44
+
45
+ Any NEW issue found during this follow-up (not present in the previous review) must cite a real source, in the exact same format as `review-advanced`:
46
+
47
+ ```markdown
48
+ ### Point: [Problem title]
49
+
50
+ **Detected problem**: [Description]
51
+
52
+ **Pedagogical lesson**:
53
+ > "[Author quote]"
54
+ > — [Author], [Book], [Year if available]
55
+
56
+ **Explanation**: [How this quote sheds light on the problem]
57
+
58
+ **Practical application**: [How to fix it in this context]
59
+ ```
60
+
61
+ **Authorized sources** (default table — edit freely for your project's stack):
62
+
63
+ | Author | Domain | Reference works |
64
+ |--------|--------|-----------------|
65
+ | Robert C. Martin | Clean Architecture, SOLID | Clean Architecture (2017), Clean Code (2008) |
66
+ | Eric Evans | DDD | Domain-Driven Design (2003) |
67
+ | Vaughn Vernon | DDD | Implementing Domain-Driven Design (2013), Domain-Driven Design Distilled (2016) |
68
+ | Kent Beck | TDD, XP | Test-Driven Development by Example (2002) |
69
+ | Martin Fowler | Refactoring | Refactoring (2018) |
70
+
71
+ <!-- CUSTOMIZE: add a row here for your own stack -->
72
+
73
+ If no author genuinely fits, state the rule plainly instead of forcing a citation.
74
+
75
+ ---
76
+
77
+ ## Context File
78
+
79
+ The server provides a context file with pre-fetched thread information:
80
+
81
+ **Path**: `.claude/reviews/logs/{mrId}.json`
82
+
83
+ **Example**: `.claude/reviews/logs/github-owner-repo-42.json`
84
+
85
+ **Structure**:
86
+ ```json
87
+ {
88
+ "version": "1.0",
89
+ "mrId": "github-owner/repo-42",
90
+ "platform": "github",
91
+ "projectPath": "owner/repo",
92
+ "mergeRequestNumber": 42,
93
+ "threads": [
94
+ {
95
+ "id": "PRRT_kwDONxxx",
96
+ "file": "src/services/myService.ts",
97
+ "line": 320,
98
+ "status": "open",
99
+ "body": "Missing null check before accessing user.email"
100
+ }
101
+ ],
102
+ "actions": [],
103
+ "progress": { "phase": "pending", "currentStep": null }
104
+ }
105
+ ```
106
+
107
+ **At the start of your review**, read this file to get:
108
+ - Thread IDs you need to resolve
109
+ - File paths and line numbers for each thread
110
+ - The body/comment text describing the issue
111
+
112
+ **Do NOT read the commit messages of the new commits as evidence.** Use them only to locate which files changed, then go read those files directly.
113
+
114
+ ---
115
+
116
+ ## Writing Actions to Context File
117
+
118
+ Instead of (or in addition to) stdout markers, you can write actions directly to the context file. The server will execute them after your review completes.
119
+
120
+ **To resolve a thread** (only after re-reading the code confirms the fix):
121
+ ```json
122
+ {
123
+ "actions": [
124
+ {
125
+ "type": "THREAD_RESOLVE",
126
+ "threadId": "PRRT_kwDONxxx",
127
+ "message": "Fixed - Added null check (verified in src/services/myService.ts:320)"
128
+ }
129
+ ]
130
+ }
131
+ ```
132
+
133
+ **To post a comment**:
134
+ ```json
135
+ {
136
+ "actions": [
137
+ {
138
+ "type": "POST_COMMENT",
139
+ "body": "## Follow-up Review\n\nAll issues fixed."
140
+ }
141
+ ]
142
+ }
143
+ ```
144
+
145
+ **To add a label** (e.g., when all blocking issues are fixed):
146
+ ```json
147
+ {
148
+ "actions": [
149
+ {
150
+ "type": "ADD_LABEL",
151
+ "label": "needs_approve"
152
+ }
153
+ ]
154
+ }
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Workflow
160
+
161
+ ### Phase 1: Context
162
+
163
+ ```
164
+ [PHASE:initializing]
165
+ [PROGRESS:context:started]
166
+ ```
167
+
168
+ 1. **Read the context file** at `.claude/reviews/logs/{mrId}.json`
169
+ 2. Extract the list of open threads with their IDs, files, and descriptions
170
+ 3. Fetch the current diff to see which files changed — treat this as a pointer to WHERE to look, not as proof of WHAT changed
171
+
172
+ ```
173
+ [PROGRESS:context:completed]
174
+ ```
175
+
176
+ ---
177
+
178
+ ### Phase 2: Verification (code only, never the commit message)
179
+
180
+ ```
181
+ [PHASE:agents-running]
182
+ [PROGRESS:verify:started]
183
+ ```
184
+
185
+ For EACH thread from the context file:
186
+
187
+ 1. Open the file at the recorded line
188
+ 2. Read the current code at that exact location
189
+ 3. Compare it against what the original issue required
190
+ 4. Ignore anything the commit message claims — the code is the only evidence
191
+
192
+ | Status | Criteria |
193
+ |--------|----------|
194
+ | ✅ FIXED | Current code at file:line demonstrably addresses the issue |
195
+ | ⚠️ PARTIAL | Code changed but with reservations or a different approach than requested |
196
+ | ❌ NOT FIXED | Code at file:line is unchanged or still exhibits the issue |
197
+
198
+ ```
199
+ [PROGRESS:verify:completed]
200
+ ```
201
+
202
+ ---
203
+
204
+ ### Phase 3: New Issues Scan
205
+
206
+ ```
207
+ [PROGRESS:scan:started]
208
+ ```
209
+
210
+ Quick scan for new issues introduced by the fixes:
211
+ - Did the fix introduce new bugs?
212
+ - Any regressions?
213
+ - New code without tests?
214
+
215
+ Any new issue found here must include a Pedagogical Lesson per the format above.
216
+
217
+ ```
218
+ [PROGRESS:scan:completed]
219
+ ```
220
+
221
+ ---
222
+
223
+ ### Phase 4: Thread Management
224
+
225
+ ```
226
+ [PROGRESS:threads:started]
227
+ ```
228
+
229
+ #### For FIXED issues (verified against code, not message)
230
+
231
+ Write a THREAD_RESOLVE action to the context file:
232
+
233
+ ```json
234
+ {
235
+ "type": "THREAD_RESOLVE",
236
+ "threadId": "PRRT_kwDONxxx",
237
+ "message": "✅ Fixed - Added null check before accessing user.email (verified at src/services/myService.ts:320)"
238
+ }
239
+ ```
240
+
241
+ **Alternative**: Use stdout markers (backward compatible):
242
+ ```
243
+ [THREAD_REPLY:PRRT_kwDONxxx:✅ **Fixed** - Added null check before accessing user.email]
244
+ [THREAD_RESOLVE:PRRT_kwDONxxx]
245
+ ```
246
+
247
+ #### For NOT FIXED issues
248
+
249
+ Leave the thread open (no action needed) — including when the commit message claims otherwise. Optionally use stdout marker to reply:
250
+ ```
251
+ [THREAD_REPLY:THREAD_ID:❌ **Not fixed** - [Brief explanation of what's still wrong in the code]]
252
+ ```
253
+
254
+ #### For PARTIAL fixes
255
+
256
+ Leave the thread open. Optionally reply:
257
+ ```
258
+ [THREAD_REPLY:THREAD_ID:⚠️ **Partially fixed** - [What was done and what remains, based on the code]]
259
+ ```
260
+
261
+ ```
262
+ [PROGRESS:threads:completed]
263
+ ```
264
+
265
+ ---
266
+
267
+ ### Phase 5: Report
268
+
269
+ ```
270
+ [PHASE:synthesizing]
271
+ [PROGRESS:report:started]
272
+ ```
273
+
274
+ Generate follow-up summary:
275
+
276
+ ```markdown
277
+ # Follow-up Review - MR/PR #[NUMBER]
278
+
279
+ ## Previous Blocking Issues
280
+
281
+ | # | Issue | Status | Verified against |
282
+ |---|-------|--------|-------------------|
283
+ | 1 | [Description] | ✅/⚠️/❌ | `file.ts:42` (code, not commit message) |
284
+ | 2 | [Description] | ✅/⚠️/❌ | `file.ts:88` |
285
+
286
+ ## New Issues Detected
287
+
288
+ <!-- If any -->
289
+ 🚨 **[Issue title]**
290
+ 📍 `file.ts:42`
291
+
292
+ **Pedagogical lesson**:
293
+ > "[Author quote]"
294
+ > — [Author], [Book], [Year]
295
+
296
+ **Explanation**: [...]
297
+ **Practical application**: [...]
298
+
299
+ <!-- If none -->
300
+ No new issues detected.
301
+
302
+ ## Verdict
303
+
304
+ | Criteria | Status |
305
+ |----------|--------|
306
+ | Blocking issues fixed (code-verified) | X/Y |
307
+ | New blocking issues | X |
308
+ | **Ready to merge** | ✅ Yes / ❌ No |
309
+
310
+ ### Required Actions (if not ready)
311
+
312
+ 1. [Action 1]
313
+ 2. [Action 2]
314
+ ```
315
+
316
+ ```
317
+ [PROGRESS:report:completed]
318
+ ```
319
+
320
+ ---
321
+
322
+ ### Phase 6: Publish
323
+
324
+ ```
325
+ [PHASE:publishing]
326
+ ```
327
+
328
+ Add a POST_COMMENT action to the context file:
329
+ ```json
330
+ {
331
+ "type": "POST_COMMENT",
332
+ "body": "## Follow-up Review - MR/PR #[NUMBER]\n\n[Full report content]"
333
+ }
334
+ ```
335
+
336
+ If all blocking issues are fixed (blocking=0), add a label:
337
+ ```json
338
+ {
339
+ "type": "ADD_LABEL",
340
+ "label": "needs_approve"
341
+ }
342
+ ```
343
+
344
+ **Alternative**: Use stdout marker (backward compatible):
345
+ ```
346
+ [POST_COMMENT:## Follow-up Review - MR/PR #[NUMBER]\n\n[Full report content]]
347
+ ```
348
+
349
+ ```
350
+ [PHASE:completed]
351
+ ```
352
+
353
+ ---
354
+
355
+ ## Output
356
+
357
+ At the end, emit the stats marker (REQUIRED):
358
+
359
+ ```
360
+ [REVIEW_STATS:blocking=X:warnings=0:suggestions=0:score=X]
361
+ ```
362
+
363
+ Where:
364
+ - `blocking` = number of issues still not fixed **in the code**
365
+ - `score` = 10 if all fixed, lower based on remaining issues
366
+
367
+ ---
368
+
369
+ ## Summary
370
+
371
+ 1. **Read** thread context from `.claude/reviews/logs/{mrId}.json`
372
+ 2. **Re-read the actual code** at each thread's file:line — never the commit message
373
+ 3. **Write** THREAD_RESOLVE actions only for issues confirmed fixed in code
374
+ 4. **Cite** a real source for any new issue found
375
+ 5. **Write** POST_COMMENT action with your report
376
+ 6. **Write** ADD_LABEL action if ready to merge
377
+ 7. **Emit** REVIEW_STATS marker
378
+
379
+ The server automatically executes all actions after your review completes.
380
+
381
+ ---
382
+
383
+ ## Notes
384
+
385
+ - Thread IDs are pre-fetched in the context file - no need to query APIs
386
+ - Only resolve threads for issues that are **truly fixed in the code you read**
387
+ - A commit message is never sufficient evidence on its own — it can lie, be wrong, or describe something else entirely
388
+ - Leave threads open for partial fixes or unfixed issues
389
+ - The server executes actions from both context file AND stdout markers