@motivation-labs/crosscheck 0.5.0 → 0.6.0

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.
Files changed (81) hide show
  1. package/README.md +24 -7
  2. package/crosscheck.config.example.yml +90 -4
  3. package/dist/__tests__/backtrace.test.d.ts +2 -0
  4. package/dist/__tests__/backtrace.test.d.ts.map +1 -0
  5. package/dist/__tests__/backtrace.test.js +158 -0
  6. package/dist/__tests__/backtrace.test.js.map +1 -0
  7. package/dist/__tests__/optimize.test.js +16 -3
  8. package/dist/__tests__/optimize.test.js.map +1 -1
  9. package/dist/cli.js +8 -2
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands/diagnose.d.ts +1 -0
  12. package/dist/commands/diagnose.d.ts.map +1 -1
  13. package/dist/commands/diagnose.js +14 -0
  14. package/dist/commands/diagnose.js.map +1 -1
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +55 -18
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/commands/review.d.ts.map +1 -1
  19. package/dist/commands/review.js +11 -5
  20. package/dist/commands/review.js.map +1 -1
  21. package/dist/commands/serve.d.ts +7 -1
  22. package/dist/commands/serve.d.ts.map +1 -1
  23. package/dist/commands/serve.js +109 -16
  24. package/dist/commands/serve.js.map +1 -1
  25. package/dist/commands/status.d.ts.map +1 -1
  26. package/dist/commands/status.js +1 -0
  27. package/dist/commands/status.js.map +1 -1
  28. package/dist/commands/watch.d.ts +7 -1
  29. package/dist/commands/watch.d.ts.map +1 -1
  30. package/dist/commands/watch.js +349 -143
  31. package/dist/commands/watch.js.map +1 -1
  32. package/dist/config/loader.d.ts +8 -0
  33. package/dist/config/loader.d.ts.map +1 -1
  34. package/dist/config/loader.js +143 -0
  35. package/dist/config/loader.js.map +1 -1
  36. package/dist/config/schema.d.ts +445 -27
  37. package/dist/config/schema.d.ts.map +1 -1
  38. package/dist/config/schema.js +70 -7
  39. package/dist/config/schema.js.map +1 -1
  40. package/dist/github/client.d.ts +26 -0
  41. package/dist/github/client.d.ts.map +1 -1
  42. package/dist/github/client.js +153 -0
  43. package/dist/github/client.js.map +1 -1
  44. package/dist/github/detector.d.ts +8 -1
  45. package/dist/github/detector.d.ts.map +1 -1
  46. package/dist/github/detector.js +84 -12
  47. package/dist/github/detector.js.map +1 -1
  48. package/dist/lib/backtrace.d.ts +20 -0
  49. package/dist/lib/backtrace.d.ts.map +1 -0
  50. package/dist/lib/backtrace.js +75 -0
  51. package/dist/lib/backtrace.js.map +1 -0
  52. package/dist/lib/board.d.ts +52 -0
  53. package/dist/lib/board.d.ts.map +1 -0
  54. package/dist/lib/board.js +394 -0
  55. package/dist/lib/board.js.map +1 -0
  56. package/dist/lib/runner.d.ts +10 -1
  57. package/dist/lib/runner.d.ts.map +1 -1
  58. package/dist/lib/runner.js +129 -51
  59. package/dist/lib/runner.js.map +1 -1
  60. package/dist/lib/verdict.d.ts +1 -0
  61. package/dist/lib/verdict.d.ts.map +1 -1
  62. package/dist/lib/verdict.js +27 -7
  63. package/dist/lib/verdict.js.map +1 -1
  64. package/dist/lib/workflow.d.ts +8 -8
  65. package/dist/lib/workflow.d.ts.map +1 -1
  66. package/dist/lib/workflow.js +22 -5
  67. package/dist/lib/workflow.js.map +1 -1
  68. package/dist/reviewers/claude.d.ts +1 -1
  69. package/dist/reviewers/claude.d.ts.map +1 -1
  70. package/dist/reviewers/claude.js +4 -6
  71. package/dist/reviewers/claude.js.map +1 -1
  72. package/dist/reviewers/codex.d.ts +2 -2
  73. package/dist/reviewers/codex.d.ts.map +1 -1
  74. package/dist/reviewers/codex.js +6 -6
  75. package/dist/reviewers/codex.js.map +1 -1
  76. package/dist/reviewers/fix.d.ts +5 -0
  77. package/dist/reviewers/fix.d.ts.map +1 -0
  78. package/dist/reviewers/fix.js +87 -0
  79. package/dist/reviewers/fix.js.map +1 -0
  80. package/get-started.md +190 -21
  81. package/package.json +1 -1
@@ -27,10 +27,10 @@ const TIER_TIMEOUT_MS = {
27
27
  balanced: 600_000,
28
28
  thorough: 1_200_000,
29
29
  };
30
- export async function runCodexReview(repoDir, baseBranch, prTitle, quality, overrideModel, authMode = 'subscription', onLog) {
30
+ export async function runCodexReview(repoDir, baseBranch, prTitle, quality, vendor, stepInstructions, onLog) {
31
31
  // subscription auth has a fixed model set by ChatGPT plan; only override for api-key
32
- const model = authMode === 'api-key'
33
- ? (overrideModel ?? TIER_MODELS_API[quality.tier] ?? 'o4-mini')
32
+ const model = vendor.auth === 'api-key'
33
+ ? (vendor.model ?? TIER_MODELS_API[quality.tier] ?? 'o4-mini')
34
34
  : undefined;
35
35
  const tmpFile = join(mkdtempSync(join(tmpdir(), 'crosscheck-')), 'review.md');
36
36
  // --base and [PROMPT] are mutually exclusive in codex review;
@@ -39,9 +39,9 @@ export async function runCodexReview(repoDir, baseBranch, prTitle, quality, over
39
39
  ? `Focus areas: ${quality.focus.join(', ')}. `
40
40
  : '';
41
41
  const customNote = quality.custom_prompt ?? '';
42
- // Adaptive instructions from ~/.crosscheck/instructions.md (managed by `crosscheck optimize`)
43
- const adaptiveInstructions = readInstructions(repoDir);
44
- const instructionsNote = [focusNote, customNote, adaptiveInstructions].filter(Boolean).join('\n\n');
42
+ // stepInstructions from workflow step takes precedence; fall back to ~/.crosscheck/instructions.md
43
+ const behaviorInstructions = stepInstructions !== undefined ? stepInstructions : readInstructions(repoDir);
44
+ const instructionsNote = [focusNote, customNote, behaviorInstructions].filter(Boolean).join('\n\n');
45
45
  mkdirSync(`${repoDir}/.codex`, { recursive: true });
46
46
  writeFileSync(`${repoDir}/.codex/instructions`, instructionsNote);
47
47
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Config } from '../config/schema.js';
2
+ export declare function runFixStep(tmpDir: string, baseRef: string, prTitle: string, reviewComment: string, instructions: string, config: Config): Promise<{
3
+ appliedCount: number;
4
+ }>;
5
+ //# sourceMappingURL=fix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/reviewers/fix.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAgCjD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAqDnC"}
@@ -0,0 +1,87 @@
1
+ import { execSync, execFileSync } from 'child_process';
2
+ import { writeFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ const PROMPT_TEMPLATE = `You opened a pull request that received the following code review.
5
+
6
+ PR title: {PR_TITLE}
7
+
8
+ Code review comment:
9
+ ---
10
+ {REVIEW_COMMENT}
11
+ ---
12
+
13
+ Diff of your changes (base..head):
14
+ ---
15
+ {DIFF}
16
+ ---
17
+
18
+ {EXTRA_INSTRUCTIONS}
19
+
20
+ Please address the issues raised in the review. Rules:
21
+ - Only fix what the review explicitly calls out
22
+ - Do not refactor unrelated code, rename variables, or add tests unless asked
23
+ - If a comment requires deeper understanding of business logic, skip it
24
+ - If the review has no actionable code changes, output exactly: NO_CHANGES
25
+
26
+ For each file you need to change, output the complete new file content using this format:
27
+
28
+ <file path="relative/path/to/file.ext">
29
+ [complete file content]
30
+ </file>
31
+
32
+ Output ONLY <file> blocks or NO_CHANGES. No other text.`;
33
+ export async function runFixStep(tmpDir, baseRef, prTitle, reviewComment, instructions, config) {
34
+ let diff = '';
35
+ try {
36
+ diff = execSync(`git diff origin/${baseRef}...HEAD`, { cwd: tmpDir, encoding: 'utf8' });
37
+ }
38
+ catch {
39
+ try {
40
+ diff = execSync('git diff HEAD~1', { cwd: tmpDir, encoding: 'utf8' });
41
+ }
42
+ catch { /* proceed with empty diff */ }
43
+ }
44
+ const prompt = PROMPT_TEMPLATE
45
+ .replace('{PR_TITLE}', prTitle)
46
+ .replace('{REVIEW_COMMENT}', reviewComment.slice(0, 8000))
47
+ .replace('{DIFF}', diff.slice(0, 16000))
48
+ .replace('{EXTRA_INSTRUCTIONS}', instructions ? `Additional instructions: ${instructions}` : '');
49
+ let output = '';
50
+ try {
51
+ // Pass prompt via stdin — same pattern as optimize.ts
52
+ output = execFileSync('claude', ['--print', '--output-format', 'text'], {
53
+ input: prompt,
54
+ encoding: 'utf8',
55
+ timeout: 180_000,
56
+ env: { ...process.env },
57
+ maxBuffer: 10 * 1024 * 1024,
58
+ }).trim();
59
+ }
60
+ catch (err) {
61
+ const msg = err instanceof Error ? err.message : String(err);
62
+ if (/not logged in|auth|credential/i.test(msg)) {
63
+ throw new Error('claude auth failure during fix step — run: claude auth login');
64
+ }
65
+ throw err;
66
+ }
67
+ if (!output || output === 'NO_CHANGES')
68
+ return { appliedCount: 0 };
69
+ // Parse <file path="...">content</file> blocks
70
+ const fileRegex = /<file path="([^"]+)">([\s\S]*?)<\/file>/g;
71
+ let match;
72
+ let appliedCount = 0;
73
+ while ((match = fileRegex.exec(output)) !== null) {
74
+ const [, filePath, rawContent] = match;
75
+ // Reject paths that escape the repo (e.g. ../../etc/passwd)
76
+ if (filePath.includes('..') || filePath.startsWith('/'))
77
+ continue;
78
+ const absPath = join(tmpDir, filePath);
79
+ try {
80
+ writeFileSync(absPath, rawContent.replace(/^\n/, ''));
81
+ appliedCount++;
82
+ }
83
+ catch { /* skip unwritable paths */ }
84
+ }
85
+ return { appliedCount };
86
+ }
87
+ //# sourceMappingURL=fix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/reviewers/fix.ts"],"names":[],"mappings":"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"}
package/get-started.md CHANGED
@@ -24,6 +24,7 @@
24
24
  - [impact](#crosscheck-impact)
25
25
  - [Configuration](#configuration)
26
26
  - [How it works](#how-it-works)
27
+ - [Post-review auto-fix](#post-review-auto-fix)
27
28
  - [FAQ](#faq)
28
29
 
29
30
  ---
@@ -185,6 +186,43 @@ crosscheck review https://github.com/owner/repo/pull/123 --reviewer claude
185
186
 
186
187
  ## Step 3 — Choose a deployment mode
187
188
 
189
+ ### Personal vs team
190
+
191
+ On first run, `crosscheck watch` (or `crosscheck serve`) will ask how you're using it:
192
+
193
+ ```
194
+ How are you using crosscheck?
195
+
196
+ [1] personal — monitor all your repos and orgs; review only PRs you author
197
+ [2] team — monitor org repos only; review all PRs from any author
198
+
199
+ Choice [1]:
200
+ ```
201
+
202
+ The choice is saved to `crosscheck.config.yml` as `deployment: personal` or `deployment: team`.
203
+
204
+ **Personal mode** (default, recommended for individuals)
205
+ - Monitors all repos under your personal GitHub account + all orgs you belong to
206
+ - Only reviews PRs you authored — ignores everyone else's
207
+ - Sets `routing.allowed_authors` to your GitHub login automatically
208
+
209
+ **Team mode** (recommended for shared machines)
210
+ - Monitors all orgs you belong to (no personal repos)
211
+ - Reviews all PRs from any author — no author filter applied
212
+
213
+ You can override the saved choice for a single session without touching the config:
214
+
215
+ ```bash
216
+ crosscheck watch --personal # personal mode this session only
217
+ crosscheck watch --team # team mode this session only
218
+ ```
219
+
220
+ To re-run the prompt and permanently change your choice:
221
+
222
+ ```bash
223
+ crosscheck watch --reconfigure
224
+ ```
225
+
188
226
  ### Watch mode — for your development machine
189
227
 
190
228
  Starts a local server and opens a tunnel via `localhost.run` (SSH, no install needed) so GitHub can reach your laptop. Registers webhooks automatically. Supports org-level coverage or per-repo. Runs while your terminal is open.
@@ -561,17 +599,25 @@ The monetary estimate formula: `(hours_saved × hourly_rate_usd) + (issues_caugh
561
599
 
562
600
  ## Configuration
563
601
 
564
- crosscheck looks for a config file in these locations (first found wins):
602
+ crosscheck stores its config in `~/.crosscheck/config.yml` by default — persistent across projects, no per-repo file needed. It also looks in these locations (first found wins):
565
603
 
566
604
  1. `./crosscheck.config.yml`
567
605
  2. `./.crosscheck.yml`
568
- 3. `~/.crosscheck/config.yml`
606
+ 3. `~/.crosscheck/config.yml` ← **default location**
607
+
608
+ Run `crosscheck init` to generate `~/.crosscheck/config.yml` with all options documented.
569
609
 
570
- Run `crosscheck init` to generate a starter file with all options commented.
610
+ Logs are written to `~/.crosscheck/logs/YYYY-MM-DD.ndjson` and retained for 30 days by default.
571
611
 
572
612
  ### Full reference
573
613
 
574
614
  ```yaml
615
+ # ── Deployment ────────────────────────────────────────────────────────────────
616
+ # Set automatically on first run. Re-run the prompt with: crosscheck watch --reconfigure
617
+ # personal — monitor your repos + orgs; review only your PRs
618
+ # team — monitor org repos only; review all PRs from any author
619
+ # deployment: personal
620
+
575
621
  # ── Mode ──────────────────────────────────────────────────────────────────────
576
622
  # single-vendor: one AI reviews all PRs
577
623
  # cross-vendor: Claude ↔ Codex review each other
@@ -605,24 +651,43 @@ budget:
605
651
  per_review_usd: 2.00 # passed to claude --max-budget-usd
606
652
 
607
653
  # ── Orgs — covers all repos in each org with one webhook ─────────────────────
608
- # Takes priority over `repos` when both are set.
609
654
  orgs:
610
655
  - motivation-labs
611
656
  - codatta
612
657
 
658
+ # ── Users — monitors all repos owned by personal GitHub accounts (non-org) ───
659
+ # At startup, crosscheck enumerates each user's repos and registers webhooks.
660
+ # Useful when your AI agents open PRs across many personal repos.
661
+ # Combines with `orgs` and `repos` — all configured sources are additive.
662
+ users:
663
+ - beingzy # your personal account
664
+ # - my-agent-login # a bot account that pushes to its own repos
665
+
613
666
  # ── Repos — for monitoring specific repos only ────────────────────────────────
614
- # Omit when using `orgs`. In watch mode, auto-detected from git remote if empty.
667
+ # Omit when using `orgs`/`users`. Auto-detected from git remote if all are empty.
615
668
  repos:
616
669
  - owner: acme
617
670
  name: specific-repo
618
671
 
619
672
  # ── Routing ───────────────────────────────────────────────────────────────────
620
673
  routing:
674
+ # Origin is detected via a four-signal chain:
675
+ # 1. PR body patterns below (fastest)
676
+ # 2. Commit message Co-Authored-By: trailers (API call, non-fatal if it fails)
677
+ # 3. Branch prefix (claude/ or codex/)
678
+ # 4. author_routes fallback (last resort)
621
679
  codex_reviews_patterns:
622
- - "Generated with \\[Claude Code\\]"
680
+ - "Generated with \\[Claude Code\\]" # Claude Code attribution footer
681
+ - "Co-Authored-By: Claude" # commit trailer
623
682
  claude_reviews_patterns:
624
- - "Generated with \\[OpenAI Codex\\]"
625
- - "Co-Authored-By: codex"
683
+ - "Generated with \\[OpenAI Codex\\]" # Codex attribution footer
684
+ - "Co-Authored-By: codex" # commit trailer
685
+
686
+ # Branch prefix detection (signal 3). Claude Code uses claude/, Codex uses codex/.
687
+ claude_branch_prefixes:
688
+ - "claude/"
689
+ codex_branch_prefixes:
690
+ - "codex/"
626
691
 
627
692
  # Restrict reviews to PRs opened by these GitHub logins.
628
693
  # Auto-filled with your GitHub login by `crosscheck init` or first `crosscheck watch`.
@@ -630,12 +695,11 @@ routing:
630
695
  allowed_authors:
631
696
  - your-github-login # auto-detected from gh auth
632
697
 
633
- # Author-based routing fallback — used when no body pattern matches.
698
+ # Author-based routing fallback (signal 4) — used when no pattern or prefix matches.
634
699
  # Maps GitHub login → vendor origin so crosscheck routes PRs even without
635
700
  # the attribution footer (e.g. when creating PRs via gh CLI directly).
636
701
  author_routes:
637
702
  your-github-login: claude # your PRs → treated as Claude-authored → Codex reviews
638
- - your-codex-bot-account
639
703
 
640
704
  # ── Tunnel (watch mode only) ──────────────────────────────────────────────────
641
705
  # localhost.run (default) — SSH tunnel, zero install, URL changes on reconnect.
@@ -653,6 +717,26 @@ impact:
653
717
  hourly_rate_usd: 150 # for --money estimate
654
718
  defect_cost_usd: 150 # per issue caught, for --money estimate
655
719
 
720
+ # ── Post-review auto-fix ──────────────────────────────────────────────────────
721
+ # Runs after each review. When issues are found, the authoring vendor opens a
722
+ # fix PR targeting the original branch. You approve and merge it; the original
723
+ # PR updates automatically.
724
+ post_review:
725
+ auto_fix:
726
+ enabled: true
727
+ trigger: on_issues # on_issues | always | never
728
+ min_severity: warning # error | warning | info — skip cosmetic findings
729
+ # same-as-author: the vendor that wrote the PR also applies the fix
730
+ # In cross-vendor mode: Claude-authored → Claude fixes; Codex-authored → Codex fixes
731
+ fixer: same-as-author # same-as-author | same-as-reviewer | codex | claude
732
+ delivery:
733
+ mode: pull_request # pull_request | commit | comment
734
+ # pull_request → fix PR targets original branch; human approves before merge
735
+ # commit → fixes pushed directly onto the original PR branch
736
+ # comment → suggested fixes posted as review comments only
737
+ pr_title: "fix: address CR issues in #{original_pr_title}"
738
+ label: cr-autofix # GitHub label applied to the fix PR
739
+
656
740
  # ── Server ────────────────────────────────────────────────────────────────────
657
741
  server:
658
742
  port: 7891
@@ -715,15 +799,38 @@ clone PR branch into temp directory
715
799
 
716
800
  post comment to PR via GitHub API
717
801
  delete temp clone
802
+
803
+ ▼ post_review.auto_fix (if enabled and issues found)
804
+ authoring vendor reads review comment
805
+
806
+ ├─ claude --print ... (Claude authored the PR)
807
+ │ or
808
+ └─ codex ... (Codex authored the PR)
809
+
810
+
811
+ opens fix PR → fix/cr-<pr-number>-review-issues → original branch
812
+ (you review and merge the fix PR; original PR updates automatically)
718
813
  ```
719
814
 
720
815
  ### PR origin detection
721
816
 
817
+ crosscheck uses a four-signal chain to determine whether a PR was authored by Claude Code, Codex, or a human:
818
+
819
+ 1. **PR body** — looks for attribution footers (e.g. `Generated with [Claude Code]`)
820
+ 2. **Commit messages** — scans all commit messages for `Co-Authored-By:` trailers
821
+ 3. **Branch prefix** — `claude/` → Claude origin; `codex/` → Codex origin
822
+ 4. **`author_routes`** — per-login fallback in config
823
+
824
+ If none match, origin is `human` and the PR is skipped in cross-vendor mode.
825
+
722
826
  | Default pattern | Matches |
723
827
  |---|---|
724
- | `Generated with \[Claude Code\]` | PRs opened by Claude Code |
725
- | `Generated with \[OpenAI Codex\]` | PRs opened by Codex CLI |
726
- | `Co-Authored-By: codex` | Commits co-authored by Codex |
828
+ | `Generated with \[Claude Code\]` | Claude Code attribution footer in PR body |
829
+ | `Generated with \[OpenAI Codex\]` | Codex attribution footer in PR body |
830
+ | `Co-Authored-By: Claude` | Commit trailers from Claude Code |
831
+ | `Co-Authored-By: codex` | Commit trailers from Codex |
832
+ | branch prefix `claude/` | Branch naming convention for Claude-authored PRs |
833
+ | branch prefix `codex/` | Branch naming convention for Codex-authored PRs |
727
834
 
728
835
  ### Reviewer assignment
729
836
 
@@ -780,6 +887,39 @@ GitHub can fire both `opened` and `synchronize` events for the same push. crossc
780
887
 
781
888
  ---
782
889
 
890
+ ## Post-review auto-fix
891
+
892
+ When `post_review.auto_fix.enabled` is `true` (the default), crosscheck completes the full loop automatically after every review that finds issues:
893
+
894
+ ```
895
+ agent opens PR #42 → opposite vendor reviews → issues found?
896
+ │ yes
897
+ authoring vendor generates fixes
898
+
899
+ fix PR #43 opened → feat/my-feature
900
+
901
+ you review and merge PR #43
902
+
903
+ PR #42 updates → you merge to main
904
+ ```
905
+
906
+ **Key design decisions:**
907
+
908
+ | Setting | Default | Why |
909
+ |---|---|---|
910
+ | `fixer: same-as-author` | the vendor that wrote the PR also fixes it | The authoring agent knows its own code and style best |
911
+ | `delivery: pull_request` | opens a new PR, doesn't push directly | You stay in the loop — no code lands without your approval |
912
+ | `trigger: on_issues` | only fires when the reviewer found warnings or worse | Skips the fix step on clean PRs |
913
+ | `min_severity: warning` | ignores info/cosmetic findings | Avoids noisy fix PRs for style-only comments |
914
+
915
+ **Fix PR branch naming:** `fix/cr-<original-pr-number>-review-issues`
916
+
917
+ **Original PR number:** never changes. The fix PR targets the original branch; once merged, its commits appear in the original PR automatically.
918
+
919
+ **To disable:** set `post_review.auto_fix.enabled: false` in your config, or set `trigger: never`.
920
+
921
+ ---
922
+
783
923
  ## FAQ
784
924
 
785
925
  ### How does crosscheck improve over time?
@@ -796,19 +936,38 @@ It picks automatically:
796
936
 
797
937
  The agent used for `optimize` is independent of which agent reviews your PRs — `optimize` is about improving the instructions, not reviewing code.
798
938
 
799
- ### What is `~/.crosscheck/instructions.md` and can I edit it?
939
+ ### How do I customize reviewer behavior?
800
940
 
801
- Yes it is a plain Markdown file that both `codex` and `claude` read before every review. On first use, crosscheck seeds it with safe defaults (no build-tool constraints, a focused review prompt, and the VERDICT format). You can edit it manually at any time. `crosscheck optimize --apply` rewrites it, so keep a backup or use version control if you've made custom edits you want to preserve.
941
+ The primary place is the workflow file. Each step has an `instructions` field that is passed verbatim to the reviewer or fixer agent:
802
942
 
803
- To reset to defaults, delete the file:
943
+ ```yaml
944
+ # .crosscheck/workflow.yml
945
+ steps:
946
+ - name: review
947
+ type: review
948
+ reviewer: auto
949
+ instructions: |
950
+ Do not suggest TypeScript patterns — this is a Rust project.
951
+ Focus on memory safety and error handling.
952
+ ## Verdict
953
+ End with: VERDICT: APPROVE | NEEDS_WORK | BLOCK
954
+ - name: fix
955
+ type: fix
956
+ reviewer: origin
957
+ when: "review.verdict != 'APPROVE'"
958
+ instructions: "Only fix issues explicitly called out. Do not refactor unrelated code."
959
+ ```
960
+
961
+ `~/.crosscheck/instructions.md` serves as a fallback when a workflow step has no `instructions:` field. `crosscheck optimize --apply` writes to that file to persist learned improvements across sessions.
962
+
963
+ To reset instructions.md to defaults, delete the file:
804
964
  ```bash
805
965
  rm ~/.crosscheck/instructions.md
806
966
  ```
807
- The next review will re-seed it from the built-in defaults.
808
967
 
809
- ### Can I have per-project instructions?
968
+ ### Can I have per-project workflow?
810
969
 
811
- Yes. Create `.crosscheck/instructions.md` in your repo root. crosscheck checks for a project-level file first and uses it instead of the user-level one. This lets you enforce project-specific constraints (e.g. "this is a Rust project do not suggest TypeScript patterns") without affecting other repos.
970
+ Yes. Create `.crosscheck/workflow.yml` in your repo root. crosscheck loads it automatically and uses it instead of the built-in default pipeline. This is the recommended way to customize reviewer behavior it keeps all per-project settings in one file under version control.
812
971
 
813
972
  ### What is `AGENT.md`?
814
973
 
@@ -835,7 +994,7 @@ crosscheck fetches the PR base branch (e.g. `staging`) into the temp clone befor
835
994
  npm install -g smee-client
836
995
  ```
837
996
 
838
- Visit [smee.io/new](https://smee.io/new) and copy the channel URL. Then in `crosscheck.config.yml`:
997
+ Visit [smee.io/new](https://smee.io/new) and copy the channel URL. Then in `~/.crosscheck/config.yml`:
839
998
 
840
999
  ```yaml
841
1000
  tunnel:
@@ -843,8 +1002,18 @@ tunnel:
843
1002
  smee_channel: https://smee.io/your-channel-id
844
1003
  ```
845
1004
 
846
- Register the smee channel URL as your GitHub webhook Payload URL once. crosscheck will forward events from the channel to the local server automatically. Unlike `localhost.run`, no re-registration is needed on restart.
1005
+ crosscheck registers the smee channel URL as your GitHub webhook automatically on first `watch` start. The channel URL never changes, so no re-registration is needed on restart. Unlike `localhost.run`, events are queued while you're offline and replayed when you reconnect.
1006
+
1007
+
1008
+ ### Can I disable the auto-fix step?
1009
+
1010
+ Yes. Set `post_review.auto_fix.enabled: false` in your config, or set `trigger: never`. You can also raise `min_severity` to `error` to limit fixes to blocking issues only.
1011
+
1012
+ To push fixes directly without a separate PR (skipping your review), switch to `delivery: commit`. To get suggested fixes as review comments without any code push, use `delivery: comment`.
1013
+
1014
+ ### Why does the fixer use the same vendor that wrote the PR?
847
1015
 
1016
+ The authoring agent has the most context about its own code — the same style, constraints, and intent behind the original changes. Using `fixer: same-as-author` keeps the feedback loop tight: the agent writes the code, another agent reviews it, the original agent fixes it. You can override this to `same-as-reviewer`, `codex`, or `claude` if you prefer a different arrangement.
848
1017
 
849
1018
  ### Does optimize run automatically?
850
1019
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motivation-labs/crosscheck",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Cross-vendor AI code review orchestrator — Claude Code ↔ Codex",
5
5
  "bin": {
6
6
  "crosscheck": "dist/cli.js"