From 86ae001cda82f109cc2842d893a095ad99ba8cf9 Mon Sep 17 00:00:00 2001 From: plind-junior <59729252+plind-junior@users.noreply.github.com> Date: Sat, 27 Jun 2026 05:10:33 +0900 Subject: [PATCH 1/6] chore: remove stale pr body draft --- PR_BODY.md | 79 ------------------------------------------------------ 1 file changed, 79 deletions(-) delete mode 100644 PR_BODY.md diff --git a/PR_BODY.md b/PR_BODY.md deleted file mode 100644 index 783ad6f6..00000000 --- a/PR_BODY.md +++ /dev/null @@ -1,79 +0,0 @@ -# feat(synthesize): `kb.synthesize` answer-mode retrieval over the review-gated KB - -## What changed - -Adds `kb.synthesize` — an answer-mode counterpart to `kb.context`. Where -`kb.context` returns a *ranked list* of relevant items, `kb.synthesize` -answers a query in prose, but strictly from **approved (durable) claims**, -with an inline `[claim_id]` citation behind every sentence. - -New surface, wired across all three transports that the capabilities test -keeps in sync: - -- `src/vouch/synthesize.py` — `synthesize(store, *, query, depth=3, - max_chars=4000, llm=False)`. Walks `build_context_pack(... limit=depth)`, - keeps only `claim` items that resolve to a durable claim via - `store.get_claim`, and composes a deterministic answer: one short, - single-clause sentence per claim, each carrying at least one `[claim_id]` - citation. No sentence is emitted that isn't traceable to a claim id. - `max_chars` truncates by dropping trailing claims (never by cutting a - citation). Returns - `{"query", "answer", "claims", "gaps", "_meta": {"synthesis_confidence"}}`. - `gaps` lists the query's salient terms for which no approved claim was - found (and is the whole answer when nothing matched). `synthesis_confidence` - is `high` when every cited claim is `stable`, `medium` when any is - `working`/`actionable`, `low` when any is `contested`. `llm=True` raises - (reserved for an opt-in generative backend; deterministic synthesis is the - v1 default). -- `src/vouch/capabilities.py` — `kb.synthesize` appended to `METHODS`. -- `src/vouch/jsonl_server.py` — `_h_synthesize` handler + `HANDLERS` entry. -- `src/vouch/server.py` — `@mcp.tool() kb_synthesize(query, depth=3, - max_chars=4000)`. -- `src/vouch/cli.py` — `vouch synthesize "" [--depth N] [--max-chars N]`. -- `CHANGELOG.md` — `### Added` bullet under `## [Unreleased]`. - -## Why / root cause - -`kb.context` is a retrieval primitive: it ranks and budgets items but leaves -answer composition (and the discipline of *only* using approved knowledge) to -the caller. There was no first-class way to ask the KB a question and get a -prose answer whose every clause is provably backed by a reviewed claim, with -the uncovered parts of the question surfaced rather than silently dropped. -`kb.synthesize` fills that gap deterministically — citation-gated by -construction, so it cannot fabricate an unbacked sentence — and grades its own -confidence from the lifecycle status of the claims it actually cited. - -## Test plan - -`tests/test_synthesize.py` covers: - -- 3 approved `auth` claims → non-empty answer citing all 3 ids by `[id]`, - confidence `high`. -- A query the KB doesn't cover → `answer == ""`, `claims == []`, `gaps` - populated with the query's salient terms. -- Fuzz/traceability: every sentence in a non-empty answer carries at least one - `[id]` citation whose id is in `claims` and resolves via `store.get_claim`. -- `max_chars` drops trailing claims without cutting a citation - (citation count == cited-claim count). -- Confidence reflects claim status (`working` → medium, `contested` → low). -- `llm=True` raises the reserved-backend `ValueError`. -- `kb.synthesize` is in `capabilities().methods` and in the JSONL `HANDLERS`, - and is callable via `handle_request` end-to-end. - -Verification gate (fresh venv, editable install of this worktree): - -``` -$ ./.venv/bin/ruff check src tests -All checks passed! - -$ ./.venv/bin/mypy src -Success: no issues found in 30 source files - -$ ./.venv/bin/python -m pytest -q -94 passed, 6 skipped in 0.81s -``` - -(The 6 skips are pre-existing numpy/embedding-optional tests, unrelated to this -change.) - -Closes #222 From ec5f0c266501b711e5d1b95a076cc5711dc34193 Mon Sep 17 00:00:00 2001 From: plind-junior <59729252+plind-junior@users.noreply.github.com> Date: Sat, 27 Jun 2026 05:40:29 +0900 Subject: [PATCH 2/6] ci: add pr auto labeling workflow --- .github/labeler.yml | 152 ++++++++++++++++++++++++ .github/workflows/labeler.yml | 184 ++++++++++++++++++++++++++++++ CHANGELOG.md | 4 + tests/test_pr_labeler_workflow.py | 70 ++++++++++++ 4 files changed, 410 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/workflows/labeler.yml create mode 100644 tests/test_pr_labeler_workflow.py diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000..27cfafa1 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,152 @@ +"docs": + - changed-files: + - any-glob-to-any-file: + - "*.md" + - "docs/**" + - "examples/**" + - "spec/**" + - "templates/README.md" + +"ci": + - changed-files: + - any-glob-to-any-file: + - ".github/**" + +"cli": + - changed-files: + - any-glob-to-any-file: + - "src/vouch/cli.py" + - "tests/test_cli.py" + +"auto-pr": + - changed-files: + - any-glob-to-any-file: + - "src/vouch/auto_pr.py" + - "skills/auto-pr/**" + - "tests/test_auto_pr.py" + +"dual-solve": + - changed-files: + - any-glob-to-any-file: + - "src/vouch/dual_solve.py" + - "src/vouch/sandbox.py" + - "src/vouch/web/dual_solve_api.py" + - "src/vouch/web/static/dual_solve.*" + - "src/vouch/web/templates/dual_solve.html" + - "tests/test_dual_solve.py" + - "tests/test_sandbox.py" + - "tests/test_web_dual_solve.py" + +"review-ui": + - changed-files: + - any-glob-to-any-file: + - "src/vouch/web/**" + - "docs/review-ui.md" + - "tests/test_web*.py" + +"website": + - changed-files: + - any-glob-to-any-file: + - "web/**" + +"adapters": + - changed-files: + - any-glob-to-any-file: + - "adapters/**" + - "src/vouch/install_adapter.py" + - "tests/test_install_adapter.py" + +"openclaw": + - changed-files: + - any-glob-to-any-file: + - "adapters/openclaw/**" + - "openclaw.plugin.json" + - "src/vouch/openclaw/**" + - "tests/test_openclaw*.py" + +"mcp": + - changed-files: + - any-glob-to-any-file: + - "src/vouch/capabilities.py" + - "src/vouch/http_server.py" + - "src/vouch/jsonl_server.py" + - "src/vouch/server.py" + - "tests/test_capabilities.py" + - "tests/test_http_server*.py" + - "tests/test_jsonl_server.py" + +"storage": + - changed-files: + - any-glob-to-any-file: + - "migrations/**" + - "src/vouch/audit.py" + - "src/vouch/bundle.py" + - "src/vouch/lifecycle.py" + - "src/vouch/migrations/**" + - "src/vouch/models.py" + - "src/vouch/page_kinds.py" + - "src/vouch/proposals.py" + - "src/vouch/storage.py" + - "templates/**" + - "tests/fixtures/migrations/**" + - "tests/test_audit*.py" + - "tests/test_bundle.py" + - "tests/test_migrations.py" + - "tests/test_page_kinds.py" + - "tests/test_schema_migrations.py" + - "tests/test_storage.py" + +"retrieval": + - changed-files: + - any-glob-to-any-file: + - "eval/**" + - "src/vouch/context.py" + - "src/vouch/eval/**" + - "src/vouch/graph.py" + - "src/vouch/hot_memory.py" + - "src/vouch/index_db.py" + - "src/vouch/salience.py" + - "src/vouch/synthesize.py" + - "src/vouch/volunteer_context.py" + - "tests/test_context.py" + - "tests/test_eval_recall.py" + - "tests/test_graph.py" + - "tests/test_index.py" + - "tests/test_retrieval_backend.py" + - "tests/test_salience.py" + - "tests/test_synthesize.py" + - "tests/test_volunteer_context.py" + +"embeddings": + - changed-files: + - any-glob-to-any-file: + - "src/vouch/embeddings/**" + - "tests/embeddings/**" + +"sync": + - changed-files: + - any-glob-to-any-file: + - "src/vouch/diff.py" + - "src/vouch/sync.py" + - "src/vouch/vault_sync.py" + - "tests/test_diff.py" + - "tests/test_sync.py" + - "tests/test_vault_sync.py" + +"schemas": + - changed-files: + - any-glob-to-any-file: + - "schemas/**" + - "scripts/gen_schemas.py" + +"packaging": + - changed-files: + - any-glob-to-any-file: + - "MANIFEST.in" + - "Makefile" + - "pyproject.toml" + +"tests": + - changed-files: + - any-glob-to-any-file: + - "tests/**" diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 00000000..7d7cbb42 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,184 @@ +name: labeler + +"on": + pull_request_target: + # This workflow only reads base-branch config and PR metadata. It never + # checks out or executes pull request code. + types: [opened, synchronize, reopened, edited, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: {} + +jobs: + label: + name: label pull request + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + pull-requests: write + steps: + - name: Ensure label taxonomy exists + uses: actions/github-script@v9 + with: + script: | + const labels = { + "docs": ["0A3069", "documentation, specs, examples, and repo guidance"], + "ci": ["E5E7EB", "github actions and automation"], + "cli": ["0A3069", "command line interface"], + "auto-pr": ["6E7781", "auto-pr orchestration"], + "dual-solve": ["6E7781", "dual-solve orchestration"], + "review-ui": ["0969DA", "browser review ui"], + "website": ["0969DA", "static website"], + "adapters": ["6E7781", "agent host adapters and install manifests"], + "openclaw": ["6E7781", "openclaw integration"], + "mcp": ["7057FF", "mcp, jsonl, and http surfaces"], + "storage": ["D6E3DA", "kb storage, migrations, schemas, and proposals"], + "retrieval": ["2DA44E", "context, search, synthesis, and evaluation"], + "embeddings": ["2DA44E", "embedding-backed retrieval"], + "sync": ["57606A", "sync, vault mirror, and diff flows"], + "schemas": ["F9D65C", "json schemas and generated schema assets"], + "packaging": ["E5E7EB", "packaging, build metadata, and make targets"], + "tests": ["F9D65C", "tests and fixtures"], + "size: XS": ["8C959F", "less than 50 changed non-doc lines"], + "size: S": ["8C959F", "50-199 changed non-doc lines"], + "size: M": ["8C959F", "200-499 changed non-doc lines"], + "size: L": ["8C959F", "500-999 changed non-doc lines"], + "size: XL": ["8C959F", "1000 or more changed non-doc lines"], + }; + + for (const [name, [color, description]] of Object.entries(labels)) { + try { + const current = await github.rest.issues.getLabel({ + ...context.repo, + name, + }); + if ( + current.data.color?.toLowerCase() !== color.toLowerCase() || + current.data.description !== description + ) { + await github.rest.issues.updateLabel({ + ...context.repo, + name, + color, + description, + }); + } + } catch (error) { + if (error?.status !== 404) { + throw error; + } + await github.rest.issues.createLabel({ + ...context.repo, + name, + color, + description, + }); + } + } + + - name: Apply path labels + uses: actions/labeler@v6 + with: + configuration-path: .github/labeler.yml + repo-token: ${{ secrets.GITHUB_TOKEN }} + sync-labels: true + + - name: Apply PR size label + uses: actions/github-script@v9 + with: + script: | + const pullRequest = context.payload.pull_request; + if (!pullRequest) { + return; + } + + const sizeLabels = ["size: XS", "size: S", "size: M", "size: L", "size: XL"]; + const files = await github.paginate(github.rest.pulls.listFiles, { + ...context.repo, + pull_number: pullRequest.number, + per_page: 100, + }); + + const excludedLockfiles = new Set([ + "bun.lockb", + "package-lock.json", + "npm-shrinkwrap.json", + "pnpm-lock.yaml", + "poetry.lock", + "uv.lock", + "yarn.lock", + ]); + const excludedDocFiles = new Set([ + "AGENTS.md", + "CHANGELOG.md", + "CLAUDE.md", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.md", + "GOVERNANCE.md", + "README.md", + "ROADMAP.md", + "SECURITY.md", + "llms.txt", + ]); + + function ignoredForSize(path) { + return ( + path.startsWith("docs/") || + path.startsWith("examples/") || + path.startsWith("spec/") || + excludedDocFiles.has(path) || + excludedLockfiles.has(path) || + path.endsWith("/package-lock.json") || + path.endsWith("/npm-shrinkwrap.json") + ); + } + + const totalChangedLines = files.reduce((total, file) => { + const path = file.filename ?? ""; + if (ignoredForSize(path)) { + return total; + } + return total + (file.additions ?? 0) + (file.deletions ?? 0); + }, 0); + + let target = "size: XL"; + if (totalChangedLines < 50) { + target = "size: XS"; + } else if (totalChangedLines < 200) { + target = "size: S"; + } else if (totalChangedLines < 500) { + target = "size: M"; + } else if (totalChangedLines < 1000) { + target = "size: L"; + } + + const currentLabels = await github.paginate( + github.rest.issues.listLabelsOnIssue, + { + ...context.repo, + issue_number: pullRequest.number, + per_page: 100, + }, + ); + + for (const label of currentLabels) { + const name = label.name ?? ""; + if (!sizeLabels.includes(name) || name === target) { + continue; + } + await github.rest.issues.removeLabel({ + ...context.repo, + issue_number: pullRequest.number, + name, + }); + } + + await github.rest.issues.addLabels({ + ...context.repo, + issue_number: pullRequest.number, + labels: [target], + }); diff --git a/CHANGELOG.md b/CHANGELOG.md index 75723dbd..5dab1d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ All notable changes to vouch are documented here. Format follows ## [Unreleased] ### Added +- GitHub PR auto-labeling: a pull-request metadata-only labeler workflow now + applies vouch surface labels from `.github/labeler.yml`, keeps those labels + in sync as files change, and adds OpenClaw-style `size: XS` through + `size: XL` labels based on non-doc changed lines. - `vouch dual-solve ` — run claude + codex on one github issue in isolated git worktrees, compare the two diffs, keep the branch you pick, and propose the chosen solution's rationale into the KB. A sibling tool to diff --git a/tests/test_pr_labeler_workflow.py b/tests/test_pr_labeler_workflow.py new file mode 100644 index 00000000..f7cb5b14 --- /dev/null +++ b/tests/test_pr_labeler_workflow.py @@ -0,0 +1,70 @@ +from __future__ import annotations + +from pathlib import Path + +import yaml + +ROOT = Path(__file__).resolve().parents[1] +LABELER = ROOT / ".github" / "labeler.yml" +WORKFLOW = ROOT / ".github" / "workflows" / "labeler.yml" + + +def _load_yaml(path: Path) -> dict: + loaded = yaml.safe_load(path.read_text(encoding="utf-8")) + assert isinstance(loaded, dict) + return loaded + + +def test_pr_labeler_taxonomy_covers_core_surfaces() -> None: + labels = _load_yaml(LABELER) + assert { + "docs", + "ci", + "cli", + "auto-pr", + "dual-solve", + "review-ui", + "adapters", + "openclaw", + "mcp", + "storage", + "retrieval", + "tests", + }.issubset(labels) + + for label, rules in labels.items(): + assert isinstance(label, str) and label + assert isinstance(rules, list) and rules, label + assert any("changed-files" in rule for rule in rules), label + + +def test_pr_labeler_workflow_is_pull_request_metadata_only() -> None: + workflow = _load_yaml(WORKFLOW) + triggers = workflow["on"] + assert "pull_request_target" in triggers + assert "pull_request" not in triggers + + steps = workflow["jobs"]["label"]["steps"] + used_actions = [step.get("uses", "") for step in steps] + assert "actions/labeler@v6" in used_actions + assert "actions/checkout@v4" not in used_actions + + labeler_step = next(step for step in steps if step.get("uses") == "actions/labeler@v6") + assert labeler_step["with"]["sync-labels"] is True + + +def test_pr_labeler_workflow_creates_every_configured_label() -> None: + labels = _load_yaml(LABELER) + workflow_text = WORKFLOW.read_text(encoding="utf-8") + for label in labels: + assert f'"{label}"' in workflow_text + + +def test_pr_labeler_size_labels_follow_openclaw_thresholds() -> None: + workflow_text = WORKFLOW.read_text(encoding="utf-8") + for label in ["size: XS", "size: S", "size: M", "size: L", "size: XL"]: + assert f'"{label}"' in workflow_text + for threshold in ["< 50", "< 200", "< 500", "< 1000"]: + assert threshold in workflow_text + for ignored_path in ["docs/", "examples/", "spec/", "package-lock.json"]: + assert ignored_path in workflow_text From adc702698cdb851fedeeaffaf79e8f2e67f703a4 Mon Sep 17 00:00:00 2001 From: plind-junior <59729252+plind-junior@users.noreply.github.com> Date: Sat, 27 Jun 2026 05:44:57 +0900 Subject: [PATCH 3/6] ci: harden pr labeler backfill --- .github/workflows/labeler.yml | 244 +++++++++++++++++++++++++++--- CHANGELOG.md | 3 +- tests/test_pr_labeler_workflow.py | 28 +++- 3 files changed, 253 insertions(+), 22 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 7d7cbb42..c442645b 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -1,28 +1,39 @@ -name: labeler +name: Labeler "on": pull_request_target: - # This workflow only reads base-branch config and PR metadata. It never - # checks out or executes pull request code. + # Maintainer-owned triage workflow: it reads base-branch config and PR + # metadata only. It never checks out or executes pull request code. types: [opened, synchronize, reopened, edited, ready_for_review] + workflow_dispatch: + inputs: + max_prs: + description: "Maximum number of open PRs to process (0 = all)" + required: false + default: "200" + per_page: + description: "PRs per page (1-100)" + required: false + default: "50" + +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request_target' }} permissions: {} jobs: - label: - name: label pull request - runs-on: ubuntu-latest + ensure-label-taxonomy: + name: ensure label taxonomy + runs-on: ubuntu-24.04 permissions: - contents: read issues: write - pull-requests: write steps: - name: Ensure label taxonomy exists - uses: actions/github-script@v9 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const labels = { @@ -80,15 +91,25 @@ jobs: } } + label: + name: label pull request + if: github.event_name == 'pull_request_target' + needs: ensure-label-taxonomy + runs-on: ubuntu-24.04 + permissions: + contents: read + issues: write + pull-requests: write + steps: - name: Apply path labels - uses: actions/labeler@v6 + uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6 with: configuration-path: .github/labeler.yml repo-token: ${{ secrets.GITHUB_TOKEN }} sync-labels: true - name: Apply PR size label - uses: actions/github-script@v9 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 with: script: | const pullRequest = context.payload.pull_request; @@ -164,6 +185,9 @@ jobs: per_page: 100, }, ); + const currentNames = new Set( + currentLabels.map((label) => label.name).filter((name) => typeof name === "string"), + ); for (const label of currentLabels) { const name = label.name ?? ""; @@ -175,10 +199,194 @@ jobs: issue_number: pullRequest.number, name, }); + currentNames.delete(name); } - await github.rest.issues.addLabels({ - ...context.repo, - issue_number: pullRequest.number, - labels: [target], - }); + if (!currentNames.has(target)) { + await github.rest.issues.addLabels({ + ...context.repo, + issue_number: pullRequest.number, + labels: [target], + }); + } + + backfill-pr-labels: + name: backfill open PR labels + if: github.event_name == 'workflow_dispatch' + needs: ensure-label-taxonomy + runs-on: ubuntu-24.04 + permissions: + contents: read + issues: write + pull-requests: write + steps: + - name: Collect open PR numbers + id: open-prs + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + with: + result-encoding: string + script: | + const inputs = context.payload.inputs ?? {}; + const maxPrsInput = inputs.max_prs ?? "200"; + const perPageInput = inputs.per_page ?? "50"; + const parsedMaxPrs = Number.parseInt(maxPrsInput, 10); + const parsedPerPage = Number.parseInt(perPageInput, 10); + const maxPrs = Number.isFinite(parsedMaxPrs) ? parsedMaxPrs : 200; + const perPage = Number.isFinite(parsedPerPage) + ? Math.min(100, Math.max(1, parsedPerPage)) + : 50; + const processAll = maxPrs <= 0; + const maxCount = processAll ? Number.POSITIVE_INFINITY : Math.max(1, maxPrs); + const numbers = []; + + let page = 1; + while (numbers.length < maxCount) { + const remaining = maxCount - numbers.length; + const pageSize = processAll ? perPage : Math.min(perPage, remaining); + const { data: pullRequests } = await github.rest.pulls.list({ + ...context.repo, + state: "open", + per_page: pageSize, + page, + }); + + if (pullRequests.length === 0) { + break; + } + + for (const pullRequest of pullRequests) { + if (!processAll && numbers.length >= maxCount) { + break; + } + numbers.push(String(pullRequest.number)); + } + + if (pullRequests.length < pageSize) { + break; + } + page += 1; + } + + core.info(`Collected ${numbers.length} open pull requests.`); + return numbers.join("\n"); + + - name: Backfill path labels + if: steps.open-prs.outputs.result != '' + uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6 + with: + configuration-path: .github/labeler.yml + repo-token: ${{ secrets.GITHUB_TOKEN }} + sync-labels: true + pr-number: ${{ steps.open-prs.outputs.result }} + + - name: Backfill PR size labels + if: steps.open-prs.outputs.result != '' + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + env: + PR_NUMBERS: ${{ steps.open-prs.outputs.result }} + with: + script: | + const sizeLabels = ["size: XS", "size: S", "size: M", "size: L", "size: XL"]; + const numbers = (process.env.PR_NUMBERS ?? "") + .split(/\s+/) + .map((raw) => Number.parseInt(raw, 10)) + .filter((number) => Number.isFinite(number)); + + const excludedLockfiles = new Set([ + "bun.lockb", + "package-lock.json", + "npm-shrinkwrap.json", + "pnpm-lock.yaml", + "poetry.lock", + "uv.lock", + "yarn.lock", + ]); + const excludedDocFiles = new Set([ + "AGENTS.md", + "CHANGELOG.md", + "CLAUDE.md", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.md", + "GOVERNANCE.md", + "README.md", + "ROADMAP.md", + "SECURITY.md", + "llms.txt", + ]); + + function ignoredForSize(path) { + return ( + path.startsWith("docs/") || + path.startsWith("examples/") || + path.startsWith("spec/") || + excludedDocFiles.has(path) || + excludedLockfiles.has(path) || + path.endsWith("/package-lock.json") || + path.endsWith("/npm-shrinkwrap.json") + ); + } + + async function applySizeLabel(pullNumber) { + const files = await github.paginate(github.rest.pulls.listFiles, { + ...context.repo, + pull_number: pullNumber, + per_page: 100, + }); + + const totalChangedLines = files.reduce((total, file) => { + const path = file.filename ?? ""; + if (ignoredForSize(path)) { + return total; + } + return total + (file.additions ?? 0) + (file.deletions ?? 0); + }, 0); + + let target = "size: XL"; + if (totalChangedLines < 50) { + target = "size: XS"; + } else if (totalChangedLines < 200) { + target = "size: S"; + } else if (totalChangedLines < 500) { + target = "size: M"; + } else if (totalChangedLines < 1000) { + target = "size: L"; + } + + const currentLabels = await github.paginate( + github.rest.issues.listLabelsOnIssue, + { + ...context.repo, + issue_number: pullNumber, + per_page: 100, + }, + ); + const currentNames = new Set( + currentLabels.map((label) => label.name).filter((name) => typeof name === "string"), + ); + + for (const label of currentLabels) { + const name = label.name ?? ""; + if (!sizeLabels.includes(name) || name === target) { + continue; + } + await github.rest.issues.removeLabel({ + ...context.repo, + issue_number: pullNumber, + name, + }); + currentNames.delete(name); + } + + if (!currentNames.has(target)) { + await github.rest.issues.addLabels({ + ...context.repo, + issue_number: pullNumber, + labels: [target], + }); + } + } + + for (const number of numbers) { + await applySizeLabel(number); + } + core.info(`Backfilled size labels for ${numbers.length} open pull requests.`); diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dab1d23..28c227bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,8 @@ All notable changes to vouch are documented here. Format follows - GitHub PR auto-labeling: a pull-request metadata-only labeler workflow now applies vouch surface labels from `.github/labeler.yml`, keeps those labels in sync as files change, and adds OpenClaw-style `size: XS` through - `size: XL` labels based on non-doc changed lines. + `size: XL` labels based on non-doc changed lines. Maintainers can also run + it manually to backfill labels on already-open PRs. - `vouch dual-solve ` — run claude + codex on one github issue in isolated git worktrees, compare the two diffs, keep the branch you pick, and propose the chosen solution's rationale into the KB. A sibling tool to diff --git a/tests/test_pr_labeler_workflow.py b/tests/test_pr_labeler_workflow.py index f7cb5b14..9495571d 100644 --- a/tests/test_pr_labeler_workflow.py +++ b/tests/test_pr_labeler_workflow.py @@ -42,16 +42,38 @@ def test_pr_labeler_workflow_is_pull_request_metadata_only() -> None: workflow = _load_yaml(WORKFLOW) triggers = workflow["on"] assert "pull_request_target" in triggers + assert "workflow_dispatch" in triggers assert "pull_request" not in triggers - steps = workflow["jobs"]["label"]["steps"] + jobs = workflow["jobs"] + assert jobs["label"]["if"] == "github.event_name == 'pull_request_target'" + assert jobs["backfill-pr-labels"]["if"] == "github.event_name == 'workflow_dispatch'" + + steps = [ + step + for job in jobs.values() + for step in job.get("steps", []) + ] used_actions = [step.get("uses", "") for step in steps] - assert "actions/labeler@v6" in used_actions + assert any( + action.startswith("actions/labeler@") + and not action.endswith("@v6") + for action in used_actions + ) assert "actions/checkout@v4" not in used_actions - labeler_step = next(step for step in steps if step.get("uses") == "actions/labeler@v6") + labeler_step = next( + step for step in jobs["label"]["steps"] + if step.get("uses", "").startswith("actions/labeler@") + ) assert labeler_step["with"]["sync-labels"] is True + backfill_step = next( + step for step in jobs["backfill-pr-labels"]["steps"] + if step.get("uses", "").startswith("actions/labeler@") + ) + assert backfill_step["with"]["pr-number"] == "${{ steps.open-prs.outputs.result }}" + def test_pr_labeler_workflow_creates_every_configured_label() -> None: labels = _load_yaml(LABELER) From 73e56d3895ef60668eb1288759af1022dd842636 Mon Sep 17 00:00:00 2001 From: dripsmvcp <138900956+dripsmvcp@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:18:42 +0900 Subject: [PATCH 4/6] feat(desktop): file-changes tree view in dual-solve panes each dual-solve candidate pane showed a flat filename list plus a single column that stacked every changed file's hunks, which is hard to scan once a diff touches more than one or two files. replace that block with a reusable FileChanges view modeled on the gittensor-ui repositories components: a compact nested file tree (folders-first) as a narrow rail drives a content pane showing only the selected file's diff. selection is local per candidate, so the claude and codex panes navigate independently. - fileTree.ts: pure buildFileTree(paths) -> nested FileNode[], folders-first alphabetical, intermediate dirs synthesized from path segments; unit-tested. - diffParse.ts: lift parseDiff out of Diff.tsx so the renderer and the new view share one parser (behavior unchanged). - FileChanges.tsx: tree rail + per-file diff pane, derived entirely from the candidate's existing diff string. no new ipc or server change. - DualSolve.tsx: swap the ul + Diff block for . renderer-only. typecheck clean; 100 tests pass including 7 new tree cases. --- desktop/src/renderer/src/app.css | 10 ++ desktop/src/renderer/src/components/Diff.tsx | 48 +------- .../renderer/src/components/FileChanges.tsx | 103 ++++++++++++++++++ .../src/renderer/src/components/diffParse.ts | 45 ++++++++ .../src/renderer/src/components/fileTree.ts | 54 +++++++++ desktop/src/renderer/src/views/DualSolve.tsx | 9 +- desktop/test/file-tree.test.ts | 66 +++++++++++ 7 files changed, 284 insertions(+), 51 deletions(-) create mode 100644 desktop/src/renderer/src/components/FileChanges.tsx create mode 100644 desktop/src/renderer/src/components/diffParse.ts create mode 100644 desktop/src/renderer/src/components/fileTree.ts create mode 100644 desktop/test/file-tree.test.ts diff --git a/desktop/src/renderer/src/app.css b/desktop/src/renderer/src/app.css index 3b276402..61a5e739 100644 --- a/desktop/src/renderer/src/app.css +++ b/desktop/src/renderer/src/app.css @@ -255,6 +255,16 @@ details summary { cursor: pointer; color: var(--ink-2); } .dl.hunk { background: var(--panel); color: var(--sepia); } .dl.ctx { color: var(--ink-2); } +/* file-changes view (dual-solve candidate pane): tree rail + diff pane */ +.fc { display: flex; gap: 8px; align-items: stretch; max-height: 460px; } +.fc-rail { flex: 0 0 140px; max-width: 140px; overflow: auto; font-family: var(--mono); font-size: 11.5px; padding-right: 4px; border-right: 1px solid var(--line); } +.fc-pane { flex: 1 1 auto; min-width: 0; overflow: auto; } +.fc-dir { color: var(--ink-2); padding: 1px 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.fc-file { color: var(--ink); padding: 1px 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; border-radius: 3px; } +.fc-file:hover { background: var(--panel-2); } +.fc-file.sel { background: var(--verm-dim); color: var(--ink); } +.fc-empty { font-size: 12.5px; } + /* spinner / boxes */ .spinner-row { display: flex; align-items: center; gap: 8px; color: var(--ink-2); font-size: 12.5px; } .spinner { width: 13px; height: 13px; border: 2px solid var(--line-2); border-top-color: var(--verm); border-radius: 50%; animation: spin .7s linear infinite; } diff --git a/desktop/src/renderer/src/components/Diff.tsx b/desktop/src/renderer/src/components/Diff.tsx index adeced59..f39ef371 100644 --- a/desktop/src/renderer/src/components/Diff.tsx +++ b/desktop/src/renderer/src/components/Diff.tsx @@ -1,55 +1,15 @@ // Diff.tsx — minimal unified-diff renderer. -// Ported from src/renderer/views/dualsolve.js renderDiff (lines 162-179). -// Splits a unified diff string into per-file sections; colors +/-/context lines. +// Splits a unified diff into per-file sections (via the shared diffParse helper) +// and colors +/-/context lines. The dual-solve file-changes view reuses the +// same parser; this component stays for the all-files stacked rendering. import type { ReactNode } from 'react' +import { parseDiff } from './diffParse' interface DiffProps { diff?: string | null } -interface DiffLine { - cls: 'hunk' | 'add' | 'del' | 'ctx' - text: string -} - -interface DiffFile { - head: string - lines: DiffLine[] -} - -function parseDiff(diff: string): DiffFile[] { - const files: DiffFile[] = [] - let cur: DiffFile | null = null - - for (const line of diff.split('\n')) { - if (line.startsWith('diff --git')) { - const m = line.match(/ b\/(.+)$/) - cur = { head: m ? m[1] : line, lines: [] } - files.push(cur) - } else if (!cur) { - continue - } else if ( - line.startsWith('+++') || - line.startsWith('---') || - line.startsWith('index ') - ) { - continue - } else { - const cls: DiffLine['cls'] = line.startsWith('@@') - ? 'hunk' - : line.startsWith('+') - ? 'add' - : line.startsWith('-') - ? 'del' - : 'ctx' - cur.lines.push({ cls, text: line || ' ' }) - } - } - - return files -} - export function Diff({ diff }: DiffProps): ReactNode { const files = parseDiff(diff ?? '') diff --git a/desktop/src/renderer/src/components/FileChanges.tsx b/desktop/src/renderer/src/components/FileChanges.tsx new file mode 100644 index 00000000..20d2c57c --- /dev/null +++ b/desktop/src/renderer/src/components/FileChanges.tsx @@ -0,0 +1,103 @@ +// FileChanges.tsx — file-changes view for a dual-solve candidate. +// modeled on gittensor-ui's RepositoryCodeBrowser tree→content pattern, trimmed +// to changed files only: a compact nested file tree (folders-first) as a narrow +// left rail drives a content pane showing the selected file's diff hunks. +// +// selection is local state — two instances (claude / codex) are independent by +// design; one candidate's selection never affects the other. + +import { useMemo, useState, type ReactNode } from 'react' +import { parseDiff, type DiffFile } from './diffParse' +import { buildFileTree, type FileNode } from './fileTree' + +interface FileChangesProps { + diff?: string | null +} + +// recursive rail row: a directory label (non-interactive) or a clickable file. +function TreeRow({ + node, + depth, + selected, + onSelect, +}: { + node: FileNode + depth: number + selected: string | null + onSelect: (path: string) => void +}): ReactNode { + const pad = { paddingLeft: `${depth * 10}px` } + if (node.type === 'tree') { + return ( +
+
+ {node.name}/ +
+ {node.children?.map((c) => ( + + ))} +
+ ) + } + const cls = node.path === selected ? 'fc-file sel' : 'fc-file' + return ( +
onSelect(node.path)} + > + {node.name} +
+ ) +} + +export function FileChanges({ diff }: FileChangesProps): ReactNode { + const files: DiffFile[] = useMemo(() => parseDiff(diff ?? ''), [diff]) + const tree = useMemo(() => buildFileTree(files.map((f) => f.head)), [files]) + + // default selection = first changed file; falls back if the diff changes. + const firstPath = files[0]?.head ?? null + const [selected, setSelected] = useState(firstPath) + const activePath = + selected && files.some((f) => f.head === selected) ? selected : firstPath + const active = files.find((f) => f.head === activePath) ?? null + + if (!files.length) { + return

(no file changes)

+ } + + return ( +
+
+ {tree.map((n) => ( + + ))} +
+
+ {active && ( +
+
{active.head}
+ {active.lines.map((l, j) => ( +
+ {l.text} +
+ ))} +
+ )} +
+
+ ) +} diff --git a/desktop/src/renderer/src/components/diffParse.ts b/desktop/src/renderer/src/components/diffParse.ts new file mode 100644 index 00000000..c1661e52 --- /dev/null +++ b/desktop/src/renderer/src/components/diffParse.ts @@ -0,0 +1,45 @@ +// diffParse.ts — split a unified-diff string into per-file sections. +// extracted from Diff.tsx so the diff renderer and the file-changes view share +// one parser. behavior is unchanged from the original Diff.tsx parseDiff. + +export interface DiffLine { + cls: 'hunk' | 'add' | 'del' | 'ctx' + text: string +} + +export interface DiffFile { + head: string + lines: DiffLine[] +} + +export function parseDiff(diff: string): DiffFile[] { + const files: DiffFile[] = [] + let cur: DiffFile | null = null + + for (const line of diff.split('\n')) { + if (line.startsWith('diff --git')) { + const m = line.match(/ b\/(.+)$/) + cur = { head: m ? m[1] : line, lines: [] } + files.push(cur) + } else if (!cur) { + continue + } else if ( + line.startsWith('+++') || + line.startsWith('---') || + line.startsWith('index ') + ) { + continue + } else { + const cls: DiffLine['cls'] = line.startsWith('@@') + ? 'hunk' + : line.startsWith('+') + ? 'add' + : line.startsWith('-') + ? 'del' + : 'ctx' + cur.lines.push({ cls, text: line || ' ' }) + } + } + + return files +} diff --git a/desktop/src/renderer/src/components/fileTree.ts b/desktop/src/renderer/src/components/fileTree.ts new file mode 100644 index 00000000..da76d80b --- /dev/null +++ b/desktop/src/renderer/src/components/fileTree.ts @@ -0,0 +1,54 @@ +// fileTree.ts — build a nested file tree from a flat list of paths. +// modeled on gittensor-ui's src/components/repositories/fileTree.ts, trimmed to +// what the dual-solve file-changes view needs: no urls, no github tree types. +// +// nodes are folders-first then alphabetical at every level. intermediate +// directories are synthesized from path segments so a lone "a/b/c.py" still +// produces the a → b → c.py chain. + +export interface FileNode { + name: string // last path segment + path: string // full path from root + type: 'tree' | 'blob' // directory | file + children?: FileNode[] // present iff type === 'tree' +} + +function sortNodes(nodes: FileNode[]): void { + nodes.sort((a, b) => { + if (a.type !== b.type) return a.type === 'tree' ? -1 : 1 + return a.name.localeCompare(b.name) + }) + for (const n of nodes) if (n.children) sortNodes(n.children) +} + +export function buildFileTree(paths: string[]): FileNode[] { + const roots: FileNode[] = [] + // path -> node, so intermediate dirs are created once and reused. + const byPath = new Map() + + for (const raw of paths) { + const full = raw.replace(/^\/+|\/+$/g, '') + if (!full) continue + const segs = full.split('/') + let prefix = '' + let siblings = roots + + segs.forEach((seg, i) => { + prefix = prefix ? `${prefix}/${seg}` : seg + const isLeaf = i === segs.length - 1 + let node = byPath.get(prefix) + if (!node) { + node = isLeaf + ? { name: seg, path: prefix, type: 'blob' } + : { name: seg, path: prefix, type: 'tree', children: [] } + byPath.set(prefix, node) + siblings.push(node) + } + // descend; only directory nodes carry children. + if (node.children) siblings = node.children + }) + } + + sortNodes(roots) + return roots +} diff --git a/desktop/src/renderer/src/views/DualSolve.tsx b/desktop/src/renderer/src/views/DualSolve.tsx index 3621b93c..5b2305f0 100644 --- a/desktop/src/renderer/src/views/DualSolve.tsx +++ b/desktop/src/renderer/src/views/DualSolve.tsx @@ -7,7 +7,7 @@ import { useCallback, useEffect, useReducer, useRef, useState } from 'react' import * as api from '../lib/client' -import { Diff } from '../components/Diff' +import { FileChanges } from '../components/FileChanges' import type { ProgressFrame } from '../../../shared/ipc' // --------------------------------------------------------------------------- @@ -347,11 +347,6 @@ export default function DualSolve() { ? ok : failed} - {c.changed_files && c.changed_files.length > 0 && ( -
    - {c.changed_files.map((f, fi) =>
  • {f}
  • )} -
- )} {c.log && (
{c.engine} log @@ -359,7 +354,7 @@ export default function DualSolve() {
)} {c.ok - ? + ? :

{c.error || 'engine produced no diff'}

} ))} diff --git a/desktop/test/file-tree.test.ts b/desktop/test/file-tree.test.ts new file mode 100644 index 00000000..7baf7376 --- /dev/null +++ b/desktop/test/file-tree.test.ts @@ -0,0 +1,66 @@ +import { describe, it, expect } from 'vitest' +import { buildFileTree, type FileNode } from '../src/renderer/src/components/fileTree' + +// flatten the tree to ":" in render order, for compact assertions. +function flat(nodes: FileNode[], out: string[] = []): string[] { + for (const n of nodes) { + out.push(`${n.type}:${n.path}`) + if (n.children) flat(n.children, out) + } + return out +} + +describe('buildFileTree', () => { + it('returns [] for empty input', () => { + expect(buildFileTree([])).toEqual([]) + }) + + it('keeps a single root-level file flat', () => { + expect(buildFileTree(['README.md'])).toEqual([ + { name: 'README.md', path: 'README.md', type: 'blob' }, + ]) + }) + + it('synthesizes intermediate directories from path segments', () => { + const t = buildFileTree(['src/parser.py']) + expect(flat(t)).toEqual(['tree:src', 'blob:src/parser.py']) + expect(t[0].type).toBe('tree') + expect(t[0].children?.[0]).toMatchObject({ name: 'parser.py', type: 'blob' }) + }) + + it('sorts folders first, then files, alphabetically at every level', () => { + const t = buildFileTree([ + 'zeta.txt', + 'src/parser.py', + 'alpha.txt', + 'src/aaa.py', + 'docs/guide.md', + ]) + // dirs (docs, src) before files (alpha, zeta); each alpha-sorted. + expect(flat(t)).toEqual([ + 'tree:docs', + 'blob:docs/guide.md', + 'tree:src', + 'blob:src/aaa.py', + 'blob:src/parser.py', + 'blob:alpha.txt', + 'blob:zeta.txt', + ]) + }) + + it('merges files that share a directory under one node', () => { + const t = buildFileTree(['src/a.py', 'src/b.py']) + expect(t).toHaveLength(1) + expect(t[0]).toMatchObject({ path: 'src', type: 'tree' }) + expect(t[0].children).toHaveLength(2) + }) + + it('de-dupes a repeated path', () => { + expect(buildFileTree(['x.py', 'x.py'])).toHaveLength(1) + }) + + it('handles deep nesting', () => { + const t = buildFileTree(['a/b/c/d.py']) + expect(flat(t)).toEqual(['tree:a', 'tree:a/b', 'tree:a/b/c', 'blob:a/b/c/d.py']) + }) +}) From ed9678afe8bc9895e5c898771bc6cbdf94d7893b Mon Sep 17 00:00:00 2001 From: dripsmvcp <138900956+dripsmvcp@users.noreply.github.com> Date: Tue, 30 Jun 2026 15:22:17 +0900 Subject: [PATCH 5/6] docs(desktop): add dual-solve file-changes view screenshot shows the per-candidate file tree rail driving the diff pane. --- .../screenshots/dual-solve-file-changes.png | Bin 0 -> 110919 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 desktop/docs/screenshots/dual-solve-file-changes.png diff --git a/desktop/docs/screenshots/dual-solve-file-changes.png b/desktop/docs/screenshots/dual-solve-file-changes.png new file mode 100644 index 0000000000000000000000000000000000000000..042b36a5dc58d727557a943db5c524c304085936 GIT binary patch literal 110919 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%0DaR$}S++wE46(a;DYp(q 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 literal 0 HcmV?d00001 From e1883cef65afc3b2b436e881f5d8f4691d57d07c Mon Sep 17 00:00:00 2001 From: dripsmvcp <138900956+dripsmvcp@users.noreply.github.com> Date: Tue, 30 Jun 2026 16:08:04 +0900 Subject: [PATCH 6/6] fix(desktop): address review on dual-solve file-changes view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit two coderabbit findings on #294: - diffParse dropped any content line starting with "+++"/"---", so a real added "++counter" or removed "--flag" line vanished from the diff. restrict the header skip to the actual markers "+++ " / "--- " (trailing space + path). adds diff-parse.test.ts covering the regression and basic parsing. - file rows in the tree rail were clickable
s — mouse-only, not keyboard-focusable. switch to ) } diff --git a/desktop/src/renderer/src/components/diffParse.ts b/desktop/src/renderer/src/components/diffParse.ts index c1661e52..0f489585 100644 --- a/desktop/src/renderer/src/components/diffParse.ts +++ b/desktop/src/renderer/src/components/diffParse.ts @@ -24,8 +24,11 @@ export function parseDiff(diff: string): DiffFile[] { } else if (!cur) { continue } else if ( - line.startsWith('+++') || - line.startsWith('---') || + // only the file-header markers, which always carry a trailing space and + // path ("+++ b/x", "--- a/x"). a content line like "++counter" or + // "--flag" must NOT be skipped. + line.startsWith('+++ ') || + line.startsWith('--- ') || line.startsWith('index ') ) { continue diff --git a/desktop/test/diff-parse.test.ts b/desktop/test/diff-parse.test.ts new file mode 100644 index 00000000..9cff2b26 --- /dev/null +++ b/desktop/test/diff-parse.test.ts @@ -0,0 +1,59 @@ +import { describe, it, expect } from 'vitest' +import { parseDiff } from '../src/renderer/src/components/diffParse' + +describe('parseDiff', () => { + it('splits into per-file sections keyed off the b/ path', () => { + const d = [ + 'diff --git a/src/x.py b/src/x.py', + 'index 111..222 100644', + '--- a/src/x.py', + '+++ b/src/x.py', + '@@ -1,2 +1,2 @@', + '-old', + '+new', + ].join('\n') + const files = parseDiff(d) + expect(files).toHaveLength(1) + expect(files[0].head).toBe('src/x.py') + // header markers (---, +++, index) are dropped; only hunk + changes remain. + expect(files[0].lines.map((l) => `${l.cls}:${l.text}`)).toEqual([ + 'hunk:@@ -1,2 +1,2 @@', + 'del:-old', + 'add:+new', + ]) + }) + + it('keeps added/removed content lines that start with ++ or --', () => { + // these begin with +/- twice but are NOT file headers (no trailing space). + const d = [ + 'diff --git a/c.py b/c.py', + '--- a/c.py', + '+++ b/c.py', + '@@ -1,1 +1,2 @@', + '++counter', + '---flag', + ].join('\n') + const lines = parseDiff(d)[0].lines + expect(lines).toEqual([ + { cls: 'hunk', text: '@@ -1,1 +1,2 @@' }, + { cls: 'add', text: '++counter' }, + { cls: 'del', text: '---flag' }, + ]) + }) + + it('returns [] for an empty diff', () => { + expect(parseDiff('')).toEqual([]) + }) + + it('handles a multi-file diff', () => { + const d = [ + 'diff --git a/a.py b/a.py', + '@@ -1 +1 @@', + '+a', + 'diff --git a/b.py b/b.py', + '@@ -1 +1 @@', + '+b', + ].join('\n') + expect(parseDiff(d).map((f) => f.head)).toEqual(['a.py', 'b.py']) + }) +})