nkscan 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.
- nkscan-0.1.0/.envrc +1 -0
- nkscan-0.1.0/.github/workflows/ci.yml +135 -0
- nkscan-0.1.0/.github/workflows/release.yml +178 -0
- nkscan-0.1.0/.gitignore +5 -0
- nkscan-0.1.0/CONTRIBUTING.md +38 -0
- nkscan-0.1.0/Cargo.lock +2241 -0
- nkscan-0.1.0/Cargo.toml +79 -0
- nkscan-0.1.0/LICENSE-APACHE +202 -0
- nkscan-0.1.0/LICENSE-MIT +17 -0
- nkscan-0.1.0/PKG-INFO +143 -0
- nkscan-0.1.0/README.md +123 -0
- nkscan-0.1.0/flake.lock +98 -0
- nkscan-0.1.0/flake.nix +128 -0
- nkscan-0.1.0/nkscan.pyi +205 -0
- nkscan-0.1.0/pyproject.toml +32 -0
- nkscan-0.1.0/rust-toolchain.toml +4 -0
- nkscan-0.1.0/src/bin/nkscan/main.rs +453 -0
- nkscan-0.1.0/src/bin/stub_gen.rs +45 -0
- nkscan-0.1.0/src/decode.rs +232 -0
- nkscan-0.1.0/src/devices.rs +403 -0
- nkscan-0.1.0/src/lib.rs +14 -0
- nkscan-0.1.0/src/output.rs +163 -0
- nkscan-0.1.0/src/python.rs +492 -0
- nkscan-0.1.0/src/scanners/ls50/boundaries.rs +197 -0
- nkscan-0.1.0/src/scanners/ls50/calibration.rs +91 -0
- nkscan-0.1.0/src/scanners/ls50/capabilities.rs +172 -0
- nkscan-0.1.0/src/scanners/ls50/cdbs/mod.rs +3 -0
- nkscan-0.1.0/src/scanners/ls50/cdbs/vendor_read_write.rs +210 -0
- nkscan-0.1.0/src/scanners/ls50/decode.rs +40 -0
- nkscan-0.1.0/src/scanners/ls50/dtc.rs +157 -0
- nkscan-0.1.0/src/scanners/ls50/geometry.rs +289 -0
- nkscan-0.1.0/src/scanners/ls50/holder.rs +164 -0
- nkscan-0.1.0/src/scanners/ls50/mod.rs +1013 -0
- nkscan-0.1.0/src/scanners/ls50/status.rs +164 -0
- nkscan-0.1.0/src/scanners/ls50/window.rs +195 -0
- nkscan-0.1.0/src/scanners/ls5000/boundaries.rs +229 -0
- nkscan-0.1.0/src/scanners/ls5000/calibration.rs +113 -0
- nkscan-0.1.0/src/scanners/ls5000/capabilities.rs +188 -0
- nkscan-0.1.0/src/scanners/ls5000/cdbs/mod.rs +1 -0
- nkscan-0.1.0/src/scanners/ls5000/cdbs/vendor_read_write.rs +206 -0
- nkscan-0.1.0/src/scanners/ls5000/decode.rs +49 -0
- nkscan-0.1.0/src/scanners/ls5000/dtc.rs +209 -0
- nkscan-0.1.0/src/scanners/ls5000/geometry.rs +361 -0
- nkscan-0.1.0/src/scanners/ls5000/holder.rs +160 -0
- nkscan-0.1.0/src/scanners/ls5000/mod.rs +564 -0
- nkscan-0.1.0/src/scanners/ls5000/status.rs +163 -0
- nkscan-0.1.0/src/scanners/ls5000/tests.rs +576 -0
- nkscan-0.1.0/src/scanners/ls5000/window.rs +200 -0
- nkscan-0.1.0/src/scanners/ls9000/boundaries.rs +533 -0
- nkscan-0.1.0/src/scanners/ls9000/calibration.rs +121 -0
- nkscan-0.1.0/src/scanners/ls9000/capabilities.rs +72 -0
- nkscan-0.1.0/src/scanners/ls9000/cdbs/mod.rs +4 -0
- nkscan-0.1.0/src/scanners/ls9000/cdbs/trigger.rs +26 -0
- nkscan-0.1.0/src/scanners/ls9000/cdbs/vendor_read_write.rs +156 -0
- nkscan-0.1.0/src/scanners/ls9000/decode.rs +526 -0
- nkscan-0.1.0/src/scanners/ls9000/dtc.rs +180 -0
- nkscan-0.1.0/src/scanners/ls9000/geometry.rs +284 -0
- nkscan-0.1.0/src/scanners/ls9000/holder.rs +93 -0
- nkscan-0.1.0/src/scanners/ls9000/mod.rs +977 -0
- nkscan-0.1.0/src/scanners/ls9000/status.rs +212 -0
- nkscan-0.1.0/src/scanners/ls9000/window.rs +245 -0
- nkscan-0.1.0/src/scanners/mod.rs +274 -0
- nkscan-0.1.0/src/scanners/nikon/capabilities.rs +238 -0
- nkscan-0.1.0/src/scanners/nikon/cdbs.rs +153 -0
- nkscan-0.1.0/src/scanners/nikon/decode.rs +243 -0
- nkscan-0.1.0/src/scanners/nikon/dtc.rs +122 -0
- nkscan-0.1.0/src/scanners/nikon/metering.rs +300 -0
- nkscan-0.1.0/src/scanners/nikon/mod.rs +189 -0
- nkscan-0.1.0/src/scsi/asc.rs +212 -0
- nkscan-0.1.0/src/scsi/cdbs/inquiry.rs +225 -0
- nkscan-0.1.0/src/scsi/cdbs/mod.rs +22 -0
- nkscan-0.1.0/src/scsi/cdbs/mode_select.rs +60 -0
- nkscan-0.1.0/src/scsi/cdbs/mode_sense.rs +280 -0
- nkscan-0.1.0/src/scsi/cdbs/read_send.rs +255 -0
- nkscan-0.1.0/src/scsi/cdbs/reservation.rs +130 -0
- nkscan-0.1.0/src/scsi/cdbs/scan.rs +99 -0
- nkscan-0.1.0/src/scsi/cdbs/send_diagnostic.rs +120 -0
- nkscan-0.1.0/src/scsi/cdbs/test_unit_ready.rs +28 -0
- nkscan-0.1.0/src/scsi/cdbs/window.rs +490 -0
- nkscan-0.1.0/src/scsi/fields.rs +47 -0
- nkscan-0.1.0/src/scsi/linux.rs +394 -0
- nkscan-0.1.0/src/scsi/macos.rs +34 -0
- nkscan-0.1.0/src/scsi/mock.rs +223 -0
- nkscan-0.1.0/src/scsi/mod.rs +380 -0
- nkscan-0.1.0/src/scsi/mode_pages/measurement_units.rs +147 -0
- nkscan-0.1.0/src/scsi/mode_pages/mod.rs +45 -0
- nkscan-0.1.0/src/scsi/usb.rs +253 -0
- nkscan-0.1.0/src/scsi/windows.rs +289 -0
- nkscan-0.1.0/src/session/ls50.rs +219 -0
- nkscan-0.1.0/src/session/ls5000.rs +236 -0
- nkscan-0.1.0/src/session/ls9000.rs +295 -0
- nkscan-0.1.0/src/session/mod.rs +597 -0
nkscan-0.1.0/.envrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
use flake
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths-ignore: &docs-paths
|
|
7
|
+
- "**.md"
|
|
8
|
+
- "LICENSE-*"
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [main]
|
|
11
|
+
paths-ignore: *docs-paths
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
# Cancel superseded runs for the same branch/PR - these nix jobs are heavy.
|
|
15
|
+
concurrency:
|
|
16
|
+
group: ci-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: true
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
packages: write
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
check:
|
|
25
|
+
name: Nix Flake Check
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
permissions:
|
|
28
|
+
contents: read
|
|
29
|
+
security-events: write # upload clippy findings as code scanning results
|
|
30
|
+
steps:
|
|
31
|
+
- name: Checkout repository
|
|
32
|
+
uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Install Nix
|
|
35
|
+
uses: DeterminateSystems/nix-installer-action@v13
|
|
36
|
+
|
|
37
|
+
- name: Setup Nix cache
|
|
38
|
+
uses: DeterminateSystems/magic-nix-cache-action@v7
|
|
39
|
+
|
|
40
|
+
- name: Run flake checks
|
|
41
|
+
run: nix flake check --print-build-logs --keep-going
|
|
42
|
+
|
|
43
|
+
# The stub is what a consumer sees of an abi3 extension, since one carries no introspectable
|
|
44
|
+
# signatures. It is generated, so this only has to catch a commit that forgot to regenerate.
|
|
45
|
+
stubs:
|
|
46
|
+
name: Stub is up to date
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
steps:
|
|
49
|
+
- name: Checkout repository
|
|
50
|
+
uses: actions/checkout@v4
|
|
51
|
+
|
|
52
|
+
- name: Install Rust
|
|
53
|
+
uses: dtolnay/rust-toolchain@master
|
|
54
|
+
with:
|
|
55
|
+
toolchain: "1.96"
|
|
56
|
+
|
|
57
|
+
- name: Cache Rust artifacts
|
|
58
|
+
uses: Swatinem/rust-cache@v2
|
|
59
|
+
|
|
60
|
+
# pyo3 needs an interpreter to build against. numpy is not needed: the generator
|
|
61
|
+
# reads type information rather than calling into it.
|
|
62
|
+
- name: Install Python
|
|
63
|
+
uses: actions/setup-python@v5
|
|
64
|
+
with:
|
|
65
|
+
python-version: "3.13"
|
|
66
|
+
|
|
67
|
+
- name: Regenerate
|
|
68
|
+
run: cargo run --features python --bin stub_gen
|
|
69
|
+
|
|
70
|
+
- name: Fail if it differs from what is committed
|
|
71
|
+
run: |
|
|
72
|
+
if ! git diff --exit-code nkscan.pyi; then
|
|
73
|
+
echo "::error::nkscan.pyi is stale, run: cargo run --features python --bin stub_gen"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# The flake checks that the bindings compile, but only a manylinux build proves the wheel a
|
|
78
|
+
# consumer would actually install. Nix cannot produce one: it links against nix-store glibc
|
|
79
|
+
# with nix-store rpaths, and the result is tagged linux_x86_64, which no index accepts.
|
|
80
|
+
#
|
|
81
|
+
# Run on every change rather than at tag time, when a release is already half published.
|
|
82
|
+
wheel:
|
|
83
|
+
name: Build wheel
|
|
84
|
+
runs-on: ubuntu-latest
|
|
85
|
+
steps:
|
|
86
|
+
- name: Checkout repository
|
|
87
|
+
uses: actions/checkout@v4
|
|
88
|
+
|
|
89
|
+
- name: Build wheel
|
|
90
|
+
uses: PyO3/maturin-action@v1
|
|
91
|
+
with:
|
|
92
|
+
args: --release --out dist
|
|
93
|
+
manylinux: auto
|
|
94
|
+
|
|
95
|
+
# The runner's default python is older than the abi3 floor, so pip would refuse a
|
|
96
|
+
# cp313 wheel. Both versions are installed to prove the point of abi3: one wheel
|
|
97
|
+
# covers the floor and every interpreter after it.
|
|
98
|
+
- name: Install the interpreters the wheel claims to support
|
|
99
|
+
uses: actions/setup-python@v5
|
|
100
|
+
with:
|
|
101
|
+
python-version: |
|
|
102
|
+
3.13
|
|
103
|
+
3.14
|
|
104
|
+
|
|
105
|
+
- name: Check it is tagged for redistribution
|
|
106
|
+
run: |
|
|
107
|
+
ls -l dist/
|
|
108
|
+
# abi3 names one interpreter floor and works on every later one, so a wheel
|
|
109
|
+
# tagged for a single version means the abi3 feature stopped taking effect
|
|
110
|
+
for wheel in dist/*.whl; do
|
|
111
|
+
case "$wheel" in
|
|
112
|
+
*abi3-manylinux*) echo "ok: $wheel" ;;
|
|
113
|
+
*) echo "::error::$wheel will not install off this machine" && exit 1 ;;
|
|
114
|
+
esac
|
|
115
|
+
done
|
|
116
|
+
|
|
117
|
+
- name: Check it installs and imports on every one of them
|
|
118
|
+
run: |
|
|
119
|
+
for python in python3.13 python3.14; do
|
|
120
|
+
echo "--- $python"
|
|
121
|
+
"$python" -m pip install --upgrade pip
|
|
122
|
+
"$python" -m pip install dist/*.whl
|
|
123
|
+
"$python" - <<'PY'
|
|
124
|
+
import nkscan, sys
|
|
125
|
+
print(" running on", sys.version.split()[0])
|
|
126
|
+
# No scanner is attached to a runner, so this exercises enumeration finding none
|
|
127
|
+
assert nkscan.list_devices() == []
|
|
128
|
+
assert issubclass(nkscan.TransportError, nkscan.TransientError)
|
|
129
|
+
try:
|
|
130
|
+
nkscan.Session("nonsense")
|
|
131
|
+
except nkscan.DeviceNotFound:
|
|
132
|
+
pass
|
|
133
|
+
print(" import, enumeration and error hierarchy all fine")
|
|
134
|
+
PY
|
|
135
|
+
done
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
packages: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build-linux:
|
|
14
|
+
name: Build Linux artifacts
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repository
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Install Nix
|
|
21
|
+
uses: DeterminateSystems/nix-installer-action@v13
|
|
22
|
+
|
|
23
|
+
- name: Setup Nix cache
|
|
24
|
+
uses: DeterminateSystems/magic-nix-cache-action@v7
|
|
25
|
+
|
|
26
|
+
- name: Build x86_64 binary
|
|
27
|
+
run: |
|
|
28
|
+
nix build --print-build-logs
|
|
29
|
+
cp result/bin/nkscan nkscan-x86_64-unknown-linux-gnu
|
|
30
|
+
|
|
31
|
+
- name: Upload Linux binaries to release
|
|
32
|
+
uses: softprops/action-gh-release@v2
|
|
33
|
+
with:
|
|
34
|
+
files: |
|
|
35
|
+
nkscan-x86_64-unknown-linux-gnu
|
|
36
|
+
|
|
37
|
+
build-windows:
|
|
38
|
+
name: Build Windows artifact
|
|
39
|
+
runs-on: windows-latest
|
|
40
|
+
steps:
|
|
41
|
+
- name: Checkout repository
|
|
42
|
+
uses: actions/checkout@v4
|
|
43
|
+
|
|
44
|
+
- name: Install Rust
|
|
45
|
+
uses: dtolnay/rust-toolchain@master
|
|
46
|
+
with:
|
|
47
|
+
toolchain: "1.96"
|
|
48
|
+
|
|
49
|
+
- name: Cache Rust artifacts
|
|
50
|
+
uses: Swatinem/rust-cache@v2
|
|
51
|
+
|
|
52
|
+
- name: Build Windows binary
|
|
53
|
+
run: |
|
|
54
|
+
cargo build --release -p nkscan --features=cli
|
|
55
|
+
cp target/release/nkscan.exe nkscan-x86_64-pc-windows-msvc.exe
|
|
56
|
+
|
|
57
|
+
- name: Upload Windows binary to release
|
|
58
|
+
uses: softprops/action-gh-release@v2
|
|
59
|
+
with:
|
|
60
|
+
files: nkscan-x86_64-pc-windows-msvc.exe
|
|
61
|
+
|
|
62
|
+
# ---- Python wheels
|
|
63
|
+
#
|
|
64
|
+
# maturin rather than nix: a nix-built extension links against nix-store glibc with
|
|
65
|
+
# nix-store rpaths and its wheel is tagged linux_x86_64, which no index accepts and which
|
|
66
|
+
# would not load off this machine anyway. maturin builds Linux wheels inside manylinux
|
|
67
|
+
# containers and runs auditwheel over the result.
|
|
68
|
+
#
|
|
69
|
+
# One wheel per platform, not per interpreter: the abi3-py313 feature makes a single build
|
|
70
|
+
# work on 3.13 and everything after it, which is the floor NegPy asks for.
|
|
71
|
+
wheels:
|
|
72
|
+
name: Wheel ${{ matrix.platform }} ${{ matrix.target }}
|
|
73
|
+
runs-on: ${{ matrix.runner }}
|
|
74
|
+
strategy:
|
|
75
|
+
fail-fast: false
|
|
76
|
+
matrix:
|
|
77
|
+
include:
|
|
78
|
+
- { platform: linux, runner: ubuntu-latest, target: x86_64 }
|
|
79
|
+
- { platform: linux, runner: ubuntu-latest, target: aarch64 }
|
|
80
|
+
- { platform: macos, runner: macos-latest, target: x86_64 }
|
|
81
|
+
- { platform: macos, runner: macos-latest, target: aarch64 }
|
|
82
|
+
- { platform: windows, runner: windows-latest, target: x64 }
|
|
83
|
+
steps:
|
|
84
|
+
- name: Checkout repository
|
|
85
|
+
uses: actions/checkout@v4
|
|
86
|
+
|
|
87
|
+
- name: Build wheel
|
|
88
|
+
uses: PyO3/maturin-action@v1
|
|
89
|
+
with:
|
|
90
|
+
target: ${{ matrix.target }}
|
|
91
|
+
args: --release --out dist
|
|
92
|
+
# Cross-compiles the aarch64 Linux wheel in a manylinux container
|
|
93
|
+
manylinux: auto
|
|
94
|
+
sccache: "true"
|
|
95
|
+
|
|
96
|
+
- name: Upload wheel
|
|
97
|
+
uses: actions/upload-artifact@v4
|
|
98
|
+
with:
|
|
99
|
+
name: wheel-${{ matrix.platform }}-${{ matrix.target }}
|
|
100
|
+
path: dist
|
|
101
|
+
|
|
102
|
+
# A version on PyPI can never be reused, and maturin takes the version from Cargo.toml
|
|
103
|
+
# rather than from the tag, so a mistyped tag would otherwise publish the wrong one.
|
|
104
|
+
version:
|
|
105
|
+
name: Tag matches Cargo.toml
|
|
106
|
+
runs-on: ubuntu-latest
|
|
107
|
+
steps:
|
|
108
|
+
- name: Checkout repository
|
|
109
|
+
uses: actions/checkout@v4
|
|
110
|
+
|
|
111
|
+
- name: Compare
|
|
112
|
+
run: |
|
|
113
|
+
crate=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
|
|
114
|
+
tag=${GITHUB_REF_NAME#v}
|
|
115
|
+
echo "Cargo.toml says $crate, tag says $tag"
|
|
116
|
+
if [ "$crate" != "$tag" ]; then
|
|
117
|
+
echo "::error::tag $GITHUB_REF_NAME does not match Cargo.toml version $crate"
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
sdist:
|
|
122
|
+
name: Source distribution
|
|
123
|
+
runs-on: ubuntu-latest
|
|
124
|
+
steps:
|
|
125
|
+
- name: Checkout repository
|
|
126
|
+
uses: actions/checkout@v4
|
|
127
|
+
|
|
128
|
+
- name: Build sdist
|
|
129
|
+
uses: PyO3/maturin-action@v1
|
|
130
|
+
with:
|
|
131
|
+
command: sdist
|
|
132
|
+
args: --out dist
|
|
133
|
+
|
|
134
|
+
- name: Upload sdist
|
|
135
|
+
uses: actions/upload-artifact@v4
|
|
136
|
+
with:
|
|
137
|
+
name: wheel-sdist
|
|
138
|
+
path: dist
|
|
139
|
+
|
|
140
|
+
publish:
|
|
141
|
+
name: Publish to PyPI
|
|
142
|
+
needs: [version, wheels, sdist]
|
|
143
|
+
runs-on: ubuntu-latest
|
|
144
|
+
environment: pypi
|
|
145
|
+
permissions:
|
|
146
|
+
# Trusted publishing: PyPI verifies this workflow by OIDC, so there is no long-lived
|
|
147
|
+
# token in the repository. Register the publisher once at
|
|
148
|
+
# pypi.org/manage/account/publishing with owner, repo and this workflow's filename.
|
|
149
|
+
id-token: write
|
|
150
|
+
steps:
|
|
151
|
+
- name: Collect every wheel and the sdist
|
|
152
|
+
uses: actions/download-artifact@v4
|
|
153
|
+
with:
|
|
154
|
+
pattern: wheel-*
|
|
155
|
+
path: dist
|
|
156
|
+
merge-multiple: true
|
|
157
|
+
|
|
158
|
+
- name: Publish
|
|
159
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
160
|
+
with:
|
|
161
|
+
packages-dir: dist
|
|
162
|
+
|
|
163
|
+
attach-wheels:
|
|
164
|
+
name: Attach wheels to the release
|
|
165
|
+
needs: [version, wheels, sdist]
|
|
166
|
+
runs-on: ubuntu-latest
|
|
167
|
+
steps:
|
|
168
|
+
- name: Collect every wheel and the sdist
|
|
169
|
+
uses: actions/download-artifact@v4
|
|
170
|
+
with:
|
|
171
|
+
pattern: wheel-*
|
|
172
|
+
path: dist
|
|
173
|
+
merge-multiple: true
|
|
174
|
+
|
|
175
|
+
- name: Upload to release
|
|
176
|
+
uses: softprops/action-gh-release@v2
|
|
177
|
+
with:
|
|
178
|
+
files: dist/*
|
nkscan-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Contributing to this project
|
|
2
|
+
|
|
3
|
+
All help is welcome and greatly appreciated!
|
|
4
|
+
If you would like to contribute to the project, we ask you adhere to the following policies:
|
|
5
|
+
|
|
6
|
+
## Before you open a PR
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
cargo fmt
|
|
10
|
+
cargo clippy --all-targets # should be silent
|
|
11
|
+
cargo test
|
|
12
|
+
rg -nP '[^\x00-\x7F]' src/ examples/ # should find nothing
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The source is ASCII only. No em dashes, smart quotes or arrows, in code or comments.
|
|
16
|
+
|
|
17
|
+
## AI Assistance
|
|
18
|
+
|
|
19
|
+
Using AI tools to help you contribute is nominally ok, we just want to remind you that
|
|
20
|
+
*you* are asking the maintainers (human people) review your code and you need to be in the loop of that process.
|
|
21
|
+
As such, we ask that you use AI as a tool to help you write code, not as an agent that autonomously generates
|
|
22
|
+
an entire contribution and submits it on your behalf.
|
|
23
|
+
|
|
24
|
+
A few simple expectations:
|
|
25
|
+
|
|
26
|
+
- **Understand your code.** You should be able to explain and answer questions about anything you submit.
|
|
27
|
+
- **Write the PR description in your own words.** A short, clear explanation of *your* change is far more useful than a pasted AI summary.
|
|
28
|
+
- **Test your change** before opening the PR.
|
|
29
|
+
- **Keep it focused.** A PR that claims to fix one thing but touches a lot of unrelated code is hard to review (broad prompts tend to cause this).
|
|
30
|
+
- **Disclose AI assistance** in the PR description, along with roughly how much was used (e.g. docs only vs. code generation). Trivial tab-completion of single keywords or short phrases doesn't need to be disclosed.
|
|
31
|
+
|
|
32
|
+
Example disclosures:
|
|
33
|
+
|
|
34
|
+
> **AI Disclosure:** This PR was written primarily by Claude Code.
|
|
35
|
+
> **AI Disclosure:** I consulted ChatGPT to understand the codebase, but the solution was authored manually.
|
|
36
|
+
> **AI Disclosure:** None.
|
|
37
|
+
|
|
38
|
+
Disclosure isn't about discouraging AI use,it just helps reviewers know how much scrutiny a change needs, and it's a courtesy to the humans on the other end of the pull request.
|