This report summarizes scanner evidence for storytold/photocraft. SynthScan examined 837,268 lines of code across 2390 source files, recording 785 pattern matches distributed across 9 syntactic categories. The legacy adjusted pattern signal is 1.1 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 745 finding(s).
Are imports declared and package/API names verified? 38 finding(s).
Are wrappers, guards, and repeated structures necessary? 2 finding(s).
Which changes need focused human review? 785 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 785 distinct pattern matches across 9 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Cargo.toml | 101 | # Test builds compile ui-egui without optimization: its library and unit tests were the biggest | COMMENT |
| LOW | packaging/env.sh | 1 | # shellcheck shell=bash | COMMENT |
| LOW | packaging/macos/verify.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | packaging/macos/package.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | packaging/web/package.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | packaging/freebsd/package.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | packaging/linux/flatpak-oci.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | packaging/linux/package.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | packaging/linux/flatpak-bundle.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | packaging/linux/flatpak/ai.storyteller.photocraft.yml | 1 | # Flatpak manifest for PhotoCraft, ready for a Flathub submission. | COMMENT |
| LOW | packaging/linux/flatpak/ai.storyteller.photocraft.yml | 21 | - --filesystem=xdg-data/ArtCraft/versions:ro | COMMENT |
| LOW | …ing/linux/flatpak/ai.storyteller.photocraft.bundle.yml | 1 | # Flatpak manifest for the single-file bundle attached to every GitHub release | COMMENT |
| LOW | …ing/linux/flatpak/ai.storyteller.photocraft.bundle.yml | 21 | # Display: Wayland first; X11 only when no Wayland compositor is running. | COMMENT |
| LOW | .config/nextest.toml | 1 | # Refuse to run under a nextest older than the fixed release: GHSA-vc25-qg58-w57c is fixed in | COMMENT |
| LOW | crates/paint/src/retouch.rs | 1 | //! Generic dab-driven stroke machinery for the retouching tools (Clone Stamp, Healing Brush, Spot | COMMENT |
| LOW | crates/paint/src/render.rs | 161 | r.clamp(0.0, 1.0) | COMMENT |
| LOW | crates/paint/src/lib.rs | 1 | //! Brush engine: Photoshop-grade brushes (computed and sampled tips, Shape Dynamics, Scattering, | COMMENT |
| LOW | crates/paint/src/tile.rs | 81 | /// thousand big sampled brushes costs a few small previews in memory, not gigabytes of bitmaps. | COMMENT |
| LOW | crates/paint/src/brush.rs | 561 | pub flow: f32, | COMMENT |
| LOW | crates/paint/src/brush.rs | 781 | /// dialog's boxes. | COMMENT |
| LOW | crates/paint/src/curve.rs | 1 | //! A response curve: how a 0..1 input (pen pressure, tilt, wheel, a fade ramp) maps to a 0..1 | COMMENT |
| LOW | crates/tablet/src/lib.rs | 1 | //! Pen tablet input that the windowing layer (winit 0.30) drops: pressure, tilt, barrel rotation | COMMENT |
| LOW | crates/tablet/src/lib.rs | 21 | //! pointer for the pen, so pen motion would have to be re-injected into egui as well. Without | COMMENT |
| LOW | crates/tablet/src/x11.rs | 1 | //! XInput2 raw tablet events on X11, over a separate pure-Rust X connection (x11rb's | COMMENT |
| LOW | crates/tablet/src/xi.rs | 1 | //! XInput2 tablet valuators → [`Sample`]s. Pure (no X calls), so it is tested on every platform; | COMMENT |
| LOW | crates/tablet/src/appkit.rs | 1 | //! AppKit `NSEvent` tablet fields → [`Sample`]s. Pure (no AppKit calls), so it is tested on | COMMENT |
| LOW | crates/gpu/tests/it/timing.rs | 1 | //! The canvas timing must measure GPU *execution*, not encode-and-submit (#7186). | COMMENT |
| LOW | crates/gpu/src/camera_raw.rs | 1 | //! Camera Raw's per-pixel develop on the GPU, for the dialog's interactive preview (#6916). | COMMENT |
| LOW | crates/gpu/src/consts.rs | 41 | pub const PATTERN_IDLE_FRAMES: u64 = 240; | COMMENT |
| LOW | crates/gpu/src/health.rs | 1 | //! Device health (#243): notices a lost wgpu device or an uncaptured wgpu error so callers stop | COMMENT |
| LOW | crates/gpu/src/health.rs | 121 | /// on a poll, and `Device::poll` panics on a lost device). | COMMENT |
| LOW | crates/gpu/src/lib.rs | 1 | //! GPU compositor (architecture §7.2, milestone M5). | COMMENT |
| LOW | crates/gpu/src/lib.rs | 21 | //! RGBA32F accumulators, reused) that bind only that cell's pages, and each finished chunk is | COMMENT |
| LOW | crates/gpu/src/prefix.rs | 1 | //! One lower-stack composite, held in bounded chunk textures. Exact COW snapshots deliberately | COMMENT |
| LOW | crates/gpu/src/plan.rs | 1 | //! Planner: walks the layer tree into a linear list of GPU passes over abstract buffer slots. | COMMENT |
| LOW | crates/gpu/src/paging.rs | 101 | /// [`Unsupported`] instead of letting it escape to wgpu's panic handler. | COMMENT |
| LOW | crates/gpu/src/fx.rs | 1 | //! Effect maps on the GPU (`photocraft_compose::effects::build_maps`). | COMMENT |
| LOW | crates/gpu/src/fx.rs | 361 | /// [`field_radius`], so a part is computed from a window grown by it. | COMMENT |
| LOW | crates/gpu/src/timing.rs | 1 | //! GPU execution time of a composite (#7186), measured with wgpu timestamp queries. | COMMENT |
| LOW | crates/gpu/src/timing.rs | 21 | //! the render targets. Measured against a waited-for wall clock on Intel UHD P630 / Mesa, with | COMMENT |
| LOW | crates/gpu/src/timing.rs | 81 | read: wgpu::Buffer, | COMMENT |
| LOW | crates/codecs/tests/it/exr_cryptomatte.rs | 1 | //! Cryptomatte (specification 1.2): the hash function is checked against the official | COMMENT |
| LOW | crates/codecs/tests/it/deep_exr.rs | 1 | //! Deep EXR: a synthetic generator builds deep chunks per the OpenEXR file layout | COMMENT |
| LOW | crates/codecs/src/exif_color.rs | 1 | //! The EXIF ColorSpace tag (0xA001, in the Exif sub-IFD that IFD0's tag 0x8769 points to): | COMMENT |
| LOW | crates/codecs/src/lib.rs | 1 | //! `photocraft-codecs`: symmetric, depth- and metadata-preserving codecs for | COMMENT |
| LOW | crates/codecs/src/orientation.rs | 1 | //! EXIF / TIFF orientation (tag 274): reading it, applying it to the pixels, | COMMENT |
| LOW | crates/codecs/src/options.rs | 1 | //! Decode limits and encode options. | COMMENT |
| LOW | crates/codecs/src/options.rs | 301 | /// Write an `sTER` chunk marking the image as a stereo pair (PNG Extensions 1.4.0, §3.6), | COMMENT |
| LOW | crates/codecs/src/source_settings.rs | 1 | //! The encoder settings a lossy file was written with, read back from its own data, so a save | COMMENT |
| LOW | crates/codecs/src/image.rs | 141 | pub text: Vec<(String, String)>, | COMMENT |
| LOW | crates/codecs/src/image.rs | 181 | /// held more than was decoded, or less than it should. | COMMENT |
| LOW | crates/codecs/src/image.rs | 281 | pub name: String, | COMMENT |
| LOW | crates/codecs/src/resolution.rs | 1 | //! Image resolution (pixels per inch) recorded in metadata blocks: EXIF / TIFF IFD0 | COMMENT |
| LOW | crates/codecs/src/cicp.rs | 1 | //! ITU-T H.273 colour descriptions (CICP: coding-independent code points), as HEIF `colr` | COMMENT |
| LOW | crates/codecs/src/codecs/iff.rs | 1 | //! Amiga IFF/ILBM reader and writer (EA "Interchange File Format", "InterLeaved BitMap" and the | COMMENT |
| LOW | crates/codecs/src/codecs/jpeg.rs | 1 | //! JPEG: decode via `zune-jpeg` (gray, YCbCr, CMYK, YCCK; arithmetic-coded and 12-bit files | COMMENT |
| LOW | crates/codecs/src/codecs/tiff_exif.rs | 1 | //! EXIF in a TIFF file: the Exif (34665) and GPS (34853) directories that IFD0 points to, plus | COMMENT |
| LOW | crates/codecs/src/codecs/tiff_exif.rs | 21 | /// IFD0's pointer to the GPS directory. | COMMENT |
| LOW | crates/codecs/src/codecs/fits.rs | 1 | //! FITS (Flexible Image Transport System, FITS Standard 4.0), implemented here: the image in the | COMMENT |
| LOW | crates/codecs/src/codecs/tiff.rs | 1 | //! TIFF and BigTIFF: 1/2/4/8/16/32/64-bit integer and 16/32/64-bit float samples, gray / RGB / | COMMENT |
| 663 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | crates/ui-egui/src/tools/crop_shield.rs | 206 | let rgb = app.ui.tool_options.crop_shield.custom_color.map(|v| v as f32 / 255.0); | CODE |
| CRITICAL | crates/ui-egui/src/tools/retouch_ui.rs | 53 | json!({"mode": app.session.tools.brush.mode.label()}) | CODE |
| CRITICAL | crates/ui-egui/src/tools/retouch_ui.rs | 102 | "mode": app.session.tools.brush.mode.label(), | CODE |
| CRITICAL | crates/ui-egui/src/tools/gradient_ui/tests.rs | 350 | let before = app.session.presets.gradient.stops.len(); | CODE |
| CRITICAL | crates/ui-egui/src/panels/brush_panel.rs | 459 | let texture = app.session.tools.brush.texture.clone(); | CODE |
| CRITICAL | crates/ui-egui/src/canvas/strokes.rs | 73 | let overlay = app.session.presets.clone.overlay.clone(); | CODE |
| CRITICAL | crates/ui-egui/src/canvas/tests.rs | 1864 | assert!(app.session.tools.mixer.spatial.is_some()); | CODE |
| CRITICAL | crates/ui-egui/src/canvas/tests.rs | 2050 | assert!(app.session.tools.mixer.spatial.is_none(), "the held Move tool doesn't sample"); | CODE |
| CRITICAL | crates/ui-egui/src/canvas/tests.rs | 2053 | assert!(app.session.tools.mixer.spatial.is_some(), "⌥ with the Mixer Brush itself samples"); | CODE |
| CRITICAL | crates/ui-egui/src/canvas/background_redraw.rs | 232 | app.session.color.settings.blend_text_gamma.to_bits() | CODE |
| CRITICAL | crates/engine/src/cmd/brush_cmds/tests.rs | 434 | let chalk_pattern = s.tools.brush.texture.pattern.clone(); | CODE |
| CRITICAL | crates/engine/src/cmd/brush_cmds/tests.rs | 1303 | assert!(s.tools.brush.shape_dynamics.size.curve.is_linear()); | CODE |
| CRITICAL | crates/engine/src/preset_store/tests.rs | 589 | assert_eq!(t.tools.brush.texture.pattern.bitmap(), Some(&tips[1])); | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | crates/paint/src/procedural.rs | 36 | /// Generate a seamless pattern tile. | COMMENT |
| MEDIUM | crates/compose/src/pattern.rs | 6 | //! exactly and scaled ones stay seamless. Below 100 % each document pixel averages an | COMMENT |
| MEDIUM | crates/algo/examples/bench_retouch.rs | 1 | //! Timing of the retouch kernels alone (no document plumbing): Poisson seamless clone and | COMMENT |
| MEDIUM | crates/algo/src/features.rs | 2 | //! robust model fitting. | COMMENT |
| MEDIUM | crates/algo/src/dff.rs | 49 | /// `min(1, robust / |d − u|)` (in layers) and the system is solved once more. 0 = off. | COMMENT |
| MEDIUM | crates/algo/src/hdr.rs | 129 | /// neighbourhood is flat in the middle exposure (robust to small misalignment), stratified by | COMMENT |
| MEDIUM | crates/algo/src/inpaint/solver.rs | 571 | // σ² from the 75th percentile of match costs (Wexler et al. use a robust scale like this). | COMMENT |
| MEDIUM | crates/ui-egui/examples/perf_scenarios.rs | 977 | /// #9328: the whole app (kittest harness, CPU canvas) with a 24 MP document; each sample toggles | COMMENT |
| MEDIUM | crates/ui-egui/src/jobs_ui/tests.rs | 1 | //! UI tests for background jobs (#210): the whole app (eframe harness, CPU canvas) keeps | COMMENT |
| MEDIUM | crates/ui-egui/src/canvas/pattern_preview.rs | 2 | //! seamless tile, so what leaves one edge is seen coming back at the opposite one. The copies | COMMENT |
| MEDIUM | crates/engine/src/cmd/retouch_cmds/patch.rs | 5 | //! `destination` mode the selected pixels are copied to the dragged outline and repair it. Either way the copied textur | COMMENT |
| MEDIUM | xtask/src/stats.rs | 104 | println!("\n(#[test] counts source attributes; macro-generated tests count once. Use --exact for harness counts. | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | crates/io/tests/it/psd_style_sheets.rs | 93 | "LOREM IPSUM", | CODE |
| LOW | crates/io/tests/it/psd_style_sheets.rs | 99 | let t = layer("LOREM IPSUM", &ed); | CODE |
| LOW | crates/io/tests/it/psd_style_sheets.rs | 182 | "LOREM IPSUM", | CODE |
| LOW | crates/io/tests/it/psd_style_sheets.rs | 188 | let mut t = layer("LOREM IPSUM", &ed); | CODE |
| LOW | crates/io/tests/it/psd_style_sheets.rs | 207 | "LOREM IPSUM", | CODE |
| LOW | crates/io/tests/it/psd_style_sheets.rs | 213 | let mut t = layer("LOREM IPSUM", &ed); | CODE |
| LOW | crates/ui-egui/src/menu_catalog.rs | 502 | (&["Type"], "Paste Lorem Ipsum", None, "type.pasteLoremIpsum"), | CODE |
| LOW | crates/ui-egui/src/prefs/prefs_ui/tests.rs | 138 | assert!(contains("placeholder", "type")); | CODE |
| LOW | crates/ui-egui/src/tools/type_tool.rs | 84 | pub const PLACEHOLDER: &str = "Lorem Ipsum"; | CODE |
| LOW | crates/text/src/tests.rs | 2905 | for text in ["a", "a\n", "a\n\n", "", "Lorem ipsum dolor sit amet"] { | CODE |
| LOW | crates/text/src/tests.rs | 2905 | for text in ["a", "a\n", "a\n\n", "", "Lorem ipsum dolor sit amet"] { | CODE |
| LOW | crates/engine/src/tests.rs | 1431 | let r = s.execute("type.create", json!({"x": 50, "y": 200, "text": "Lorem Ipsum", "size": 48, "coalesce": "k"})).unw | CODE |
| LOW | crates/engine/src/cmd/type_extra_cmds.rs | 2 | //! Convert to Shape, Rasterize, Warp Text, the OpenType toggles, Paste Lorem Ipsum, Update All | COMMENT |
| LOW⚡ | crates/engine/src/cmd/type_extra_cmds.rs | 23 | /// Photoshop's Paste Lorem Ipsum filler. | COMMENT |
| LOW⚡ | crates/engine/src/cmd/type_extra_cmds.rs | 24 | pub const LOREM_IPSUM: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt | CODE |
| LOW⚡ | crates/engine/src/cmd/type_extra_cmds.rs | 24 | pub const LOREM_IPSUM: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt | CODE |
| LOW | crates/engine/src/cmd/type_extra_cmds.rs | 542 | // ---------- lorem ipsum / update / fonts / defaults ---------- | COMMENT |
| LOW | crates/engine/src/cmd/type_extra_cmds.rs | 549 | let caret = with_text(s, p, "Paste Lorem Ipsum", |t, _| { | CODE |
| LOW | crates/engine/src/cmd/type_extra_cmds.rs | 811 | "Paste Lorem Ipsum", | CODE |
| LOW | crates/engine/src/cmd/web_cmds/tests.rs | 476 | (40, "mailto:hello@example.org"), | CODE |
| LOW | crates/engine/src/cmd/type_extra_cmds/tests.rs | 255 | assert!(text(&s, id).text.starts_with("Hi Lorem ipsum")); | CODE |
| LOW | crates/engine/src/cmd/type_extra_cmds/tests.rs | 421 | // #4188: Lock All stopped type.edit (#3132) but not Paste Lorem Ipsum into the layer. | COMMENT |
| LOW | crates/engine/src/cmd/type_cmds/tests.rs | 158 | let id = s.execute("type.create", json!({"x": 0, "y": 40, "text": "Lorem Ipsum", "coalesce": "k"})).unwrap()["layer" | CODE |
| LOW | crates/engine/src/cmd/type_cmds/tests.rs | 159 | assert_eq!(layer_name_of(&s, id), "Lorem Ipsum"); | CODE |
| LOW | docs/ui-design.md | 56 | | Type tool | `type_tool.rs` | Click: point text with the placeholder "Lorem Ipsum" selected. Drag: paragraph box. Inlin | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | crates/algo/src/segment/subject.rs | 95 | /// Step 5: GrabCut again with a background model that only knows the backdrop. A colour model | COMMENT |
| LOW⚡ | crates/ui-egui/src/dialogs/layer_style/tests.rs | 1068 | // Step 4: disable the stroke row — a pending edit, the document is untouched. | COMMENT |
| LOW⚡ | crates/ui-egui/src/dialogs/layer_style/tests.rs | 1070 | // Step 5: add a Color Overlay (a new instance: no fx snapshot, factory defaults). | COMMENT |
| LOW | crates/ui-egui/src/dialogs/layer_style/tests.rs | 1083 | // Step 6: untick Preview — the canvas shows the real document, whose stroke is | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | crates/algo/src/segment/subject.rs | 95 | /// Step 5: GrabCut again with a background model that only knows the backdrop. A colour model | COMMENT |
| LOW⚡ | crates/ui-egui/src/dialogs/layer_style/tests.rs | 1068 | // Step 4: disable the stroke row — a pending edit, the document is untouched. | COMMENT |
| LOW⚡ | crates/ui-egui/src/dialogs/layer_style/tests.rs | 1070 | // Step 5: add a Color Overlay (a new instance: no fx snapshot, factory defaults). | COMMENT |
| LOW | crates/ui-egui/src/dialogs/layer_style/tests.rs | 1083 | // Step 6: untick Preview — the canvas shows the real document, whose stroke is | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | crates/engine/src/cmd/smart_cmds.rs | 11 | //! ──transform (exact shift, or bicubic warp)──────► placed (document pixels) | COMMENT |
| MEDIUM | crates/engine/src/cmd/smart_cmds.rs | 13 | //! ──filter mask mix (unfiltered ↔ filtered)───────► cache | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | docs/architecture.md | 521 | kurbo = "*" # pin at scaffold time | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | packaging/linux/flatpak-oci.sh | 5 | # Usage: | COMMENT |