docs: tidy agent, contributor and release docs

This commit is contained in:
aiongg
2026-10-31 04:17:45 +00:00
parent 8a87a457ab
commit 6d737c219e
37 changed files with 48 additions and 87 deletions
+5 -9
View File
@@ -1,6 +1,6 @@
# AGENTS.md: guide for AI agents and contributors
PhotoCraft is an open-source, native, Photoshop-comparable image editor written in **Rust only** (no JavaScript or TypeScript). **No Tauri, Electron or webview shells:** the desktop app is native egui/eframe on wgpu, and the web build is the same Rust compiled to WebAssembly (trunk + wasm-bindgen). Never add Tauri (or any webview/JS UI framework) as a dependency, build step or packaging target. The product name is always written **PhotoCraft** (`{Function}Craft` in PascalCase, like its siblings ArtCraft, ArtCraftX, DesignCraft, VectorCraft, EffectCraft, FilmCraft, LightCraft, PdfCraft) in user-facing text: UI, window titles, About, installers, release names, docs prose. Machine names stay lowercase: crates (`photocraft-*`), binaries, file names, ids (`ai.storyteller.photocraft`). Standards and learnings shared across the crafting apps live in `../craftrules` (read its `README.md`; the repository is not public — outside contributors should ask a maintainer for the standards relevant to their change). Contribute reusable learnings there; shared Rust components live in [storytold/craft-libs](https://github.com/storytold/craft-libs) and are pinned by immutable git revision. UI libraries stay at L6. The goal is 1:1 Photoshop parity (same menus, shortcuts, behaviour and file fidelity) with better performance, and every feature drivable by agents. Read this file first, then `docs/`.
PhotoCraft is an open-source, native, Photoshop-comparable image editor written in **Rust only** (no JavaScript or TypeScript). **No Tauri, Electron or webview shells:** the desktop app is native egui/eframe on wgpu, and the web build is the same Rust compiled to WebAssembly (trunk + wasm-bindgen). Never add Tauri (or any webview/JS UI framework) as a dependency, build step or packaging target. The product name is always written **PhotoCraft** (`{Function}Craft` in PascalCase, like its siblings ArtCraft, ArtCraftX, DesignCraft, VectorCraft, EffectCraft, FilmCraft, LightCraft, PdfCraft) in user-facing text: UI, window titles, About, installers, release names, docs prose. Machine names stay lowercase: crates (`photocraft-*`), binaries, file names, ids (`ai.storyteller.photocraft`). Shared Rust components live in [storytold/craft-libs](https://github.com/storytold/craft-libs) and are pinned by immutable git revision. UI libraries stay at L6. The goal is 1:1 Photoshop parity (same menus, shortcuts, behaviour and file fidelity) with better performance, and every feature drivable by agents. Read this file first, then `docs/`.
## 1. Orientation (5 minutes)
@@ -49,7 +49,7 @@ xtask/ cargo xtask layers | wasm | ci | stats | corpus | t
### Never crash (outranks feature work)
People trust PhotoCraft with their work, and a crash loses it. A malformed file, a bad command or MCP param, a corrupt settings file, an odd keystroke or a full disk must produce an error the user or agent can act on, never a panic. Don't ship a feature by adding a panic path; fix a crash before building on top of it. The shared standard is `../craftrules/standards/never-crash.md`.
People trust PhotoCraft with their work, and a crash loses it. A malformed file, a bad command or MCP param, a corrupt settings file, an odd keystroke or a full disk must produce an error the user or agent can act on, never a panic. Don't ship a feature by adding a panic path; fix a crash before building on top of it.
- **Non-test code never panics.** No `unwrap()`, `expect()`, `panic!`, `unreachable!`, `todo!` or `unimplemented!`. Return the crate's error type and propagate with `?`; use `ok_or(..)?`, `let .. else { return Err(..) }`, `if let`, or `unwrap_or*` where a fallback is truly correct (never one that silently corrupts a document). Unfinished features return an "unsupported" error. The only exception is a provably infallible literal: `#[allow(clippy::expect_used)]` plus `.expect("why it can't fail")`.
- **No `unsafe`.** The workspace sets `unsafe_code = "forbid"`. The one exception is the isolated helper crate `photocraft-tablet` (`crates/tablet`): winit drops pen tablet data, and reading it on macOS needs an AppKit event monitor (Objective-C interop) and on Windows a pointer message hook (`GetPointerPenInfo`). Only its `src/macos.rs` and `src/windows.rs` allow `unsafe` (`unsafe_code = "deny"` crate-wide, every block has a `SAFETY:` comment, tested against real `NSEvent`s and pointer messages); its X11 path and all mapping code are safe. Don't add `unsafe` anywhere else.
@@ -62,7 +62,7 @@ People trust PhotoCraft with their work, and a crash loses it. A malformed file,
1. **Everything is a command.** New user-visible behaviour = a command in the engine (`crates/engine/src/*_cmds.rs`, registered in `commands.rs`) with id, label, menu path, shortcut, params doc, `enabled` and `run`, plus tests. The UI, CLI, control channel and MCP all dispatch commands by id. Use the **exact id from `crates/ui-egui/src/menu_catalog.rs`** and the menu item goes live automatically. Only pure view/window state (zoom, panels, screen mode) belongs to the shell (`menus.rs` `UI_COMMANDS`).
2. **No format or colour assumptions.** Bit depth (8/16/32f) and colour model (RGB/Gray/CMYK/Lab…) are runtime data. Never introduce a `u8`-only pixel path in public APIs. Never assume sRGB: colour conversions go through `photocraft-cms` (`Transform`, `transform::cached`). Test at several depths.
3. **Clean-room.** We studied Photoshop and other proprietary editors for *behaviour and look only*. Never copy their code, shaders, profiles or assets. Implement from public specs (Adobe PSD spec, ICC, ISO 32000 blend modes, papers) and observation. Third-party assets must be permissively licensed, keep their license file next to them, and get a row in `ATTRIBUTION.md` (path, title, author, source, license) in the same change; so do original assets. The ArtCraft logos in `docs/brand/` are not open source (`docs/brand/LICENSE-brand.txt`). **Never commit font files:** fonts live in [storytold/craft-fonts](https://github.com/storytold/craft-fonts) (rules: `../craftrules/standards/fonts.md`). PhotoCraft uses it through the optional build input `CRAFT_FONTS_DIR=<craft-fonts checkout>` (read by `crates/text/build.rs`, exposed as `photocraft_text::CRAFT_FONTS`; empty without it, and everything must still work). Build with it: `CRAFT_FONTS_DIR="$PWD/../craft-fonts" cargo build`; details in `docs/development.md` › Fonts.
3. **Clean-room.** We studied Photoshop and other proprietary editors for *behaviour and look only*. Never copy their code, shaders, profiles or assets. Implement from public specs (Adobe PSD spec, ICC, ISO 32000 blend modes, papers) and observation. Third-party assets must be permissively licensed, keep their license file next to them, and get a row in `ATTRIBUTION.md` (path, title, author, source, license) in the same change; so do original assets. The ArtCraft logos in `docs/brand/` are not open source (`docs/brand/LICENSE-brand.txt`). **Never commit font files:** fonts live in [storytold/craft-fonts](https://github.com/storytold/craft-fonts). PhotoCraft uses it through the optional build input `CRAFT_FONTS_DIR=<craft-fonts checkout>` (read by `crates/text/build.rs`, exposed as `photocraft_text::CRAFT_FONTS`; empty without it, and everything must still work). Build with it: `CRAFT_FONTS_DIR="$PWD/../craft-fonts" cargo build`; details in `docs/development.md` › Fonts.
4. **Tests are the gate.** Every change comes with tests. Format crates use round-trip, synthetic-generator, oracle and fuzz tests. Keep the PSD corpus results and the parity floor (`crates/ui-egui/src/parity.rs`) from regressing.
5. **The UI is thin and data-driven.** UI state lives in `ui-egui/src/state.rs` (serde), so the control channel can read and drive it. Colours and radii come from `theme::Tokens`, never hard-coded.
6. **Verify UI changes visually.** Render offscreen with `cargo run -p photocraft-ui-egui --example snapshot` (no window, no focus stealing), or launch with `--control` and take `ui.screenshot`. Look at the PNG. Demo images must be public-domain art, never personal photos. When fetching assets, never put a person's name, email or other personal details in requests (User-Agent, headers, URLs); use a generic `Photocraft-dev` User-Agent.
@@ -80,7 +80,7 @@ Priorities: important infrastructure first, then low-hanging parity, then the lo
dimension, where PhotoCraft is lacking; `docs/gaps.md` ranks the work. `docs/parity-checklist.md`
(menu wiring) is not a measure of behaviour. When your work moves a number or closes a gap,
update the parity doc and gap entry it belongs to, with the date, and bump their status line
and revision history (craftrules `standards/progress-docs.md`).
and revision history.
1. **Check `docs/scorecard.md`** before picking work: each area's `missing` and `partial` rows,
the performance scenarios that are over budget or not measurable yet, and the count of
settings that do nothing. Its numbers are measured; prefer them to estimates.
@@ -130,7 +130,6 @@ Then append a terse entry to `log/devlog.md` (what landed, numbers, what's still
- `docs/parity-checklist.md`: generated Photoshop menu coverage.
- `docs/scorecard.md`: generated scorecard (sources: `scorecard/*.toml`, `perf/budgets.toml`, `perf/baseline.json`, corpus floors, prefs audit).
- `docs/releasing.md`: cutting a release (`cargo xtask version`, the `release` branch), signing secrets, packaging scripts in `packaging/`.
- `../craftrules/release/playbook.md`: how every storytold app builds signed release binaries (the canonical recipe; `docs/release-playbook.md` just points there); `docs/releasing.md` is PhotoCraft's specifics.
- `plan/` (local, gitignored): research, parity plan, execution plan, estimates.
- `log/` (local, gitignored): the dev log.
@@ -150,14 +149,11 @@ If the field has a PSD equivalent, map it in `crates/io` too, and keep unknown P
username has a `[people.<username>]` entry in `contributors/people.toml`. If not, ask them once
whether they want to be credited by more than their username: a real name, a display name, and/or
their public GitHub profile name (`sync_github_name = true`). If yes, add **only their own** entry
(copy the template at the top of the file, or run
`python3 ../../craftrules/scripts/contributors.py --add-me . --real-name "…" --sync-github-name`)
(copy the template at the top of the file)
and include it in their PR, committed as them. If no, change nothing: they are credited as
`@username` anyway.
- Never add, edit, guess or copy anyone else's entry or name (not from git config, commit authors or
GitHub profiles). Never hand-edit `contributors.json`.
- Maintainers refresh the stats with `python3 ../../craftrules/scripts/contributors.py .` (it also
re-verifies who wrote each `people.toml` entry; `--check` only verifies).
## CI workflows
- Workflows in `.github/workflows/` call the shared workflows in [`storytold/craft-common-actions`](https://github.com/storytold/craft-common-actions) at `@main`, with their inputs and secrets. No other jobs: if no shared workflow does what's needed, it doesn't go here.
+2 -2
View File
@@ -123,7 +123,7 @@ Detail and the next releases: [docs/roadmap.md](docs/roadmap.md).
| Date | Entry |
|---|---|
| 2026-10-17 | Object Finder classifies background by boundary coverage, retaining large enclosed foregrounds and rejecting surrounding backdrop (#6548); learned segmentation remains open (#2788) |
| 2026-10-10 | Full re-measure against Photoshop 2026 27.11.0 (installed bundle inspected): breadth ~76%, ready ~45%, alpha. Progress docs reorganized to the craftrules standard (`parity.md` → `parity-checklist.md`, `parity-estimate.md` merged into `target-app-parity.md`). 0.6.0 released. |
| 2026-10-10 | Full re-measure against Photoshop 2026 27.11.0 (installed bundle inspected): breadth ~76%, ready ~45%, alpha. Progress docs reorganized (`parity.md` → `parity-checklist.md`, `parity-estimate.md` merged into `target-app-parity.md`). 0.6.0 released. |
| 2026-10-09 | Remove tool, Rotate View, crop rotation; OpenRaster and Paint.NET; 39 Affinity documents in the corpus |
| 2026-10-08 | 0.5.0. Affinity import; Magnetic Lasso, Pattern Stamp, Mixer Brush, Pencil, Patch, Vertical Type on the toolbar |
| 2026-10-07 | 0.3.0. 10 UI languages; shortcut audit 214 → 0 failures; TIFF decode 10× faster |
@@ -143,4 +143,4 @@ Detail and the next releases: [docs/roadmap.md](docs/roadmap.md).
| 2026-10-10 | minor | Readiness by audience with hours per tier |
| 2026-10-10 | minor | Mainstream-practitioner and essentials-user numbers added |
| 2026-10-10 | minor | Alpha gate result (passes; stays alpha) in the stage explanation |
| 2026-10-10 | major | First version, per craftrules `standards/progress-docs.md` |
| 2026-10-10 | major | First version |
+1 -2
View File
@@ -23,8 +23,7 @@ as the other Crafting Apps do.
## Provenance
The owner's original drawing, made in ArtCraft (2880 px, engraving style, keyed to the palette),
vectorised with craftrules `assets/logo-options/_tools/vectorize_tile.py`. The source PNG stays in
craftrules at `assets/app-icons/photocraft/source.png`. License: see `LICENSE.txt`.
vectorised. License: see `LICENSE.txt`.
## Files
+2 -5
View File
@@ -1,13 +1,10 @@
# Contributor names for the About window (craftrules standards/contributors.md).
# Contributor names for the About window.
#
# Everyone who contributes is credited by GitHub username automatically. Anything more is up to
# you: add YOUR OWN entry below, in your own PR (commit it yourself). Never add someone else; a
# maintainer may add a person only when that person asked, recording where in consent_source.
#
# Easiest: python3 ../../craftrules/scripts/contributors.py --add-me . \
# [--real-name "Ada Lovelace"] [--display-name "Ada"] [--sync-github-name]
#
# Or copy this block, replacing your-github-username (every field is optional):
# Copy this block, replacing your-github-username (every field is optional):
#
# [people.your-github-username]
# real_name = "Your Name" # shown when the viewer picks "Real name"
+1 -1
View File
@@ -5,7 +5,7 @@ edition.workspace = true
license.workspace = true
description = "Pen tablet pressure, tilt, rotation and eraser end on macOS (AppKit) and Linux X11 (XInput2), and barrel button on Windows"
# The one isolated `unsafe` helper crate (craftrules never-crash, AGENTS.md): the AppKit event
# The one isolated `unsafe` helper crate (see AGENTS.md, Never crash): the AppKit event
# monitor on macOS and the WH_GETMESSAGE pointer hook on Windows need platform interop. Only
# `src/macos.rs` and `src/windows.rs` allow `unsafe`; everything else is denied, and every other
# crate keeps the workspace's `unsafe_code = "forbid"`.
+1 -1
View File
@@ -9,7 +9,7 @@
//! messages on the UI thread's message queue to read `PEN_FLAG_BARREL` (`GetPointerPenInfo`),
//! which winit 0.30 drops by mapping pen inputs to touch events.
//! AppKit's monitor API and Windows' thread hook need OS interop, so `macos.rs` and `windows.rs`
//! allow `unsafe` (craftrules never-crash: an isolated, tested helper crate with `SAFETY:`
//! allow `unsafe` (an isolated, tested helper crate with `SAFETY:`
//! comments on every block).
//! - **Linux X11** ([`x11::spawn`]): a second, pure-Rust X connection (x11rb) selects XInput2
//! raw events on the root window and maps the tablet device's valuators ("Abs Pressure",
+1 -1
View File
@@ -1,5 +1,5 @@
//! Optional craft-fonts build input (https://github.com/storytold/craft-fonts, recipe from its
//! `docs/integration.md`; rules in `craftrules/standards/fonts.md`).
//! `docs/integration.md`).
//!
//! With `CRAFT_FONTS_DIR=<craft-fonts checkout>`, every font in its `fonts/manifest.txt` is
//! embedded and exposed as `photocraft_text::CRAFT_FONTS`; unset, `CRAFT_FONTS` is empty and the
+3 -4
View File
@@ -1,8 +1,7 @@
//! Bake the contributor credits into the binary as static Rust tables (craftrules
//! standards/contributors.md). Nothing is read at run time.
//! Bake the contributor credits into the binary as static Rust tables. Nothing is read at run time.
//!
//! - contributors/contributors.json: commit stats per GitHub username, generated by craftrules
//! scripts/contributors.py, which also marks whose people.toml entry it verified.
//! - contributors/contributors.json: commit stats per GitHub username, with a mark for whose people.toml
//! entry is verified.
//! - contributors/people.toml: the names people chose for themselves. A name is used only when the
//! JSON says the entry was verified (`people_entry`).
//!
+1 -1
View File
@@ -362,7 +362,7 @@ fn dialog_body(app: &mut PhotocraftApp, ui: &mut egui::Ui, d: &Dialog, fields: &
}
}
DialogKind::About => {
// Tabs About · Contributors · Models (craftrules standards/contributors.md). The
// Tabs About · Contributors · Models. The
// tab is a dialog field, so automation can switch it with `ui.dialog.set`.
let tab = about_tab(fields);
let mut chosen = tab;
+1 -1
View File
@@ -1,6 +1,6 @@
//! The About window's credits: every contributor (GitHub login always; display and real names only
//! with recorded consent) and the AI models that helped. The tables are baked into the binary by
//! build.rs from contributors/contributors.json (craftrules standards/contributors.md); nothing is
//! build.rs from contributors/contributors.json; nothing is
//! read at run time. UI strings go through `tl!` (column abbreviations like `+LOC` stay as they are).
use std::cmp::Ordering;
+1 -1
View File
@@ -2416,7 +2416,7 @@
Frequency التردد
Use tablet pressure to change pen width استخدام ضغط الجهاز اللوحي لتغيير عرض القلم
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
About حول
Contributors المساهمون
Models النماذج
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -56,7 +56,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -2629,7 +2629,7 @@ cameraRaw Roughness Ruhed
Frequency Frekvens
Use tablet pressure to change pen width Brug tablettryk til at ændre penbredden
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
About Om
Contributors Bidragydere
Models Modeller
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -32,7 +32,7 @@
# Layer Style dialog: style presets and per-effect defaults
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -30,7 +30,7 @@
# Command-id override: under Edit > Purge a bare "Deshacer" reads as an action, not the history.
# Rendering mode and recovery
# Camera Raw: contextual controls and window title
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
# Shared screen eyedropper and text Color Picker (#1128).
Can't render this file because it contains an unexpected character in line 4 and column 47.
+1 -1
View File
@@ -2630,7 +2630,7 @@ cameraRaw Roughness Karheus
Frequency Taajuus
Use tablet pressure to change pen width Muuta kynän leveyttä piirtopöydän paineella
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
About Tietoja
Contributors Tekijät
Models Mallit
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -47,7 +47,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -38,7 +38,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 4 and column 47.
+1 -1
View File
@@ -54,7 +54,7 @@
# Strings added on main after this catalog was written (2026-10).
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Layer Style > Blending Options (Advanced Blending)
# Swatches panel
Can't render this file because it contains an unexpected character in line 79 and column 53.
+1 -1
View File
@@ -49,7 +49,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -38,7 +38,7 @@
# Additional generated filter labels and Photoshop-aligned UI terminology.
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 63 and column 53.
+1 -1
View File
@@ -2629,7 +2629,7 @@ cameraRaw Roughness Ruhet
Frequency Frekvens
Use tablet pressure to change pen width Bruk trykk fra tegnebrett til å endre pennbredden
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
About Om
Contributors Bidragsytere
Models Modeller
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -32,7 +32,7 @@
# Layer Style dialog: style presets and per-effect defaults
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -132,7 +132,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -41,7 +41,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -2627,7 +2627,7 @@ cameraRaw Roughness Grovhet
Frequency Frekvens
Use tablet pressure to change pen width Använd tryckkänslighet på ritplattan för att ändra pennans bredd
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
About Om
Contributors Medverkande
Models Modeller
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -123,7 +123,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 152 and column 53.
+1 -1
View File
@@ -37,7 +37,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 63 and column 53.
+1 -1
View File
@@ -41,7 +41,7 @@
# About ▸ Contributors / Models (credits, craftrules standards/contributors.md)
# About ▸ Contributors / Models (credits)
# Swatches panel
# Layer Style > Blending Options (Advanced Blending)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1 -1
View File
@@ -2,7 +2,7 @@
- **Language:** Rust only. No JavaScript or TypeScript. On the web, `wasm-bindgen` generates a small loader; never hand-write JS.
- **Licence:** contributions are MIT OR Apache-2.0 (`LICENSE-MIT`, `LICENSE-APACHE`, `NOTICE`). The ArtCraft logos in `docs/brand/` are not open source (`docs/brand/LICENSE-brand.txt`).
- **Clean-room:** do not copy code, shaders, icons, ICC profiles or other assets from proprietary software (such as Photoshop). Match behaviour and look by observation and public specs. Only use assets with permissive licences, keep their license next to the asset (e.g. `assets/fonts/OFL-*.txt`, `assets/icons/LICENSE-lucide.txt`), and list every asset in `ATTRIBUTION.md`. **Fonts** live in [storytold/craft-fonts](https://github.com/storytold/craft-fonts), never in this repo: add new fonts there, and build with them through the optional `CRAFT_FONTS_DIR` build input (`docs/development.md` › Fonts; rules in `../craftrules/standards/fonts.md`, a sibling checkout — `storytold/craftrules` is not public, so ask a maintainer for the rules relevant to your change).
- **Clean-room:** do not copy code, shaders, icons, ICC profiles or other assets from proprietary software (such as Photoshop). Match behaviour and look by observation and public specs. Only use assets with permissive licences, keep their license next to the asset (e.g. `assets/fonts/OFL-*.txt`, `assets/icons/LICENSE-lucide.txt`), and list every asset in `ATTRIBUTION.md`. **Fonts** live in [storytold/craft-fonts](https://github.com/storytold/craft-fonts), never in this repo: add new fonts there, and build with them through the optional `CRAFT_FONTS_DIR` build input (`docs/development.md` › Fonts).
- **Never crash:** non-test code must not panic: no `unwrap`/`expect`/`panic!`/`unreachable!`/`todo!`/`unimplemented!` and no `unsafe`. Errors go through `Result` and `?`, input-derived indices and sizes are checked, and every crash fix ships with a regression test. See *Never crash* in `AGENTS.md`.
- **Commands, not handlers:** new features are engine commands with tests, and the UI calls them (checklist below).
- **Layering:** `cargo xtask layers` must pass. Register new crates in `xtask/src/layers.rs`.
+4 -21
View File
@@ -1,16 +1,14 @@
# Contributors in the About window
**About ▸ Contributors** credits everyone who contributed to PhotoCraft, and **About ▸ Models** credits
the AI models named in `Co-Authored-By` trailers. This follows the shared craftrules standard
[`standards/contributors.md`](https://github.com/storytold/craftrules/blob/main/standards/contributors.md);
this page is the local copy of the decision.
the AI models named in `Co-Authored-By` trailers.
## Decision
- Two files, both **compiled into the binary** by the UI crate's `build.rs` (nothing is read from
disk or the network at run time; the web build has them too):
- [`contributors/contributors.json`](../contributors/contributors.json): commit stats per GitHub
username. **Generated** by `craftrules/scripts/contributors.py`; never hand-edit.
username.
- [`contributors/people.toml`](../contributors/people.toml): the names people chose for
themselves. **Each contributor adds only their own entry**, in their own PR.
- Each contributor gets one line: GitHub username (always), display name (opt-in, or their synced
@@ -38,20 +36,5 @@ display_name = "Nickname"
sync_github_name = true # use the name on your public GitHub profile as display name
```
or, with craftrules checked out next to `craft-apps/`:
```sh
python3 ../../craftrules/scripts/contributors.py --add-me . --real-name "Your Name" --sync-github-name
```
Names show after the next refresh: the script checks that each entry was committed by its own
user (or by a maintainer with a `consent_source`). Delete your entry to remove your names.
## Refreshing (maintainers)
```sh
python3 ../../craftrules/scripts/contributors.py . # regenerate + verify; needs git, Python 3.11+, gh
python3 ../../craftrules/scripts/contributors.py --check . # verify people.toml only
```
Commit the updated `contributors/contributors.json`. Git author names and emails are never recorded.
Names show for entries committed by their own user (or by a maintainer with a `consent_source`).
Delete your entry to remove your names. Git author names and emails are never recorded.
+1 -1
View File
@@ -113,7 +113,7 @@ Rust test and variable work on Windows with the native shell's environment-varia
## Fonts (craft-fonts)
Font assets shared by the Crafting Apps live in [storytold/craft-fonts](https://github.com/storytold/craft-fonts), never in this repo: don't commit font files here (Inter and JetBrains Mono in `assets/fonts/` are the only exceptions; new fonts go to craft-fonts). The rules are in `craftrules/standards/fonts.md` in a sibling `craftrules` checkout (see below); that repository is not public, so outside contributors can ask a maintainer for the rules that apply to their change.
Font assets shared by the Crafting Apps live in [storytold/craft-fonts](https://github.com/storytold/craft-fonts), never in this repo: don't commit font files here (Inter and JetBrains Mono in `assets/fonts/` are the only exceptions; new fonts go to craft-fonts).
craft-fonts is an **optional build input**, never a Cargo dependency:
+1 -2
View File
@@ -241,7 +241,6 @@ remain the performance evidence used to retain the change.
Native Iris GUI frame/slider latency, ARM/macOS/Linux performance and wasm runtime
speed were not measured. Compilation confirms wasm compatibility only. Photoshop
equivalence beyond the base implementation's semantics is not asserted. The private
shared craftrules checkout was unavailable at the supplied locations; repository
equivalence beyond the base implementation's semantics is not asserted. Repository
AGENTS.md and architecture/development/contributing/control/performance rules were
followed. Existing source allocation and per-tile cancellation limits are retained.
-8
View File
@@ -1,8 +0,0 @@
# Release playbook
The release playbook shared by every crafting app lives in craftrules:
[`../craftrules/release/playbook.md`](../../craftrules/release/playbook.md)
(`storytold/craftrules`, a sibling checkout; the repository is not public). It is the canonical copy; don't duplicate it here.
PhotoCraft is its reference implementation (`.github/workflows/release.yml`, `packaging/`,
`cargo xtask version`). PhotoCraft-specific details are in [releasing.md](releasing.md).
+2 -4
View File
@@ -5,9 +5,7 @@ signed installers for macOS, Windows, Linux and the web, plus a FreeBSD tarball,
or updates a **draft** GitHub Release named `PhotoCraft v<version>`. Nobody sees a draft until a
maintainer publishes it.
This is PhotoCraft's implementation of the shared
[release playbook](release-playbook.md). User-facing names say **PhotoCraft**. Files, binaries
and ids stay lowercase (`photocraft-<version>-<platform>-<arch>.<ext>`, `ai.storyteller.photocraft`).
User-facing names say **PhotoCraft**. Files, binaries and ids stay lowercase (`photocraft-<version>-<platform>-<arch>.<ext>`, `ai.storyteller.photocraft`).
## In-app update checks
@@ -84,7 +82,7 @@ at the `craft-fonts-ref` commit in `.github/workflows/release.yml` and builds wi
`docs/development.md` › Fonts) and fail rather than ship without them. The packages carry each font's licence as
`OFL-<family>.txt` (`copy_font_licences` in `packaging/env.sh`; the portable zip on Windows;
`Contents/Resources/Licenses` in the macOS app). Bump the pin deliberately, together with the one
in `ci.yml`. Rules: `../craftrules/standards/fonts.md`; build option: `docs/development.md` › Fonts.
in `ci.yml`. Build option: `docs/development.md` › Fonts.
### macOS
+1 -2
View File
@@ -90,8 +90,7 @@ Weights reflect what a working Photoshop user depends on (photographers, retouch
## Mainstream practitioner: ~43%
The same question for the typical professional Photoshop user (photographer, retoucher,
designer), not the whole product. Method: craftrules `standards/progress-docs.md`. Areas a
professional uses weekly (the [alpha-gate](roadmap.md#alpha-gate) workflows plus their everyday
designer), not the whole product. Areas a professional uses weekly (the [alpha-gate](roadmap.md#alpha-gate) workflows plus their everyday
tools), depth from the [feature areas](#feature-areas) table. Left out: AI, plug-ins and
scripting, Libraries/cloud, video, specialist hardware (tilt, Touch Bar), languages.
+1 -2
View File
@@ -250,6 +250,5 @@ The measurements establish equivalence to the starting PhotoCraft kernel, not a
new Photoshop oracle or broader parity increase. Cold startup, actual GUI
input/frame latency, allocation counts and other platforms' native performance
remain unmeasured. No performance budget, scorecard checklist or parity floor is
raised from these local results. The shared craftrules checkout was unavailable
at the documented paths; the repository's own contributor and validation rules
raised from these local results. The repository's own contributor and validation rules
were followed.