Core: атомизировать физический вход Paint - #484
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (15)
WalkthroughПереведены appearance-граф и ChangesАтомарные paint inputs
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant ProgramSession
participant AppearanceGraphSpec
participant AppearanceBindings
participant CompiledAppearanceProgram
ProgramSession->>AppearanceGraphSpec: lower PaintSpec::Input graph
ProgramSession->>AppearanceBindings: lower encoded paint inputs
AppearanceGraphSpec->>CompiledAppearanceProgram: compile and bind paint inputs
AppearanceBindings->>CompiledAppearanceProgram: admit and execute values
CompiledAppearanceProgram-->>ProgramSession: rendered target result
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai full review Exact-head review: |
|
✅ Action performedFull review finished. Your included review limit is currently reached under our Fair Usage Limits Policy. Your recent PR review activity is in the 95th percentile or higher among CodeRabbit users, so adaptive limits apply. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 24 minutes. |
|
RCA первого MSRV gate: compile не начинался — exact clean-set receipt корректно отверг изменённые whole-file bytes Exact verification: |
|
RCA WASM gate на exact head В |
|
@coderabbitai full review Exact-head review: |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
expected='692b66c9fc3bbf605bdfc0aff666e85b673c67fd'
echo "HEAD: $(git rev-parse HEAD)"
git cat-file -e "${expected}^{commit}"
base="$(git merge-base "${expected}" origin/main 2>/dev/null || git merge-base "${expected}" main)"
echo "MERGE_BASE: $base"
echo '--- CHANGED FILES ---'
git diff --name-status "$base" "$expected"
echo '--- DIFF STAT ---'
git diff --stat "$base" "$expected"
echo '--- CANDIDATE FILES ---'
fd -t f . | rg -i 'appearance|program_session|paint|point.*support|receipt|wasm|contract|binding|proof'
echo '--- ATOMIC AND LEGACY SYMBOL REFERENCES ---'
rg -n -i -C 2 \
'EncodedPointPaintValueV1|PaintInputId|PaintSpec::Input|ColorInput|Solid|set.*(source|opacity|alpha)|source.*setter|opacity.*setter|base.*alpha|base_alpha|paint.*input' \
. \
-g '!target/**' -g '!node_modules/**' || true
echo '--- RECEIPT / WASM METADATA MATCHES ---'
rg -n -i -C 3 \
'2cdb16116e01efd9d76bff544e1b13dac1cc9a59208bf5ad5f42808c1e024cc0|376675|e70a9b2d6f55775c75a00bf81bc5fde0207df3d7ffc29d13ae00a349ab172971|3d548ed9c77adb1a99eaa37c8a3f9ff06526adaa18cee4085023d13e6f6731b7|30324408912|v3a-atomic-paint-input|PRODUCT_IDENTITY_VERIFIED' \
. \
-g '!target/**' -g '!node_modules/**' || trueLength of output: 196418 🏁 Script executed: #!/bin/bash
set -euo pipefail
expected='692b66c9fc3bbf605bdfc0aff666e85b673c67fd'
base="$(git merge-base "$expected" origin/main 2>/dev/null || git merge-base "$expected" main)"
printf 'HEAD=%s\nEXPECTED=%s\nBASE=%s\n' "$(git rev-parse HEAD)" "$expected" "$base"
echo '--- EXACT DIFF: IMPLEMENTATION / TESTS / RECEIPTS ---'
git diff --find-renames --find-copies --unified=30 "$base" "$expected" -- \
crates/labcolors-core/src/appearance.rs \
crates/labcolors-core/src/program_session.rs \
crates/labcolors-core/contracts/clean-set-srgb8-v1/receipt-v1.json \
crates/labcolors-core/contracts/clean-set-srgb8-v1/receipt-v1.sha256 \
packages/colors/bench/wasm.json \
scripts/check-wasm-size-budget.mjs \
scripts/verify_clean_set_receipt.py
echo '--- APPEARANCE MAP ---'
ast-grep outline crates/labcolors-core/src/appearance.rs --items all --type struct,enum,impl,function --match 'Paint|Appearance|Opacity|point_opacity' || true
echo '--- KEY IMPLEMENTATION SLICES ---'
sed -n '1,180p;1110,1328p;1928,1950p;2220,2320p' crates/labcolors-core/src/appearance.rs
sed -n '3128,3170p;4140,4190p;4690,4840p' crates/labcolors-core/src/program_session.rs
echo '--- PRIVATE LEGACY-API SEARCH (DEFINITIONS AND CALLS) ---'
rg -n -i -C 2 \
'(ColorInput|PaintSourceInput|SolidPaintInput|set_(paint_)?(source|opacity|alpha)|overwrite_(paint_)?(source|opacity|alpha)|bind_(paint_)?(source|opacity|alpha)|source_binding|opacity_binding)' \
crates/labcolors-core/src/appearance.rs \
crates/labcolors-core/src/program_session.rs \
crates/labcolors-core/src/*tests.rs || true
echo '--- ATOMIC / NUMERIC REGRESSION TEST NAMES AND BODIES ---'
rg -n -i -C 4 \
'(atomic|cartesian|base alpha|base_alpha|left.associ|subnormal|underflow|191|black.*0\.25|opacity.*multiply)' \
crates/labcolors-core/src/appearance.rs \
crates/labcolors-core/src/*tests.rs
echo '--- RECEIPT HASH VALIDATION ---'
python3 - <<'PY'
import hashlib, json
from pathlib import Path
root=Path('crates/labcolors-core/contracts/clean-set-srgb8-v1')
receipt=root/'receipt-v1.json'
data=json.loads(receipt.read_text())
for entry in data.get('source_files', []):
p=Path(entry['path'])
actual=hashlib.sha256(p.read_bytes()).hexdigest() if p.exists() else 'MISSING'
print(f"{entry['path']}: declared={entry['sha256']} actual={actual} ok={actual == entry['sha256']}")
print('receipt-v1.json sha256=', hashlib.sha256(receipt.read_bytes()).hexdigest())
print('receipt-v1.sha256=', (root/'receipt-v1.sha256').read_text().strip())
PY
echo '--- WASM RECEIPT / CHECKER ---'
cat packages/colors/bench/wasm.json
sed -n '1,260p' scripts/check-wasm-size-budget.mjsLength of output: 160875 🏁 Script executed: #!/bin/bash
set -euo pipefail
expected='692b66c9fc3bbf605bdfc0aff666e85b673c67fd'
base="$(git merge-base "$expected" origin/main 2>/dev/null || git merge-base "$expected" main)"
echo '--- COMPLETE CHANGE SCOPE ---'
git diff --name-status "$base" "$expected"
echo '--- PUBLIC PROGRAM / IDENTITY DIFF (SHOULD BE EMPTY) ---'
git diff --stat "$base" "$expected" -- \
crates/labcolors-core/src/program.rs \
crates/labcolors-core/src/program_identity.rs \
crates/labcolors-core/src/lib.rs
git diff --unified=5 "$base" "$expected" -- \
crates/labcolors-core/src/program.rs \
crates/labcolors-core/src/program_identity.rs \
crates/labcolors-core/src/lib.rs
echo '--- FOCUSED REGRESSION TEST BODIES ---'
sed -n '270,330p;735,875p;1200,1295p' crates/labcolors-core/src/appearance_graph_tests.rs
echo '--- SOURCE-OVER / POINT-SUPPORT CLAIM REFERENCES ---'
rg -n -C 3 \
'PhysicalProgramIdentityV1|InputOpacityOverSurfaceEncodedSrgb8V1|point_program_matches|source-over|source over|mathematical|математичес|replay' \
crates/labcolors-core/src/appearance.rs \
crates/labcolors-core/src/appearance_graph_tests.rs \
crates/labcolors-core/src/appearance_replay_tests.rs \
crates/labcolors-core/src/point_support.rs \
crates/labcolors-core/contracts/point-support-*.json || true
echo '--- STRICT LEGACY IDENTIFIER ABSENCE ---'
rg -n -i '\b(ColorInputId|CompiledColorInputSlotV1|PaintSpec::Solid|CompiledPaintSpec::Solid|DuplicateColorInput|MissingPaintColorInput|DuplicateColorBinding|MissingColorBinding|UnexpectedColorBinding|bind_color_input|overwrite_color_at)\b' \
crates/labcolors-core --glob '*.rs' || true
echo '--- COMPLETE CLEAN-SET RECEIPT VALIDATION ---'
python3 - <<'PY'
import hashlib, json
from pathlib import Path
root=Path('crates/labcolors-core/contracts/clean-set-srgb8-v1')
receipt=root/'receipt-v1.json'
data=json.loads(receipt.read_text())
bad=[]
for group in ('artifacts','source_files'):
for e in data.get(group,[]):
p=Path(e['path'])
exists=p.is_file()
raw=p.read_bytes() if exists else b''
digest=hashlib.sha256(raw).hexdigest() if exists else 'MISSING'
size=len(raw) if exists else None
hashok=digest == e.get('sha256')
sizeok=('bytes' not in e or size == e['bytes'])
print(f'{group} {p}: exists={exists} size={size} declared_size={e.get("bytes")} size_ok={sizeok} hash_ok={hashok}')
if not exists or not hashok or not sizeok: bad.append(str(p))
print('receipt_sha256=',hashlib.sha256(receipt.read_bytes()).hexdigest())
print('bad_entries=',bad)
PY
echo '--- RECEIPT VERIFIER CONTRACT (NON-EXECUTED) ---'
rg -n -C 5 'def verify_product_receipt|artifacts|source_files|sha256|bytes|PRODUCT_IDENTITY_VERIFIED' \
scripts/verify_clean_set_receipt.py
echo '--- WASM RUN AND PR CHECK STATUS (READ-ONLY GITHUB METADATA) ---'
gh run view 30324408912 --repo Labpics-Team/lab-colors --json databaseId,status,conclusion,event,headSha,workflowName,createdAt,updatedAt,url,jobs 2>&1 || true
gh pr view 484 --repo Labpics-Team/lab-colors --json headRefOid,statusCheckRollup,url 2>&1 || trueLength of output: 95471
Проверено:
✅ Action performedFull review finished. |
Корневая проблема
Private appearance-runtime представлял source и base alpha разными входами. Finite Program пока менял только source, поэтому следующий alpha/glass-срез мог бы создать недекларированные Cartesian-пары.
Изменение
PaintInputId -> EncodedPointPaintValueV1 { source, opacity };PaintSpec::Inputзаменяет privateSolid + ColorInput;alpha = 1;Public Program/identity V3 в этом PR намеренно не меняются. Atomic finite candidates и identity V4 — следующий отдельный срез.
RED -> GREEN
Первый RED: один Paint input
black@0.25на белом должен дать[191;3]без отдельного opacity-узла; прежний IR не мог представить вход.Дополнительный hostile oracle доказывает
base alpha × modifier(s)в точном left-associated binary64 порядке, включая subnormal/underflow. Мутант, забывающий base alpha, даёт RED.Проверки exact head
-D warnings, rustfmt: green;Review focus
Проверить, что
PaintIdостаётся topology identity, атомарное input value не несёт ID, отдельного source/alpha setter больше нет, а public behavior и numerical proof law не изменены.Summary by CodeRabbit