Repository navigation
Description
Objective. Expose the mask stack in the FireCraft shell as a CS6-shaped panel: one row per mask level, in stack order, with per-level enable, delete, combine mode, and selection coupling to the canvas.
Why. FireCraft's engine already carries mask commands (crates/engine/src/catalog/mask.rs) and mask plumbing in the document model (crates/doc/src/fwmap/reader.rs), but a user cannot see or manipulate a mask at all. A mask that exists only in the file format is not a feature: it is data the user cannot inspect, disable, reorder, or reason about. The shell is where FireCraft stops being a file-format library and becomes a daily-driver tool.
Current state. The stack model, its FWMap persistence, the compositor fold and the level panel are implemented on branch feat/mask-stack-ui-v2 and in flight as PR #113 (head 44b383a, merged with main and conflict-free). The merge is gated on the two CI receipts; it is not on main yet. The engine catalog exports element_mask_stack(document, id) -> Vec<MaskLevel>, and the shell panel is wired to the registry command surface.
Authority. docs/tasks/T9-mask-stack.md; decisions 0092 (wire contract) and 0093 (level model); the CS6 reference install's Properties panel mask section as the behavioural authority; docs/planning/generated/dom-parity.md for the command-bound count.
Work.
- The mask panel lists the document's masks in stack order, matching the CS6 mask panel's section.
- Per-mask controls: enable/disable, delete, and the combine mode (add / subtract / intersect / invert) with a preview of the mask shape.
- Selecting a mask in the panel selects the corresponding object on the canvas.
- Everything is exposed as registry commands, reachable from the menu tree and the command palette — no panel-local behaviour.
Acceptance.
- A document with two masks shows two rows; toggling a mask's enable flag changes the rendered output.
- The combine mode of a selected mask is editable and takes effect.
- No inert menu rows are added (the
inert_count_never_risestest caps them at 8). - The reachability floor does not regress (
docs/planning/generated/dom-parity.mdregenerated with no new unreachable share).
Verification. cargo run -p xtask -- ci green on the exact PR head; the mask stack's unit tests cover fold/unfold and FWMap round-trip; the workspace clippy and test suite pass.
Boundaries. The mask stack is a FireCraft extension — CS6 has one element mask per object and no stack at all. The stack's shape follows the modern raster editors (Photoshop layer masks, Affinity mask stacks): per-level operators over the coverage below. Do not present it as a CS6 parity feature.
Tracking. Task #143; PR #113.
Next action (owner: shell). Land PR #113 on the receipt of both CI gates, then take the follow-ups in #114 — the panel's screenshot acceptance against the CS6 Properties panel, and the compositor's mask sampling resolution.
Activity
aliasfoxkde commentedon Nov 10, 2026
Status: IN PROGRESS
Landed: not on
main. WIP branchfeat/mask-stack-ui(b9ec164) only; the engine-side mask commands already exist (crates/engine/src/mask.rsand the catalog mask commands).Still outstanding: no merged mask stack panel, so adding / removing / reordering / toggling / inverting a mask on an object is not reachable from the shell.
Next: land the panel with every action dispatching a registry command, and the two-masks stack/unstack acceptance test. Owner: app/shell owner.
aliasfoxkde commentedon Nov 11, 2026
Campaign fields (appended 2026-11-11)
Outcome — The CS6 mask stack is exposed in the FireCraft shell: the document's masks list in stack order, each mask's enable flag and combine mode are editable with a preview, and selecting a mask selects its object on canvas.
Objective — Build the mask panel over the engine's existing mask commands and the document's mask plumbing, with every action dispatched as a registry command so it is reachable from the menu tree and the command palette.
Stopping condition — A document with two masks shows two rows, toggling a mask's enable flag changes the rendered output, the combine mode of a selected mask is editable and takes effect, and no inert menu rows are added.
Verification — A two-masks stack/unstack test asserting the panel's rows and the enable/combine effects on the rendered output;
cargo test -p app inert_worklist -- --nocaptureshows the inert count still at or below 8.Status — IN PROGRESS
Tracking: task #143; the work is preserved on branch
feat/mask-stack-ui(mask combine-mode plumbing incrates/doc/src/fwmap/reader.rs), with no panel and no pull request yet.Defects: none recorded.
aliasfoxkde commentedon Nov 11, 2026
PR #113 (
feat(app,engine): the mask stack — model, persistence, …) is open and carries this work (currently conflict-dirty againstmainafter train #107). Leaving open until it lands.