lxreview 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 (67) hide show
  1. lxreview-0.1.0/.github/dependabot.yml +10 -0
  2. lxreview-0.1.0/.github/workflows/ci.yml +48 -0
  3. lxreview-0.1.0/.github/workflows/publish.yml +32 -0
  4. lxreview-0.1.0/.gitignore +18 -0
  5. lxreview-0.1.0/LICENSE +21 -0
  6. lxreview-0.1.0/PKG-INFO +169 -0
  7. lxreview-0.1.0/README.md +145 -0
  8. lxreview-0.1.0/SECURITY.md +17 -0
  9. lxreview-0.1.0/THIRD_PARTY.md +16 -0
  10. lxreview-0.1.0/docs/ARCHITECTURE.md +109 -0
  11. lxreview-0.1.0/docs/CONFIGURATION.md +108 -0
  12. lxreview-0.1.0/docs/OPERATIONS.md +201 -0
  13. lxreview-0.1.0/pyproject.toml +38 -0
  14. lxreview-0.1.0/scripts/benchmark.py +95 -0
  15. lxreview-0.1.0/scripts/release.py +28 -0
  16. lxreview-0.1.0/src/lxreview/__init__.py +3 -0
  17. lxreview-0.1.0/src/lxreview/backend.py +30 -0
  18. lxreview-0.1.0/src/lxreview/bridge/__init__.py +0 -0
  19. lxreview-0.1.0/src/lxreview/bridge/relay.py +224 -0
  20. lxreview-0.1.0/src/lxreview/bridge/ssh.py +250 -0
  21. lxreview-0.1.0/src/lxreview/browser/__init__.py +0 -0
  22. lxreview-0.1.0/src/lxreview/browser/playwright.py +555 -0
  23. lxreview-0.1.0/src/lxreview/browser/service.py +152 -0
  24. lxreview-0.1.0/src/lxreview/cli.py +1179 -0
  25. lxreview-0.1.0/src/lxreview/config.py +163 -0
  26. lxreview-0.1.0/src/lxreview/contracts.py +124 -0
  27. lxreview-0.1.0/src/lxreview/discussion.py +141 -0
  28. lxreview-0.1.0/src/lxreview/doctor.py +342 -0
  29. lxreview-0.1.0/src/lxreview/errors.py +21 -0
  30. lxreview-0.1.0/src/lxreview/git.py +300 -0
  31. lxreview-0.1.0/src/lxreview/install/__init__.py +0 -0
  32. lxreview-0.1.0/src/lxreview/install/claude.py +121 -0
  33. lxreview-0.1.0/src/lxreview/install/runtime.py +120 -0
  34. lxreview-0.1.0/src/lxreview/mcp/__init__.py +0 -0
  35. lxreview-0.1.0/src/lxreview/mcp/server.py +67 -0
  36. lxreview-0.1.0/src/lxreview/observability.py +37 -0
  37. lxreview-0.1.0/src/lxreview/paths.py +124 -0
  38. lxreview-0.1.0/src/lxreview/process.py +342 -0
  39. lxreview-0.1.0/src/lxreview/resources/__init__.py +0 -0
  40. lxreview-0.1.0/src/lxreview/resources/review-follow.md +18 -0
  41. lxreview-0.1.0/src/lxreview/resources/review-loop.md +48 -0
  42. lxreview-0.1.0/src/lxreview/resources/review-watch.md +6 -0
  43. lxreview-0.1.0/src/lxreview/resources/runtime-manifest.json +23 -0
  44. lxreview-0.1.0/src/lxreview/reviewer.py +41 -0
  45. lxreview-0.1.0/src/lxreview/runs.py +139 -0
  46. lxreview-0.1.0/src/lxreview/security.py +426 -0
  47. lxreview-0.1.0/src/lxreview/services.py +122 -0
  48. lxreview-0.1.0/src/lxreview/timeline.py +209 -0
  49. lxreview-0.1.0/src/lxreview/toolchain.py +201 -0
  50. lxreview-0.1.0/src/lxreview/worker.py +629 -0
  51. lxreview-0.1.0/tests/conftest.py +26 -0
  52. lxreview-0.1.0/tests/fixtures/chatgpt.html +198 -0
  53. lxreview-0.1.0/tests/test_bridge.py +312 -0
  54. lxreview-0.1.0/tests/test_browser_service.py +116 -0
  55. lxreview-0.1.0/tests/test_chatgpt_page.py +228 -0
  56. lxreview-0.1.0/tests/test_claude_process.py +196 -0
  57. lxreview-0.1.0/tests/test_cli.py +541 -0
  58. lxreview-0.1.0/tests/test_core.py +494 -0
  59. lxreview-0.1.0/tests/test_discussion.py +117 -0
  60. lxreview-0.1.0/tests/test_doctor.py +125 -0
  61. lxreview-0.1.0/tests/test_git.py +245 -0
  62. lxreview-0.1.0/tests/test_install_process.py +466 -0
  63. lxreview-0.1.0/tests/test_live.py +33 -0
  64. lxreview-0.1.0/tests/test_mcp.py +122 -0
  65. lxreview-0.1.0/tests/test_toolchain.py +105 -0
  66. lxreview-0.1.0/tests/test_worker.py +503 -0
  67. lxreview-0.1.0/uv.lock +1847 -0
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: uv
4
+ directory: /
5
+ schedule:
6
+ interval: monthly
7
+ - package-ecosystem: github-actions
8
+ directory: /
9
+ schedule:
10
+ interval: monthly
@@ -0,0 +1,48 @@
1
+ name: quality
2
+ on:
3
+ push:
4
+ pull_request:
5
+ permissions:
6
+ contents: read
7
+ jobs:
8
+ test:
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ os: [ubuntu-24.04, macos-14]
13
+ python: ['3.12', '3.13', '3.14']
14
+ runs-on: ${{ matrix.os }}
15
+ steps:
16
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
17
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
18
+ with:
19
+ version: '0.12.19'
20
+ python-version: ${{ matrix.python }}
21
+ enable-cache: true
22
+ - run: uv sync --frozen
23
+ - run: uv run ruff check .
24
+ - run: uv run ruff format --check .
25
+ - run: uv run mypy src
26
+ - run: uv run pytest
27
+ - run: uv build
28
+ - name: Wheel installs as a uv tool
29
+ run: |
30
+ export UV_TOOL_DIR=/tmp/lxreview-tools UV_TOOL_BIN_DIR=/tmp/lxreview-tools/bin
31
+ uv tool install --python '${{ matrix.python }}' dist/*.whl
32
+ /tmp/lxreview-tools/bin/lxreview version
33
+ /tmp/lxreview-tools/bin/lxreview --help
34
+ browser:
35
+ # Drives the real Playwright session against a local page that mirrors ChatGPT's markup.
36
+ runs-on: ubuntu-24.04
37
+ steps:
38
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
39
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
40
+ with:
41
+ version: '0.12.19'
42
+ python-version: '3.13'
43
+ enable-cache: true
44
+ - run: uv sync --frozen
45
+ - run: uv run playwright install --with-deps chromium
46
+ - run: uv run pytest -m browser
47
+ env:
48
+ LXREVIEW_BROWSER_TESTS: '1'
@@ -0,0 +1,32 @@
1
+ name: publish
2
+ # Publishes a release to PyPI when a version tag such as v0.1.0 is pushed. PyPI trusts this
3
+ # workflow through trusted publishing, so no API token is stored.
4
+ on:
5
+ push:
6
+ tags: ['v*']
7
+ permissions:
8
+ contents: read
9
+ jobs:
10
+ publish:
11
+ runs-on: ubuntu-24.04
12
+ environment: pypi
13
+ permissions:
14
+ id-token: write
15
+ steps:
16
+ - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
17
+ - uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
18
+ with:
19
+ version: '0.12.19'
20
+ python-version: '3.12'
21
+ - name: Tag matches the package version
22
+ run: test "v$(uv version --short)" = "$GITHUB_REF_NAME"
23
+ - run: uv sync --frozen
24
+ - run: uv run ruff check .
25
+ - run: uv run mypy src
26
+ - run: uv run pytest
27
+ - run: uv build
28
+ - name: Wheel installs as a uv tool
29
+ run: |
30
+ UV_TOOL_DIR=/tmp/tools UV_TOOL_BIN_DIR=/tmp/tools/bin uv tool install --managed-python dist/*.whl
31
+ /tmp/tools/bin/lxreview version
32
+ - run: uv publish --trusted-publishing always
@@ -0,0 +1,18 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ .mypy_cache/
7
+ dist/
8
+ *.egg-info/
9
+ .live-results/
10
+
11
+ # Local-only agent instructions; never commit
12
+ CLAUDE.md
13
+ CLAUDE.local.md
14
+ .claude/
15
+ AGENTS.md
16
+ LXReview-instructions.md
17
+ .agents/
18
+ .codex/
lxreview-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Joshua Falco Beirer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,169 @@
1
+ Metadata-Version: 2.5
2
+ Name: lxreview
3
+ Version: 0.1.0
4
+ Summary: Independent AI review loops for LXPLUS development
5
+ Project-URL: Homepage, https://github.com/jbeirer/lxreview
6
+ Project-URL: Issues, https://github.com/jbeirer/lxreview/issues
7
+ Author: Joshua Beirer
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Operating System :: MacOS
11
+ Classifier: Operating System :: POSIX :: Linux
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.12
14
+ Requires-Dist: aiohttp==3.14.3
15
+ Requires-Dist: httpx<1,>=0.28
16
+ Requires-Dist: mcp==2.2.0
17
+ Requires-Dist: playwright==1.63.0
18
+ Requires-Dist: psutil<8,>=7
19
+ Requires-Dist: pydantic<3,>=2.11
20
+ Requires-Dist: rich<16,>=14
21
+ Requires-Dist: tomli-w<2,>=1.2
22
+ Requires-Dist: typer<1,>=0.16
23
+ Description-Content-Type: text/markdown
24
+
25
+ # LXReview
26
+
27
+ **Independent AI review loops for Claude Code development on LXPLUS.**
28
+
29
+ ChatGPT reviews the actual GitHub PR, Claude evaluates and fixes useful findings, and LXReview sends the updated PR through another independent review. The run continues in the background until no accepted substantial issues remain or the pass limit is reached.
30
+
31
+ ## Why LXReview?
32
+
33
+ - **Independent review** — ChatGPT reads the PR on GitHub rather than relying on Claude's description of its work.
34
+ - **Automatic fix/review loop** — accepted findings can be fixed, checked, committed, pushed and reviewed again.
35
+ - **Persistent runs** — reviews keep running after you close the Claude chat.
36
+ - **Visible decisions** — follow findings, accept/reject reasons, edits, checks, commits and subsequent passes.
37
+ - **Uses existing subscriptions** — sign into ChatGPT normally; no OpenAI API key or API credits are required.
38
+
39
+ ## How it works
40
+
41
+ ```mermaid
42
+ flowchart LR
43
+ PR[PR on GitHub] --> Review[ChatGPT reviews]
44
+ Review --> Evaluate[Claude evaluates findings]
45
+ Evaluate --> Fix[Accepted fixes + checks + push]
46
+ Fix --> Review
47
+ ```
48
+
49
+ The loop finishes when no accepted substantial issues remain, with at most one extra pass of non-blocking fixes. The final pass reports remaining issues without making edits that would go unreviewed; errors stop the run rather than count as success.
50
+
51
+ ## Quick start
52
+
53
+ ### Prerequisites
54
+
55
+ - An LXPLUS account and a Git checkout of the project you want reviewed.
56
+ - Claude Code installed and authenticated, plus GitHub CLI (`gh`) authenticated with `gh auth login`.
57
+ - Git and [uv](https://docs.astral.sh/uv/) available on the installation host.
58
+ - A ChatGPT account that can access the PR, and a workstation with SSH and a VNC viewer for the initial browser login.
59
+
60
+ The host also needs the desktop and sandbox tools checked by `doctor`; see [host requirements](docs/OPERATIONS.md#lxplus-host-considerations).
61
+
62
+ ### Install and log in
63
+
64
+ On the LXPLUS host where you will work:
65
+
66
+ ```bash
67
+ uv tool install --managed-python lxreview
68
+ lxreview setup --mode lxplus-browser
69
+ lxreview login
70
+ lxreview doctor
71
+ ```
72
+
73
+ To install from a checkout instead, use `uv tool install --managed-python /path/to/lxreview`. uv gives LXReview its own environment on a uv-managed Python and puts the `lxreview` command in `~/.local/bin`; if that directory is not on your PATH, `uv tool update-shell` adds it. `setup` installs the pinned Chrome and the Claude Code integration under `~/.lxreview`, and `login` walks you through connecting to the remote desktop and signing into ChatGPT. Installation is private to your account.
74
+
75
+ To view the browser again later, run `lxreview desktop connect` on the same LXPLUS host. It prints the SSH tunnel and VNC viewer instructions to follow on your workstation; see [reconnecting to the desktop](docs/OPERATIONS.md#reconnect-to-the-desktop).
76
+
77
+ ### Start your first review
78
+
79
+ Open a **new Claude Code conversation in the project you want reviewed**, with its PR branch checked out and the working tree clean. Replace the example URL with your PR:
80
+
81
+ ```text
82
+ /review-loop https://github.com/owner/repository/pull/123
83
+ ```
84
+
85
+ Or let LXReview find the current branch's PR:
86
+
87
+ ```text
88
+ /review-loop
89
+ ```
90
+
91
+ The branch must be pushed to its upstream and have an open, accessible PR because ChatGPT reads the code on GitHub. The command returns a run ID and follows progress in the same chat.
92
+
93
+ ## What happens during a review?
94
+
95
+ 1. ChatGPT independently reviews the current PR in a fresh Temporary Chat.
96
+ 2. Claude evaluates substantial findings and eligible non-blocking findings against the code and PR discussion, including decisions already settled there.
97
+ 3. Claude runs the project's relevant checks on the unchanged code, implements accepted fixes, then checks again.
98
+ 4. Claude commits the fixes; LXReview pushes them and asks ChatGPT to review the updated PR.
99
+
100
+ New check failures block publication. Pre-existing failures and checks that cannot run are reported. See [review decisions and verification](docs/OPERATIONS.md#review-decisions-and-verification) for the detailed policy.
101
+
102
+ ## Following and controlling a run
103
+
104
+ **Closing the Claude chat does not stop the review run.** Watch it again from another conversation on the same LXPLUS host, or use the terminal. Ctrl-C in a terminal watch also stops only the watching.
105
+
106
+ Replace `<run-id>` with the ID returned at startup; `lxreview runs` lists IDs and hosts.
107
+
108
+ | Task | Claude Code | Terminal |
109
+ | --- | --- | --- |
110
+ | Follow | `/review-watch <run-id>` | `lxreview watch <run-id>` |
111
+ | Check status | `/review-status <run-id>` | `lxreview status <run-id>` |
112
+ | Inspect pass 1 | `/review-show <run-id> 1` | `lxreview show <run-id> --pass 1` |
113
+ | Stop | `/review-stop <run-id>` | `lxreview stop <run-id>` |
114
+ | Resume | `/review-resume <run-id>` | `lxreview resume <run-id>` |
115
+
116
+ Resume is for failed, cancelled or interrupted runs and requires a clean, pushed checkpoint. Runs survive ordinary disconnection, subject to host policy, but not node reboot or drain.
117
+
118
+ ## Choosing models
119
+
120
+ Defaults work without configuration. Override model and effort for one run:
121
+
122
+ ```text
123
+ /review-loop --chatgpt sol:high --claude opus:xhigh
124
+ ```
125
+
126
+ `lxreview options` lists available choices. See [Configuration](docs/CONFIGURATION.md) for persistent defaults, pass limits and custom verification environments.
127
+
128
+ ## Browser modes
129
+
130
+ Use **`lxplus-browser`** for normal LXPLUS use and persistent runs.
131
+
132
+ | Mode | Best for | Main trade-off |
133
+ | --- | --- | --- |
134
+ | `lxplus-browser` | Runs independent of your workstation | Browser runs on the LXPLUS host |
135
+ | `local-browser` | Keeping the browser on your workstation | Workstation must stay online, awake and connected |
136
+
137
+ For the alternative mode, run `lxreview setup --mode local-browser --role host` on LXPLUS, then follow the [workstation setup and pairing steps](docs/OPERATIONS.md#local-browser).
138
+
139
+ ## Common commands
140
+
141
+ | Command | Purpose |
142
+ | --- | --- |
143
+ | `lxreview doctor` | Check setup and perform a ChatGPT smoke test |
144
+ | `lxreview runs` | Find runs and their host |
145
+ | `lxreview options` | List model and effort choices |
146
+ | `lxreview update` | Verify/reinstall the current release's pinned runtimes |
147
+ | `lxreview uninstall` | Remove integration and archive the installation |
148
+
149
+ Run controls are listed above. See [Operations](docs/OPERATIONS.md) for application upgrades, reports and recovery.
150
+
151
+ ## Troubleshooting
152
+
153
+ - Run `lxreview doctor`; use `--no-smoke` to avoid consuming a ChatGPT turn.
154
+ - Check `gh auth status` and ensure your clean, pushed branch matches the PR.
155
+ - On AFS, `run` and `resume` require at least two hours of token lifetime; renew with `kinit` followed by `aklog`.
156
+ - After setup changes, open a fresh Claude Code conversation to load the integration.
157
+
158
+ More help: [Operations and troubleshooting](docs/OPERATIONS.md#troubleshooting).
159
+
160
+ ## More documentation
161
+
162
+ - [Configuration](docs/CONFIGURATION.md)
163
+ - [Browser setup and operations](docs/OPERATIONS.md)
164
+ - [Architecture](docs/ARCHITECTURE.md)
165
+ - [Security](SECURITY.md)
166
+ - [Development](docs/ARCHITECTURE.md#development)
167
+ - [Third-party notices](THIRD_PARTY.md)
168
+
169
+ Browser automation is not an official OpenAI, Anthropic or CERN integration. UI changes can break it; each user logs in normally, with no CAPTCHA or MFA bypass.
@@ -0,0 +1,145 @@
1
+ # LXReview
2
+
3
+ **Independent AI review loops for Claude Code development on LXPLUS.**
4
+
5
+ ChatGPT reviews the actual GitHub PR, Claude evaluates and fixes useful findings, and LXReview sends the updated PR through another independent review. The run continues in the background until no accepted substantial issues remain or the pass limit is reached.
6
+
7
+ ## Why LXReview?
8
+
9
+ - **Independent review** — ChatGPT reads the PR on GitHub rather than relying on Claude's description of its work.
10
+ - **Automatic fix/review loop** — accepted findings can be fixed, checked, committed, pushed and reviewed again.
11
+ - **Persistent runs** — reviews keep running after you close the Claude chat.
12
+ - **Visible decisions** — follow findings, accept/reject reasons, edits, checks, commits and subsequent passes.
13
+ - **Uses existing subscriptions** — sign into ChatGPT normally; no OpenAI API key or API credits are required.
14
+
15
+ ## How it works
16
+
17
+ ```mermaid
18
+ flowchart LR
19
+ PR[PR on GitHub] --> Review[ChatGPT reviews]
20
+ Review --> Evaluate[Claude evaluates findings]
21
+ Evaluate --> Fix[Accepted fixes + checks + push]
22
+ Fix --> Review
23
+ ```
24
+
25
+ The loop finishes when no accepted substantial issues remain, with at most one extra pass of non-blocking fixes. The final pass reports remaining issues without making edits that would go unreviewed; errors stop the run rather than count as success.
26
+
27
+ ## Quick start
28
+
29
+ ### Prerequisites
30
+
31
+ - An LXPLUS account and a Git checkout of the project you want reviewed.
32
+ - Claude Code installed and authenticated, plus GitHub CLI (`gh`) authenticated with `gh auth login`.
33
+ - Git and [uv](https://docs.astral.sh/uv/) available on the installation host.
34
+ - A ChatGPT account that can access the PR, and a workstation with SSH and a VNC viewer for the initial browser login.
35
+
36
+ The host also needs the desktop and sandbox tools checked by `doctor`; see [host requirements](docs/OPERATIONS.md#lxplus-host-considerations).
37
+
38
+ ### Install and log in
39
+
40
+ On the LXPLUS host where you will work:
41
+
42
+ ```bash
43
+ uv tool install --managed-python lxreview
44
+ lxreview setup --mode lxplus-browser
45
+ lxreview login
46
+ lxreview doctor
47
+ ```
48
+
49
+ To install from a checkout instead, use `uv tool install --managed-python /path/to/lxreview`. uv gives LXReview its own environment on a uv-managed Python and puts the `lxreview` command in `~/.local/bin`; if that directory is not on your PATH, `uv tool update-shell` adds it. `setup` installs the pinned Chrome and the Claude Code integration under `~/.lxreview`, and `login` walks you through connecting to the remote desktop and signing into ChatGPT. Installation is private to your account.
50
+
51
+ To view the browser again later, run `lxreview desktop connect` on the same LXPLUS host. It prints the SSH tunnel and VNC viewer instructions to follow on your workstation; see [reconnecting to the desktop](docs/OPERATIONS.md#reconnect-to-the-desktop).
52
+
53
+ ### Start your first review
54
+
55
+ Open a **new Claude Code conversation in the project you want reviewed**, with its PR branch checked out and the working tree clean. Replace the example URL with your PR:
56
+
57
+ ```text
58
+ /review-loop https://github.com/owner/repository/pull/123
59
+ ```
60
+
61
+ Or let LXReview find the current branch's PR:
62
+
63
+ ```text
64
+ /review-loop
65
+ ```
66
+
67
+ The branch must be pushed to its upstream and have an open, accessible PR because ChatGPT reads the code on GitHub. The command returns a run ID and follows progress in the same chat.
68
+
69
+ ## What happens during a review?
70
+
71
+ 1. ChatGPT independently reviews the current PR in a fresh Temporary Chat.
72
+ 2. Claude evaluates substantial findings and eligible non-blocking findings against the code and PR discussion, including decisions already settled there.
73
+ 3. Claude runs the project's relevant checks on the unchanged code, implements accepted fixes, then checks again.
74
+ 4. Claude commits the fixes; LXReview pushes them and asks ChatGPT to review the updated PR.
75
+
76
+ New check failures block publication. Pre-existing failures and checks that cannot run are reported. See [review decisions and verification](docs/OPERATIONS.md#review-decisions-and-verification) for the detailed policy.
77
+
78
+ ## Following and controlling a run
79
+
80
+ **Closing the Claude chat does not stop the review run.** Watch it again from another conversation on the same LXPLUS host, or use the terminal. Ctrl-C in a terminal watch also stops only the watching.
81
+
82
+ Replace `<run-id>` with the ID returned at startup; `lxreview runs` lists IDs and hosts.
83
+
84
+ | Task | Claude Code | Terminal |
85
+ | --- | --- | --- |
86
+ | Follow | `/review-watch <run-id>` | `lxreview watch <run-id>` |
87
+ | Check status | `/review-status <run-id>` | `lxreview status <run-id>` |
88
+ | Inspect pass 1 | `/review-show <run-id> 1` | `lxreview show <run-id> --pass 1` |
89
+ | Stop | `/review-stop <run-id>` | `lxreview stop <run-id>` |
90
+ | Resume | `/review-resume <run-id>` | `lxreview resume <run-id>` |
91
+
92
+ Resume is for failed, cancelled or interrupted runs and requires a clean, pushed checkpoint. Runs survive ordinary disconnection, subject to host policy, but not node reboot or drain.
93
+
94
+ ## Choosing models
95
+
96
+ Defaults work without configuration. Override model and effort for one run:
97
+
98
+ ```text
99
+ /review-loop --chatgpt sol:high --claude opus:xhigh
100
+ ```
101
+
102
+ `lxreview options` lists available choices. See [Configuration](docs/CONFIGURATION.md) for persistent defaults, pass limits and custom verification environments.
103
+
104
+ ## Browser modes
105
+
106
+ Use **`lxplus-browser`** for normal LXPLUS use and persistent runs.
107
+
108
+ | Mode | Best for | Main trade-off |
109
+ | --- | --- | --- |
110
+ | `lxplus-browser` | Runs independent of your workstation | Browser runs on the LXPLUS host |
111
+ | `local-browser` | Keeping the browser on your workstation | Workstation must stay online, awake and connected |
112
+
113
+ For the alternative mode, run `lxreview setup --mode local-browser --role host` on LXPLUS, then follow the [workstation setup and pairing steps](docs/OPERATIONS.md#local-browser).
114
+
115
+ ## Common commands
116
+
117
+ | Command | Purpose |
118
+ | --- | --- |
119
+ | `lxreview doctor` | Check setup and perform a ChatGPT smoke test |
120
+ | `lxreview runs` | Find runs and their host |
121
+ | `lxreview options` | List model and effort choices |
122
+ | `lxreview update` | Verify/reinstall the current release's pinned runtimes |
123
+ | `lxreview uninstall` | Remove integration and archive the installation |
124
+
125
+ Run controls are listed above. See [Operations](docs/OPERATIONS.md) for application upgrades, reports and recovery.
126
+
127
+ ## Troubleshooting
128
+
129
+ - Run `lxreview doctor`; use `--no-smoke` to avoid consuming a ChatGPT turn.
130
+ - Check `gh auth status` and ensure your clean, pushed branch matches the PR.
131
+ - On AFS, `run` and `resume` require at least two hours of token lifetime; renew with `kinit` followed by `aklog`.
132
+ - After setup changes, open a fresh Claude Code conversation to load the integration.
133
+
134
+ More help: [Operations and troubleshooting](docs/OPERATIONS.md#troubleshooting).
135
+
136
+ ## More documentation
137
+
138
+ - [Configuration](docs/CONFIGURATION.md)
139
+ - [Browser setup and operations](docs/OPERATIONS.md)
140
+ - [Architecture](docs/ARCHITECTURE.md)
141
+ - [Security](SECURITY.md)
142
+ - [Development](docs/ARCHITECTURE.md#development)
143
+ - [Third-party notices](THIRD_PARTY.md)
144
+
145
+ Browser automation is not an official OpenAI, Anthropic or CERN integration. UI changes can break it; each user logs in normally, with no CAPTCHA or MFA bypass.
@@ -0,0 +1,17 @@
1
+ # Security model
2
+
3
+ LXReview deliberately runs its dedicated Claude worker with bypass permissions. It does not change permission mode in ordinary Claude conversations.
4
+
5
+ Workers have an explicit tool list, no subagent tools, no external MCP servers, and run-scoped `PreToolUse` hooks. Claude's Bash sandbox is explicitly enabled with `failIfUnavailable` and no unsandboxed fallback; missing sandbox prerequisites fail rather than weaken the policy. No worker turn has network access. Evaluation is read-only. The edit/test turn may run the project's own tooling, one literal command at a time: hooks refuse shell composition and expansion, shells and wrapper commands (`bash`, `env`, `xargs`, `sudo` and similar), `GIT_*`, loader and `PATH` assignments, Git mutations, commands that modify files outside the repository, and paths to credentials. The sandbox confines writes to the repository (Git metadata, hooks and tool configuration such as `.claude`, `.gitmodules` and `.lfsconfig` excluded) and a private per-turn directory, and hides credentials and private data: the installation root, `~/.config` (except Git's own configuration), `~/.claude`, SSH, GnuPG, cloud, container and package-registry credentials, keyrings, browser profiles, shell histories, Kerberos ticket files and `.env` files. The publication turn may only stage and commit, with no Co-Authored-By or Claude attribution.
6
+
7
+ Before each evaluation, LXReview reads the PR's discussion with your `gh` login, outside the sandbox, through one read-only GraphQL query; Claude receives it as untrusted text, and each pass keeps a copy in its audit directory. LXReview itself verifies that publication added exactly one commit on top of the reviewed head and left no uncommitted changes, then signs (if configured) and pushes it outside the sandbox with the user's credentials, to the existing upstream by an explicit refspec. Push policy checks reject force/mirror refspecs and alternate destinations in Git configuration. Pre-push hooks are not run for these pushes, since they could execute files the worker changed; commit hooks run inside the sandbox. A repository setup command from `[verify.setup]` runs outside the sandbox before the worker edits anything; it comes from the user's own configuration and must not source repository files.
8
+
9
+ These protections are defense in depth, not a claim that hooks safely execute arbitrary hostile projects. Test code and commit hooks are executable code; use a disposable branch and trusted repository. A failing check or push is never fixed by disabling the sandbox. User or enterprise Claude managed settings may further restrict operation.
10
+
11
+ Playwright drives Chrome over a private pipe, so Chrome opens no debugging port. The browser service accepts calls only on a 0600 unix socket in a 0700 per-user runtime directory (`/run/user/<uid>`, or the private installation root where the host has none), with a per-start bearer token. VNC and the relay bind only to loopback. SSH reverse forwarding explicitly binds `127.0.0.1` on the exact LXPLUS node. Loopback is not a user boundary: relay bearer authentication remains mandatory. A fresh challenge checks server possession of the relay token before the client sends its bearer to a potentially stale port. Pairing uses a single-use ten-minute nonce. Relay credentials rotate on bridge creation, expire after at most eight hours, and are sent over SSH stdin, never argv. A disconnected bridge is unavailable, and credentials expire even when remote cleanup cannot run. The relay accepts only named package operations and no arbitrary URL or file proxying.
12
+
13
+ Private roots/directories use 0700 and secrets/state use 0600. Runtime archives are pinned by SHA-256 and Python dependencies by `uv.lock` hashes; Playwright never downloads browsers. Downloads are staged and checked before extraction. Browser state is never copied, exported or shared. No OpenAI API, cookie extraction, CAPTCHA bypass, or MFA bypass exists.
14
+
15
+ Events redact credential-shaped keys/values and drop thinking/signature blocks. Raw reviewer responses are preserved verbatim by contract, so do not send credentials to the reviewer. Audit artifacts may contain proprietary code and should be handled as private repository data. The package cannot reliably recognize every arbitrary secret embedded in source text; inspect reports before sharing them.
16
+
17
+ Installer integration refuses command collisions. Uninstall removes only registrations and links that still match ownership records. It archives the private root for recovery; delete the archive for complete removal. No shell startup, conda, global npm, user VNC startup or unrelated browser process is modified.
@@ -0,0 +1,16 @@
1
+ # Third-party components
2
+
3
+ LXReview composes these projects.
4
+
5
+ | Component | License / terms | Distribution |
6
+ |---|---|---|
7
+ | [Chrome for Testing](https://googlechromelabs.github.io/chrome-for-testing/) 154.0.8037.57 | Google Chrome terms and Chromium third-party notices | Downloaded directly from Google's release bucket |
8
+ | [CPython](https://www.python.org/) | PSF license | uv-managed private runtime |
9
+ | [uv](https://github.com/astral-sh/uv) | MIT / Apache-2.0 | User-provided installer (`uv tool install`) |
10
+ | [Playwright](https://github.com/microsoft/playwright) 1.63.0 | Apache-2.0 (its wheel bundles a Node.js driver under MIT) | Python dependency; drives the pinned Chrome |
11
+ | [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) | MIT | Python dependency |
12
+ | Typer, Pydantic, HTTPX, Rich, tomli-w | MIT | Python dependencies |
13
+ | aiohttp | Apache-2.0 | Python dependency |
14
+ | psutil | BSD-3-Clause | Python dependency |
15
+
16
+ Exact Python dependencies and hashes are in `uv.lock`. Preserve upstream license files when redistributing runtimes. Claude Code, TigerVNC, Xfce, systemd, tmux, SSH and macOS launchd are external installed tools, not bundled here. This software has no claimed endorsement by CERN, OpenAI, Anthropic or any upstream project.
@@ -0,0 +1,109 @@
1
+ # Architecture
2
+
3
+ For setup and run control, see [Operations](OPERATIONS.md). For trust boundaries and publication restrictions, see [Security](../SECURITY.md).
4
+
5
+ ## Components
6
+
7
+ | Module | Responsibility |
8
+ | --- | --- |
9
+ | `contracts.py` | Normalized requests, responses, health, reviewer and browser-session protocols |
10
+ | `worker.py` | Provider-neutral review loop |
11
+ | `reviewer.py` | Independent review semantics and prompts |
12
+ | `browser/playwright.py` | ChatGPT selectors, page state, prompt readback, submission and completion rules |
13
+ | `browser/service.py` | Supervised driver process that owns Chrome and serves named operations over a private Unix socket |
14
+ | `backend.py` | Composition root; workflow prompts and worker logic do not branch on browser placement |
15
+ | `bridge/relay.py` | Named browser operations, with a workstation session lock across a whole review |
16
+ | `bridge/ssh.py` | Exact-host pairing and reverse forwarding |
17
+ | `mcp/server.py` | Stable package-owned stdio API for browser operations |
18
+ | `process.py` | Package-scoped supervision through systemd, tmux under a systemd scope, or launchd |
19
+
20
+ Configuration uses strict TOML/Pydantic. Schema 1 is the initial schema; unknown versions fail with an upgrade instruction rather than being rewritten. User settings are described in [Configuration](CONFIGURATION.md).
21
+
22
+ ## Browser placement
23
+
24
+ In `lxplus-browser` mode, the worker and browser run on the same host:
25
+
26
+ ```mermaid
27
+ flowchart LR
28
+ Worker[Persistent Claude worker] --> Reviewer[Reviewer contract]
29
+ Reviewer --> Service[Browser service]
30
+ Service --> Chrome[Chrome on private VNC desktop]
31
+ Viewer[Workstation VNC viewer] -. login .-> Chrome
32
+ ```
33
+
34
+ In `local-browser` mode, the browser service runs on the workstation:
35
+
36
+ ```mermaid
37
+ flowchart LR
38
+ Worker[Worker on LXPLUS] --> Reviewer[Reviewer contract]
39
+ Reviewer --> Relay[Authenticated operation relay]
40
+ Relay --> Service[Workstation browser service]
41
+ Service --> Chrome[Workstation Chrome]
42
+ ```
43
+
44
+ The relay is reached through a loopback-only SSH reverse tunnel to the exact LXPLUS node. MCP exposes the browser contract to Claude Code; the worker calls the reviewer backend directly. Browser authentication and transport boundaries are detailed in [Security](../SECURITY.md).
45
+
46
+ ## Worker lifecycle
47
+
48
+ The full review loop holds one cross-process reviewer lock and one repository lock. Each pass creates a fresh Temporary Chat in the same browser tab and persists the raw review before invoking Claude. The independent reviewer receives only the PR target, updated SHA and rubric, never earlier review findings.
49
+
50
+ Claude uses three restricted turns in one Claude session:
51
+
52
+ 1. Read-only evaluation of findings against the repository and PR discussion.
53
+ 2. Offline edits and checks, without Git metadata writes.
54
+ 3. Staging and committing after verification permits publication.
55
+
56
+ LXReview validates the resulting commit and pushes it outside those turns. The [operations policy](OPERATIONS.md#review-decisions-and-verification) covers findings, baseline checks and final-pass behavior.
57
+
58
+ ```mermaid
59
+ stateDiagram-v2
60
+ [*] --> QUEUED
61
+ QUEUED --> RUNNING
62
+ RUNNING --> CLEAN
63
+ RUNNING --> NO_VALID_SUBSTANTIAL_FINDINGS
64
+ RUNNING --> MAX_PASSES
65
+ RUNNING --> FAILED
66
+ RUNNING --> CANCELLED
67
+ RUNNING --> INTERRUPTED
68
+ FAILED --> QUEUED: verified resume
69
+ CANCELLED --> QUEUED: verified resume
70
+ INTERRUPTED --> QUEUED: verified resume
71
+ ```
72
+
73
+ Resume verifies branch/remote identity and a clean, pushed HEAD. Incomplete pass evidence is archived before another independent pass. A durable cancellation marker wins over later worker state updates; observing a missing worker marks a nonterminal run interrupted.
74
+
75
+ ## Hosts, storage and integration
76
+
77
+ Host identity prevents shared-home LXPLUS users from treating another node's services as local. Supervisor names include an installation-root hash to avoid collisions between installations. Sockets and service temporary files live in `/run/user/<uid>/lxreview-<hash>` when available, falling back to the installation's `run` directory; AFS homes cannot hold Unix sockets.
78
+
79
+ | Location | Contents |
80
+ | --- | --- |
81
+ | `~/.local/bin/lxreview` | Command installed by `uv tool install` |
82
+ | `~/.lxreview/bin/lxreview` | Fixed launcher written by `setup`: the tool environment's interpreter with this installation root |
83
+ | `~/.lxreview/state/runs/<id>/` | Run state, redacted events, worker output, Claude session ID and cancellation marker |
84
+ | `<git-common-dir>/review-loop/<id>/` | Run metadata, events, summary and per-pass evidence |
85
+ | `<git-common-dir>/review-loop/<id>/pass-NN/` | Verbatim review, explicit evaluations, PR discussion, diff, check reports and metadata |
86
+
87
+ Using the Git common directory keeps audit evidence out of commits and supports worktrees. Interrupted pass directories are retained with an `-interrupted-*` suffix. Events exclude hidden reasoning and redact credential-shaped values; raw reviews remain verbatim. See [Security](../SECURITY.md) before sharing artifacts.
88
+
89
+ Claude's user integration registers the MCP server and six slash commands pointing to the fixed launcher, so upgrading the package keeps them valid. Ownership records allow uninstall to remove only unchanged package-owned entries. Setup leaves shell startup files and PATH untouched.
90
+
91
+ During sandboxed commands, Claude Code creates empty, read-only placeholders for protected paths such as `.bashrc`, `.mcp.json` and `.claude/settings.json`. They disappear after the command, and LXReview excludes them from `git status` during the run. The full filesystem boundary is documented in [Security](../SECURITY.md).
92
+
93
+ ## Development
94
+
95
+ From the source checkout:
96
+
97
+ ```bash
98
+ uv sync --frozen
99
+ uv run pytest
100
+ uv run ruff check .
101
+ uv run ruff format --check .
102
+ uv run mypy src
103
+ uv build
104
+ uv tool install --managed-python --reinstall . # use this checkout as the installed lxreview
105
+ ```
106
+
107
+ Releases are published to PyPI by the `publish` workflow when a tag matching the package version (`v0.1.0`) is pushed. Playwright, mcp and aiohttp are pinned exactly in `pyproject.toml`, because an installed wheel does not use `uv.lock`.
108
+
109
+ The default test suite does not require a live browser or account login. See [third-party notices](../THIRD_PARTY.md) for runtime dependencies.