reviewgate 0.1.0__tar.gz

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 (83) hide show
  1. reviewgate-0.1.0/.code-review-graph/.gitignore +3 -0
  2. reviewgate-0.1.0/.code-review-graph/graph.db +0 -0
  3. reviewgate-0.1.0/.github/workflows/agentboard-review.yml +100 -0
  4. reviewgate-0.1.0/.github/workflows/ci.yml +48 -0
  5. reviewgate-0.1.0/.gitignore +11 -0
  6. reviewgate-0.1.0/BENCHMARK.md +163 -0
  7. reviewgate-0.1.0/CONTRIBUTING.md +70 -0
  8. reviewgate-0.1.0/LICENSE +5 -0
  9. reviewgate-0.1.0/PKG-INFO +305 -0
  10. reviewgate-0.1.0/README.md +276 -0
  11. reviewgate-0.1.0/ROADMAP.md +134 -0
  12. reviewgate-0.1.0/bench/report.py +83 -0
  13. reviewgate-0.1.0/examples/paired_run.py +91 -0
  14. reviewgate-0.1.0/examples/run_fk_graph.py +89 -0
  15. reviewgate-0.1.0/examples/run_reliability_5x.py +124 -0
  16. reviewgate-0.1.0/examples/run_repo_review.py +97 -0
  17. reviewgate-0.1.0/examples/run_repo_review_llm.py +70 -0
  18. reviewgate-0.1.0/examples/run_review.py +135 -0
  19. reviewgate-0.1.0/examples/run_review_composite_fk.py +136 -0
  20. reviewgate-0.1.0/examples/run_review_fix.py +108 -0
  21. reviewgate-0.1.0/examples/run_review_perfile.py +83 -0
  22. reviewgate-0.1.0/examples/run_text_review.py +38 -0
  23. reviewgate-0.1.0/pyproject.toml +59 -0
  24. reviewgate-0.1.0/review_board_run2.html +723 -0
  25. reviewgate-0.1.0/review_board_run3.html +675 -0
  26. reviewgate-0.1.0/scripts/render_pr_comment.py +116 -0
  27. reviewgate-0.1.0/src/agentboard/__init__.py +62 -0
  28. reviewgate-0.1.0/src/agentboard/agents/__init__.py +0 -0
  29. reviewgate-0.1.0/src/agentboard/agents/critic_agent.py +174 -0
  30. reviewgate-0.1.0/src/agentboard/agents/fix_agent.py +98 -0
  31. reviewgate-0.1.0/src/agentboard/agents/fix_with_test_agent.py +135 -0
  32. reviewgate-0.1.0/src/agentboard/agents/gap_auditor.py +166 -0
  33. reviewgate-0.1.0/src/agentboard/agents/openai_agent.py +140 -0
  34. reviewgate-0.1.0/src/agentboard/agents/openai_explainer.py +77 -0
  35. reviewgate-0.1.0/src/agentboard/agents/peer_reviewer.py +184 -0
  36. reviewgate-0.1.0/src/agentboard/agents/reviewer_agent.py +253 -0
  37. reviewgate-0.1.0/src/agentboard/cli.py +771 -0
  38. reviewgate-0.1.0/src/agentboard/config.py +296 -0
  39. reviewgate-0.1.0/src/agentboard/dataset.py +192 -0
  40. reviewgate-0.1.0/src/agentboard/demo/__init__.py +10 -0
  41. reviewgate-0.1.0/src/agentboard/demo/target/demo.test.js +14 -0
  42. reviewgate-0.1.0/src/agentboard/demo/target/order_tool.js +22 -0
  43. reviewgate-0.1.0/src/agentboard/demo/target/package.json +7 -0
  44. reviewgate-0.1.0/src/agentboard/fingerprint.py +62 -0
  45. reviewgate-0.1.0/src/agentboard/graph.py +186 -0
  46. reviewgate-0.1.0/src/agentboard/ingestion/__init__.py +0 -0
  47. reviewgate-0.1.0/src/agentboard/ingestion/intent.py +48 -0
  48. reviewgate-0.1.0/src/agentboard/ingestion/output_invariants.py +113 -0
  49. reviewgate-0.1.0/src/agentboard/ingestion/pr_diff.py +111 -0
  50. reviewgate-0.1.0/src/agentboard/ingestion/repo_adapter.py +36 -0
  51. reviewgate-0.1.0/src/agentboard/ingestion/tech_detect.py +119 -0
  52. reviewgate-0.1.0/src/agentboard/ingestion/text_adapter.py +27 -0
  53. reviewgate-0.1.0/src/agentboard/interfaces.py +85 -0
  54. reviewgate-0.1.0/src/agentboard/loop.py +203 -0
  55. reviewgate-0.1.0/src/agentboard/personas.py +103 -0
  56. reviewgate-0.1.0/src/agentboard/proposal_cache.py +147 -0
  57. reviewgate-0.1.0/src/agentboard/review.py +185 -0
  58. reviewgate-0.1.0/src/agentboard/state.py +121 -0
  59. reviewgate-0.1.0/src/agentboard/verifiers/__init__.py +0 -0
  60. reviewgate-0.1.0/src/agentboard/verifiers/assertion_lint.py +59 -0
  61. reviewgate-0.1.0/src/agentboard/verifiers/finding_verifier.py +575 -0
  62. reviewgate-0.1.0/src/agentboard/verifiers/pytest_verifier.py +114 -0
  63. reviewgate-0.1.0/src/agentboard/verifiers/schema_verifier.py +53 -0
  64. reviewgate-0.1.0/src/agentboard/verifiers/transition_verifier.py +208 -0
  65. reviewgate-0.1.0/src/agentboard/verifiers/vitest_verifier.py +353 -0
  66. reviewgate-0.1.0/src/agentboard/whiteboards/__init__.py +0 -0
  67. reviewgate-0.1.0/src/agentboard/whiteboards/flow_adapter.py +314 -0
  68. reviewgate-0.1.0/src/agentboard/whiteboards/html_adapter.py +104 -0
  69. reviewgate-0.1.0/src/agentboard/whiteboards/tldraw_adapter.py +28 -0
  70. reviewgate-0.1.0/tests/test_audit_wiring.py +174 -0
  71. reviewgate-0.1.0/tests/test_config_preflight.py +207 -0
  72. reviewgate-0.1.0/tests/test_dataset.py +118 -0
  73. reviewgate-0.1.0/tests/test_determinism.py +202 -0
  74. reviewgate-0.1.0/tests/test_env_scrub.py +61 -0
  75. reviewgate-0.1.0/tests/test_failure_classification.py +58 -0
  76. reviewgate-0.1.0/tests/test_gate_e2e.py +166 -0
  77. reviewgate-0.1.0/tests/test_injection_placement.py +92 -0
  78. reviewgate-0.1.0/tests/test_loop.py +55 -0
  79. reviewgate-0.1.0/tests/test_multitarget.py +60 -0
  80. reviewgate-0.1.0/tests/test_openai_agent.py +66 -0
  81. reviewgate-0.1.0/tests/test_pnpm_pin.py +69 -0
  82. reviewgate-0.1.0/tests/test_proposal_cache.py +104 -0
  83. reviewgate-0.1.0/tests/test_sandbox_trust.py +231 -0
@@ -0,0 +1,3 @@
1
+ # Auto-generated by code-review-graph — do not commit database files.
2
+ # The graph.db contains absolute paths and code structure metadata.
3
+ *
@@ -0,0 +1,100 @@
1
+ name: agentboard review
2
+
3
+ # Advisory pre-merge review: an LLM proposes edge-case tests, a deterministic
4
+ # gate executes them against this PR's code, and the evidence lands as a PR
5
+ # comment. Never blocking: confirmed gaps live in the comment, not the exit
6
+ # code. A human decides.
7
+ #
8
+ # Fork PRs are skipped by design: they cannot access OPENAI_API_KEY (repo
9
+ # secrets are withheld from forks), and that is correct; do not work around
10
+ # it.
11
+
12
+ on:
13
+ pull_request:
14
+
15
+ permissions:
16
+ contents: read
17
+ pull-requests: write
18
+
19
+ jobs:
20
+ review:
21
+ # Same-repo PRs only: forks have no access to the key.
22
+ if: github.event.pull_request.head.repo.full_name == github.repository
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ with:
27
+ fetch-depth: 0
28
+ ref: ${{ github.event.pull_request.head.sha }}
29
+
30
+ - uses: actions/setup-python@v5
31
+ with:
32
+ python-version: "3.12"
33
+
34
+ - uses: actions/setup-node@v4
35
+ with:
36
+ node-version: "22"
37
+
38
+ - name: Install agentboard
39
+ # In agentboard's own repo this installs the PR's code (true
40
+ # dogfooding); in any other repo the local install fails fast and
41
+ # the fallback pulls the published tool.
42
+ run: pip install -e . 2>/dev/null || pip install git+https://github.com/anp0429/agentboard
43
+
44
+ - name: Pick a reviewable target from the PR's changed files
45
+ id: target
46
+ env:
47
+ BASE_SHA: ${{ github.event.pull_request.base.sha }}
48
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
49
+ run: |
50
+ target=$(git diff --name-only "$BASE_SHA...$HEAD_SHA" \
51
+ | grep -E '\.(ts|tsx|js|jsx|mjs)$' \
52
+ | grep -vE '\.test\.|\.spec\.|/tests?/|__tests__' \
53
+ | head -1 || true)
54
+ echo "target=$target" >> "$GITHUB_OUTPUT"
55
+ if [ -z "$target" ]; then
56
+ echo "No reviewable source change in this PR; skipping quietly."
57
+ fi
58
+
59
+ - name: Review
60
+ if: steps.target.outputs.target != ''
61
+ env:
62
+ OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
63
+ BASE_SHA: ${{ github.event.pull_request.base.sha }}
64
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
65
+ # Filenames are PR-controlled data. Passing through env (not inline
66
+ # expression interpolation) keeps shell metacharacters inert.
67
+ TARGET: ${{ steps.target.outputs.target }}
68
+ run: |
69
+ agentboard review \
70
+ --repo . \
71
+ --target "$TARGET" \
72
+ --base "$BASE_SHA" \
73
+ --head "$HEAD_SHA" \
74
+ --json-out agentboard-run.json \
75
+ --board agentboard-board.html
76
+
77
+ - name: Render comment
78
+ if: steps.target.outputs.target != ''
79
+ run: python3 scripts/render_pr_comment.py agentboard-run.json > agentboard-comment.md
80
+
81
+ - name: Post or update the sticky comment
82
+ if: steps.target.outputs.target != ''
83
+ uses: actions/github-script@v7
84
+ with:
85
+ script: |
86
+ const fs = require("fs");
87
+ const body = fs.readFileSync("agentboard-comment.md", "utf8");
88
+ const marker = "<!-- agentboard-review -->";
89
+ const { owner, repo } = context.repo;
90
+ const issue_number = context.payload.pull_request.number;
91
+ const { data: comments } = await github.rest.issues.listComments(
92
+ { owner, repo, issue_number, per_page: 100 });
93
+ const mine = comments.find(c => c.body && c.body.includes(marker));
94
+ if (mine) {
95
+ await github.rest.issues.updateComment(
96
+ { owner, repo, comment_id: mine.id, body });
97
+ } else {
98
+ await github.rest.issues.createComment(
99
+ { owner, repo, issue_number, body });
100
+ }
@@ -0,0 +1,48 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ python-version: ["3.11", "3.12"]
16
+
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install package and test dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install -e .
29
+ pip install pytest
30
+
31
+ # The verifier/gate is unit-testable without any API key — that's the point.
32
+ - name: Run unit tests (no API key required)
33
+ env:
34
+ PYTHONPATH: src
35
+ run: python -m pytest tests/ -q
36
+
37
+ lint:
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+ - uses: actions/setup-python@v5
42
+ with:
43
+ python-version: "3.12"
44
+ - name: Install ruff
45
+ run: pip install ruff
46
+ - name: Lint
47
+ run: ruff check src/ tests/ examples/
48
+ continue-on-error: true # advisory for now; tighten after first green run
@@ -0,0 +1,11 @@
1
+
2
+ __pycache__/
3
+ .DS_Store
4
+ review_board.html
5
+ .env*
6
+ node_modules/
7
+ package-lock.json
8
+ agentboard_demo_board.html
9
+ review_board.html
10
+ paired_board_*.html
11
+ zod_board_*.html
@@ -0,0 +1,163 @@
1
+ # Benchmark
2
+
3
+ Can agentboard find a real bug in code it has never seen, from an intent
4
+ that does not name the bug? This measures that, on recent merged bugfix PRs
5
+ from active TypeScript repositories, and publishes the misses.
6
+
7
+ ## Method
8
+
9
+ For each row:
10
+
11
+ 1. Pick a bugfix PR that is already merged into an active repo.
12
+ 2. Check out the PR's **parent** commit — the code exactly as it was before
13
+ the fix. The bug is present.
14
+ 3. Run agentboard with a **neutral intent** that describes what the module
15
+ is for, never what the bug is. PR titles telegraph the answer, so the PR
16
+ and its tests are ground truth, not input.
17
+ 4. Score the confirmed gaps against the fix, by reading source.
18
+
19
+ The intent discipline is the whole experiment. "recursively merge an object
20
+ with default values" is a fair description of defu; "prevent prototype
21
+ pollution via `__proto__`" would be handing over the answer. If a skeptic
22
+ can argue the intent leaked the bug, the row does not count.
23
+
24
+ No row uses the bug agentboard was originally developed against
25
+ (supabase/mcp #317). Training on your test set is not a benchmark; #317
26
+ appears only as a disclosed reference case in the README.
27
+
28
+ Every gap in this table was adjudicated by reading the fix diff or the
29
+ source at the parent commit. The auditor's advisory calls were **not**
30
+ trusted as scores — see the auditor-inversion note below for why that
31
+ matters.
32
+
33
+ ## Results
34
+
35
+ Tool version `e175535`. 12 distinct bugs across 8 repos (two rows are
36
+ security-axis twins). Zero environment failures.
37
+
38
+ | # | Repo | PR | Target module | Outcome |
39
+ |---|------|----|--------------|---------|
40
+ | s1 | supabase/mcp | #269 | content-api graphql | in-area catch |
41
+ | s2 | supabase/mcp | #329 | management-api errors | miss (4 clean false positives) |
42
+ | r1 | unjs/ufo | #335 | url base join/strip | missed #335, **re-found #360** |
43
+ | r2 | unjs/ufo | #313 | url base prefix match | **strict catch** |
44
+ | r3 | unjs/defu | #156 | recursive default merge | **strict catch** (`__proto__` pollution) |
45
+ | r4 | unjs/pathe | #246 | path resolve | **strict catch** (UNC authority) |
46
+ | r5 | unjs/pathe | #241 | path parse | in-area catch (node divergence) |
47
+ | r6 | pmndrs/jotai | #3354 | store subscribe | miss (subtle async) |
48
+ | r7 | pmndrs/jotai | #3326 | atomWithStorage | miss (component harness) |
49
+ | r8 | vueuse/vueuse | #5525 | useFetch | **in-area catch + 2 bonus bugs** |
50
+ | r9 | TanStack/query | #10812 | devtools sort | **strict catch** |
51
+ | r10 | colinhacks/zod | #5898 | object catchall | miss (wrong-remedy assertion) |
52
+
53
+ Security-axis twins: r3s (defu) reproduced the strict catch and added a
54
+ nested `__proto__` variant the default axis missed; r10s (zod) missed the
55
+ same way the default did.
56
+
57
+ **Summary: 8 of 12 rows produced a real confirmed bug. 4 were exact strict
58
+ catches (ufo #313, defu #156, pathe #246, query #10812). r8 over-delivered:
59
+ pointed at vueuse before a known fix, it caught the fix's neighborhood and
60
+ two additional real bugs the PR never touched (a falsy-`initialData` bug
61
+ from `||` where `??` was meant, and a header-array-merge bug). 4 rows
62
+ missed. 0 environment failures.**
63
+
64
+ ### The two bonus bugs (r8)
65
+
66
+ vueuse `useFetch`, at the parent of #5525, neutral intent "fetch a URL
67
+ reactively with abort and refetch support":
68
+
69
+ - `const data = shallowRef<T | null>(initialData || null)` — `||` coerces a
70
+ valid falsy `initialData` (`0`, `''`, `false`) to `null`. Should be `??`.
71
+ - `headersToObject` only handles `Headers` instances, silently dropping
72
+ array-form `HeadersInit` (`[['authorization', ...]]`).
73
+
74
+ Neither is what #5525 fixed. Both are real, both were found from a neutral
75
+ intent, both have an executed failing test attached.
76
+
77
+ ## The auditor inverted, twice — and that is the point
78
+
79
+ The auditor is a second model (Claude) that reads the source and flags
80
+ confirmed gaps it believes assert something the code never promised. It is
81
+ **advisory**: it never changes a verdict.
82
+
83
+ On two rows it called a **real strict catch** a false positive:
84
+
85
+ - **r2 (ufo #313):** the code matched `/api` as a prefix of `/api-v2`. The
86
+ auditor called the failing test a wrong assumption.
87
+ - **r9 (query #10812):** the comparator `(a, b) => a < b ? 1 : -1` never
88
+ returns `0` for ties, violating the comparator contract — the exact thing
89
+ #10812 fixed. The auditor flagged it a false positive **and cited the
90
+ buggy line as evidence**, mistaking the bug for the contract.
91
+
92
+ A calibration pass (a false-positive call must now quote the source line it
93
+ relies on, or it downgrades) made the auditor's output more useful but did
94
+ **not** stop this: it can cite the buggy code as if that code were the
95
+ specification. This is the benchmark's most important finding, and it is the
96
+ thesis proving itself inside the tool. The judging model was confidently
97
+ wrong. Execution was right. That is exactly why the verdict comes from the
98
+ gate and never from a model — the auditor is a lead, not a ruling, and every
99
+ gap in this table was adjudicated by a human reading source.
100
+
101
+ ## Misses, in daylight
102
+
103
+ - **s2 (supabase #329):** four gaps, all false positives — the proposals
104
+ asserted `.length` on a formatted string result. The real fix (a 403
105
+ org-scoping error message) was never approached. The auditor correctly
106
+ flagged all four.
107
+ - **r6 (jotai #3354):** a subscriber-notification bug that only manifests
108
+ after a nested `store.set` with sub/unsub inside a write. Too subtle for
109
+ the proposer; two false positives instead.
110
+ - **r7 (jotai #3326):** a React component target. The proposer wrote React
111
+ Testing Library tests with wrong DOM assumptions; the gate correctly
112
+ classified them `broken_test` rather than gaps. Complex component harnesses
113
+ are a real reviewer-capability limit.
114
+ - **r10 (zod #5898):** the `__proto__` catchall bug is present, but the
115
+ proposer asserted the wrong remedy (expected `__proto__` as a visible data
116
+ key) rather than the real defect (prototype pollution). The bug class was
117
+ right, the assertion was wrong. Same bug class as defu #156, opposite
118
+ outcome — see below.
119
+
120
+ ## Assertion quality is the frontier
121
+
122
+ defu #156 and zod #5898 are both `__proto__` bugs. defu's proposal asserted
123
+ *the prototype was not polluted* and caught the bug. zod's asserted
124
+ *`__proto__` should appear as a data key* and missed it, producing a false
125
+ positive on a real defect. Same vulnerability, opposite result, decided
126
+ entirely by what the model chose to assert. Improving assertion quality —
127
+ not reaching the topic — is the open problem this benchmark surfaces, and it
128
+ is the training signal behind the roadmap's model work.
129
+
130
+ ## Determinism receipts
131
+
132
+ Every run prints a fingerprint over its verdicts. Six rows were run on two
133
+ separate days, through a proposal-cache hit and a changed advisory layer,
134
+ and reproduced byte-identical fingerprints:
135
+
136
+ | Row | fingerprint (both runs) |
137
+ |-----|-------------------------|
138
+ | s1 | `d64b434d0833afcf` |
139
+ | s2 | `3811dc33363f9751` |
140
+ | r1 | `6e9bb41299792a83` |
141
+ | r3 | `b6a7bd31e37e5bb7` |
142
+ | r4 | `35d6c88385a680c2` |
143
+ | r10 | `f7214bf3b971ad1c` |
144
+
145
+ The auditor changed between the two runs; the fingerprints did not, because
146
+ the auditor is advisory and never enters the verdict. When verdict-side code
147
+ changed, every row was rerun on one tool version rather than mixing.
148
+
149
+ ## Reproduce
150
+
151
+ Each row is a fresh checkout at the parent commit, `--base HEAD` (empty
152
+ change, stranger-mode review), a neutral intent, and the auditor on:
153
+
154
+ ```
155
+ git clone <repo> && cd <repo> && git checkout <parent-sha>
156
+ agentboard review --repo . --target <file> --tests <tests> \
157
+ --head HEAD --base HEAD --intent "<neutral intent>" \
158
+ --audit-model claude-sonnet-5 --json-out run.json
159
+ ```
160
+
161
+ Parent SHAs, targets, and neutral intents for all rows are in
162
+ `bench/run_bench.sh`. Environment failures, when they occur, are reported as
163
+ failures, never retried until green.
@@ -0,0 +1,70 @@
1
+ # Contributing to agentboard
2
+
3
+ Thanks for looking. agentboard is a review gate with one non-negotiable idea:
4
+ **a model may propose, but only executed tests decide.** Contributions are
5
+ welcome as long as they hold that line.
6
+
7
+ ## The invariants (do not break these)
8
+
9
+ These are the whole reason the tool is trustworthy. A change that violates one
10
+ will not be merged, however useful it looks otherwise.
11
+
12
+ 1. **The verdict is deterministic and model-free.** No LLM sits in the
13
+ pass/fail path. A behavior becomes a `confirmed_gap` only if a proposed test
14
+ compiles, runs, and fails its assertion on the real code.
15
+ 2. **A garbage test cannot manufacture a finding.** A test that crashes or
16
+ fails to load is classified against the test (`broken_test`), never against
17
+ the code under review. Only a named assertion failure is a gap.
18
+ 3. **The auditor is advisory.** A second model may flag a likely false
19
+ positive, with a quoted source line. It never changes a verdict. It has been
20
+ wrong (see `BENCHMARK.md`); the gate has the final word, always.
21
+ 4. **Per-finding isolation.** Every proposed test runs against a clean checkout
22
+ of the repo; no finding sees another's injected test.
23
+ 5. **The engine knows nothing about GitHub.** CI and MCP are adapters over the
24
+ `--json-out` schema. Keep PR-shaped concepts out of the core.
25
+
26
+ If your change touches the gate, the classifier, or the cache key, add a test
27
+ that pins the behavior. `tests/` has examples of the style, including
28
+ falsifier invariants (an impossible test must always read as a real failure).
29
+
30
+ ## Development
31
+
32
+ ```
33
+ git clone https://github.com/anp0429/agentboard
34
+ cd agentboard
35
+ pip install -e ".[dev]"
36
+ PYTHONPATH=src python -m pytest tests/ -q
37
+ ```
38
+
39
+ The demo runs with no API key and exercises the deterministic gate:
40
+
41
+ ```
42
+ agentboard demo
43
+ agentboard demo --fixed
44
+ ```
45
+
46
+ A live review needs `OPENAI_API_KEY` (reviewer) and, for the auditor,
47
+ `ANTHROPIC_API_KEY`. Reviews on real repos run vitest, so Node is required for
48
+ those; the Python test suite does not need it.
49
+
50
+ ## Before you open a PR
51
+
52
+ - `PYTHONPATH=src python -m pytest tests/ -q` passes.
53
+ - `ruff check src/ tests/` is clean (advisory today, tightening over time).
54
+ - New behavior has a test. New verdict-path behavior has a test that would fail
55
+ without your change.
56
+ - If you changed anything the benchmark exercises, say so; `BENCHMARK.md`
57
+ documents the method and the honest misses, and we keep it honest.
58
+
59
+ ## What is especially welcome
60
+
61
+ - New `RepoProfile` presets or `.agentboard.toml` recipes for repos that need
62
+ scoping (multiple vitest projects, per-package monorepos).
63
+ - A pytest gate (the current gate is vitest-only; `PytestVerifier` exists but
64
+ speaks the older protocol).
65
+ - Benchmark rows: a merged bugfix PR, run at its parent commit with a neutral
66
+ intent, scored honestly including misses.
67
+
68
+ ## Reporting a security issue
69
+
70
+ Please use GitHub's private vulnerability reporting rather than a public issue.
@@ -0,0 +1,5 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ankita
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction...