From 09cd6f64c835f9df5ecd2321a3d96bb1070b5362 Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Wed, 11 Nov 2026 09:29:43 -0600 Subject: [PATCH 01/37] docs(ledger): reconcile TASKS.md against the landed trains Reconcile the live ledger against main at 658f015 (2026-11-11): the shell-lineage (#107) and release-engineering (#108) trains landed. Phase 20.5-20.7 and all of Phase 21 shipped with them, so those queue rows close; the web-deployment reconciliation (#104), the menu census (2 inert of 296), and the Phase 22 landing notes are updated; the stray hash line at the file end and the stale 5fac7a2 reconciliation header go away. T22's ticket loses its 'current PR branch' wording in the same change. Co-Authored-By: Claude Code --- docs/TASKS.md | 52 +++++++++++++-------------------- docs/tasks/T22-screenshot-ui.md | 2 +- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/docs/TASKS.md b/docs/TASKS.md index 58ee9a0..e34a761 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -1,13 +1,11 @@ # FireCraft — Live task board -> **Live ledger.** Reconciled on the PR #8 working branch (2026-11-07; merged -> with `main` on 2026-11-10) against `main` at `5fac7a2`. Changes remain -> unmerged until PR approval. Use [`NEXT.md`](NEXT.md) for phase detail and -> [`tasks/`](tasks/) for task tickets. Historical plans and session notes are -> not current status sources. - +> **Live ledger.** Reconciled against `main` at `658f015` on 2026-11-11, +> after the shell-lineage train (#107) and the release-engineering train +> (#108, merged into the train as `1884c04`) landed. Use [`NEXT.md`](NEXT.md) +> for phase detail and [`tasks/`](tasks/) for task tickets. Historical plans +> and session notes are not current status sources. > - > Working document (not a historical record). Canonical planning: > [`PLANNING.md`](PLANNING.md) + [`planning/firecraft/ROADMAP.md`](planning/firecraft/ROADMAP.md). > Per-task tickets: [`tasks/`](tasks/) (one file per task, same @@ -44,10 +42,10 @@ | Priority | Task | Status | Detail | |---|---|---|---| | P0 | Refresh user-visible CS6 parity matrix | **Done — matrix published** | [T26](tasks/T26-parity-matrix.md) → [`CS6-PARITY.md`](CS6-PARITY.md): every CS6 menu, tool, panel, inspector field set, workflow, import/export surface, canvas interaction, keymap area, and selection state classified with an evidence citation and an owning ticket. The browser-sampling check the ticket named was performed on 2026-11-04 against a fresh optimized bundle and is recorded in T22. | -| P0 | Phase 22: CS6 shell fidelity and screenshot audit | In progress | [T22](tasks/T22-screenshot-ui.md) — screenshot acceptance is complete; 22.1 panel inventory and 22.2 tool strip are complete in PR #8; 22.5 chrome remains partial, and 22.4 still has evidence-gated bitmap transform/fill-stroke work. [Phase 22](NEXT.md#phase-22--cs6-shell-fidelity-p0-the-looks-and-acts-like-fireworks-phase) | -| P1 | Phase 20: daily-driver editing features | **In progress — 20.1 landed** | In-canvas text editing landed 2026-11-06 ([T20](tasks/T20-text-editing.md)); remaining: Optimize, animation timeline, mask stack, tabs, history rewind, slice behavior; [details](NEXT.md#phase-20--daily-driver-features-p1) | -| P1 | Phase 21: modern differentiators | Queued | Autosave, HiDPI, palette, preferences, accessibility, scripting; [details](NEXT.md#phase-21--modern-differentiators) | -| P1 | Reconcile live web deployment | Artifact differs | The public manifest's JS/wasm/index hashes differ from local `dist/web`; identify intended deploy and verify it before publishing. See [T18](tasks/T18-release.md). | +| P0 | Phase 22: CS6 shell fidelity and screenshot audit | In progress | [T22](tasks/T22-screenshot-ui.md) — screenshot acceptance is complete; 22.1 panel inventory and 22.2 tool strip landed on `main` with the shell-lineage train (#107); 22.5 chrome remains partial, and 22.4 still has evidence-gated bitmap transform/fill-stroke work. [Phase 22](NEXT.md#phase-22--cs6-shell-fidelity-p0-the-looks-and-acts-like-fireworks-phase) | +| P1 | Phase 20: daily-driver editing features | **In progress — 20.1, 20.5–20.7 landed** | In-canvas text editing landed 2026-11-06 ([T20](tasks/T20-text-editing.md)); multi-document tabs (20.5), history-panel rewind (20.6) and slice/hotspot behavior editing with HTML preview (20.7) landed 2026-11-11 with the shell-lineage train (#107). Remaining: Optimize ([T7](tasks/T7-optimize-panel.md)), animation timeline ([T8](tasks/T8-animation-timeline.md); compose-side onion skin landed as #100), mask stack (PR #113 in flight); [details](NEXT.md#phase-20--daily-driver-features-p1) | +| P1 | Phase 21: modern differentiators | **Done — all items landed 2026-11-11** | Autosave/crash recovery, HiDPI, command palette v2 (fuzzy scoring, recents, Save Steps As Command), preferences, accesskit accessibility and in-app scripting (`.jsf`/`.fwsteps`) all landed with the shell-lineage train (#107, PR #15); [details](NEXT.md#phase-21--modern-differentiators) | +| P1 | Reconcile live web deployment | **Reconciled — republish pending** | #104 (`docs/web-deployment-reconciliation`) reconciled the live site against v0.2.5: the JS, wasm and `appinfo` match; `host.html`/`index.html` fail the site's own manifest because Cloudflare injects an analytics beacon after it is written. Decision recorded there: the release bytes are the source of truth. Next: republish from the release artifact. See [T18](tasks/T18-release.md). | | P2 | Next-release asset breadth and platform verification | Open | [T23](tasks/T23-release-assets.md); recipes exist, but non-Linux artifacts need real platform build/launch receipts. | | P2 | Coverage and test quality ratchet | Open | Replace the old aspirational 99% label with measured per-crate targets and snapshots; [NEXT.md](NEXT.md). | | P2 | Aegis gate: content-keyed baseline, so a doc edit no longer fails the gate | **Done — landed on `main`** | [decisions/0074-aegis-content-keyed-baseline.md](decisions/0074-aegis-content-keyed-baseline.md). The baseline keys on content (pattern, file, digest) rather than on line, and every rule class stays armed. | @@ -57,11 +55,11 @@ | # | Task | Ticket | Status | Owner | Next action | |---|---|---|---|---|---| -| 5 | 19.6 inert-menu burn-down — Modify/File families (83 of 289; batch 8 = Attach to Path landed 2026-11-03) | [tasks/T5-inert-burndown.md](tasks/T5-inert-burndown.md) | `IN PROGRESS` | UI/verb lane | continue the per-family burn-down; each batch carries its own evidence gate. This branch's newer census has batches 1–17 landed with 2 inert rows of 294, derived by `menus::tests::inert_count_never_rises` | +| 5 | 19.6 inert-menu burn-down — Modify/File families (83 of 289; batch 8 = Attach to Path landed 2026-11-03) | [tasks/T5-inert-burndown.md](tasks/T5-inert-burndown.md) | `IN PROGRESS` | UI/verb lane | continue the per-family burn-down; each batch carries its own evidence gate. The current census: batches 1–17 landed with 2 inert rows of 296 (the pinned total, `menus::tests::menu_item_total_is_pinned`), derived by `menus::tests::inert_count_never_rises` (ceiling 2) | | 194 | Aegis gate: content-keyed baseline, so a doc edit no longer fails the gate (decision 0074) | [decisions/0074-aegis-content-keyed-baseline.md](decisions/0074-aegis-content-keyed-baseline.md) | `IMPLEMENTED` — the content-keyed gate and its decision record are in the tree; the gate has been exercised on this branch's tree | CI/tooling lane | **landed in `main` (#18)** and merged here; attach a run id before claiming the fleet-wide state | | 27 | Cross-platform release engineering: Windows, macOS, Linux package matrix, Android feasibility, source, SBOM/provenance, signing, CI aggregation and certification | [tasks/T27-cross-platform-release.md](tasks/T27-cross-platform-release.md) | `IN PROGRESS` — implementation is ahead of verification; **no target is `CERTIFIED`** and nothing is signed | release-workflow lane | land an end-to-end tag run of the repaired workflow and attach the run id as the RP-07 receipt; consolidate the duplicated `dist --source`/`--sbom` verbs (B-3) | | 26 | Refresh user-visible CS6 parity matrix | [tasks/T26-parity-matrix.md](tasks/T26-parity-matrix.md) | `IMPLEMENTED` — matrix published | parity lane | every CS6 menu, tool, panel, inspector field set, workflow, import/export surface, canvas interaction, keymap area, and selection state is classified with an evidence citation and an owning ticket in [`CS6-PARITY.md`](CS6-PARITY.md); the browser-sampling check the ticket named was performed on 2026-11-04 against a fresh optimized bundle and is recorded in T22 | -| 22 | Phase 22: CS6 shell fidelity and screenshot audit | [tasks/T22-screenshot-ui.md](tasks/T22-screenshot-ui.md) | `IN PROGRESS` | UI lane | screenshot acceptance is complete; 22.1 panel inventory and 22.2 tool strip are complete in PR #8; 22.5 chrome remains partial, and 22.4 still has evidence-gated bitmap transform/fill-stroke work. [Phase 22](NEXT.md#phase-22--cs6-shell-fidelity-p0-the-looks-and-acts-like-fireworks-phase) | +| 22 | Phase 22: CS6 shell fidelity and screenshot audit | [tasks/T22-screenshot-ui.md](tasks/T22-screenshot-ui.md) | `IN PROGRESS` | UI lane | screenshot acceptance is complete; 22.1 panel inventory and 22.2 tool strip landed on `main` with the shell-lineage train (#107); 22.5 chrome remains partial, and 22.4 still has evidence-gated bitmap transform/fill-stroke work. [Phase 22](NEXT.md#phase-22--cs6-shell-fidelity-p0-the-looks-and-acts-like-fireworks-phase) | | 20 | 20.1 In-canvas text editing (egui TextEdit overlay; kittest focus tests) | [tasks/T20-text-editing.md](tasks/T20-text-editing.md) | `IMPLEMENTED` — landed 2026-11-06 (`shell::begin_text_edit` / `text_edit_overlay`) | editing lane | the remaining Phase 20 items (Optimize, animation timeline, mask stack, tabs, history rewind, slice behavior) stay queued below | @@ -73,23 +71,16 @@ | 20 | 20.1 In-canvas text editing (egui TextEdit overlay; kittest focus tests) | [tasks/T20-text-editing.md](tasks/T20-text-editing.md) | | 7 | 20.2 Optimize panel (palette/bitrate over `ExportOptions` + live preview) | [tasks/T7-optimize-panel.md](tasks/T7-optimize-panel.md) | | 8 | 20.3 Animation timeline (frames strip, timing, onion skinning, `symbol.tween`) | [tasks/T8-animation-timeline.md](tasks/T8-animation-timeline.md) | -| — | 20.4 Mask stack UI (add/remove/mode/link/move) | — | -| 9 | 20.5 Multi-document tabs + Window-menu panel toggles | — | -| 10 | 20.6 History panel click-to-rewind (journal replay to seq N) | — | -| 11 | 20.7 Slice/hotspot behavior editing + HTML preview | — (landed on `feat/slice-hotspot-edit`, PR #13 — not yet on `main`) | +| — | 20.4 Mask stack UI (add/remove/mode/link/move) | PR #113 (in flight) | ## Queued (Phase 21 — modern differentiators) - - -| # | Task | Ticket | -|---|---|---| -| 12 | 21.1 Autosave + crash recovery (journal snapshot sidecar; restore prompt) | — | -| 13 | 21.2 HiDPI `pixels_per_point` + render-stamp→dirty-counter migration | — | -| 14 | 21.3 Command palette v2 (fuzzy scoring, recents, save-steps-as-command) | — | -| 15 | 21.4 Preferences dialog + platform-storage persistence (0067 follow-up) | — | -| 16 | 21.5 accesskit desktop + web re-audit (0067 records the web blocker) | — | -| 17 | 21.6 In-app scripting (`.jsf`/`.fwsteps` from the Commands menu) | — | +**All Phase 21 items landed 2026-11-11** with the shell-lineage train +(#107, PR #15): autosave/crash recovery, HiDPI, command palette v2 +(fuzzy scoring, recents, Save Steps As Command), preferences, accesskit +accessibility, and in-app scripting (`.jsf` and `.fwsteps` from the +Commands menu). Scope detail stays in +[NEXT.md](NEXT.md#phase-21--modern-differentiators). ## Queued (release + quality) @@ -131,7 +122,7 @@ progress: ## Phase 22 detail -| Item | State at `5fac7a2` | Remaining evidence/work | +| Item | State at `658f015` (reconciled 2026-11-11) | Remaining evidence/work | |---|---|---| | 22.1 Panel inventory and docking | Complete | The right dock is a resizable, scrolling column of stacked panels in CS6's order (`crates/app/src/shell/panel_windows.rs`: 18-panel inventory, collapse/close headers, scroll keeps every panel reachable at any viewport height). All surfaces dispatch, including the previously-missing Optimize, Slices, CSS Properties, Find and Replace, and Common Library panels (landed 2026-11-06). Common Library lists the document's own symbols — CS6's shipped libraries are proprietary resources and are not copied. | | 22.2 Tool strip and flyouts | Complete | The strip is CS6's, as data in `crates/app/src/toolstrip.rs`: six categories in CS6's order, twenty-four groups with their one-key shortcuts, the flyout memberships, and CS6's group-cycling rule. Evidence in [`research/fw-ui-evidence.md`](research/fw-ui-evidence.md); landed 2026-11-05. | @@ -146,7 +137,7 @@ progress: | Task | Evidence | |---|---| | 19.1–19.5 canvas competence | Transform handles, path nodes, gradient editor, command palette, guides/grid/snap; [NEXT.md](NEXT.md). | -| 19.6 menu wiring campaign | Batches 1–17 landed; current census is 2 inert rows of 294, derived and gated by `menus::tests::inert_count_never_rises`. Remaining rows are feature work or evidence-gated, not an active burn-down. | +| 19.6 menu wiring campaign | Batches 1–17 landed; current census is 2 inert rows of 296 (pinned total `menus::tests::menu_item_total_is_pinned`, ceiling `menus::tests::inert_count_never_rises`). Remaining rows are feature work or evidence-gated, not an active burn-down. | | 19b path nodes and wasm budget | Path node add/delete and dated wasm ceiling re-pin recorded in [Progress](PROGRESS.md). | | v0.2.5 release tag | `v0.2.5` exists; see [release notes](releases/v0.2.5.md). The live deployment uses a different manifest from the current local distribution. | @@ -165,6 +156,7 @@ progress: | Aegis gate is content-keyed on this branch — a finding's identity is `(pattern, file, content digest)` rather than Aegis's line-keyed fingerprint, so a prose edit that moves a documented false positive no longer fails the gate. No rule class is switched off; each class's rows carry the reason they were adjudicated ([decision 0074](decisions/0074-aegis-content-keyed-baseline.md)) | 2026-11-09 | | Host fork-bomb from a throwaway `/proc/self/exe` probe — ~5800 processes at load 2057 starved the GitForge runner's sandbox; terminated by per-PID cmdline+exe verification and the probe directory moved aside | 2026-11-09 | | Task-board tracking scaffold — `docs/TASKS.md` plus the `docs/tasks/` per-task ticket set (one file per task, same objective/inputs/authority/stopping-condition/verification shape as the milestone tickets). The scaffold is this board and the `docs/tasks/` directory; the row it carried in the queued table is closed by this reconciliation | 2026-11-09 | +| Shell-lineage and release-engineering trains merged — #107 squash `658f015` carrying #8, #13, #15, #41, #83, #84, #100, #102, #103 and (via #108 → `1884c04`) #85, #101, #104, #105, #106; the 14 constituent PRs were closed as merged-by-train, and Phase 20.5–20.7 plus all of Phase 21 shipped in the same landing | 2026-11-11 | ## Blocked or evidence-gated @@ -179,5 +171,3 @@ progress: - Update this file and the ticket when work starts, changes scope, or lands. - Keep detailed implementation history in [`SESSIONS.md`](SESSIONS.md); keep host/tooling diagnostics out of the FireCraft session history. - Do not copy a second active task list into the handoff or historical audit documents. - -d1699c053ec52ee9585cb2294242bdd779787503 diff --git a/docs/tasks/T22-screenshot-ui.md b/docs/tasks/T22-screenshot-ui.md index 23a1e15..492c98b 100644 --- a/docs/tasks/T22-screenshot-ui.md +++ b/docs/tasks/T22-screenshot-ui.md @@ -1,6 +1,6 @@ # T22 — Screenshot-driven shell and responsive UI audit -**Status:** screenshot audit complete. The tracked screenshot (`docs/img/app-main.png`), 1920×1080 capture, and empty/vector/bitmap state set are recorded below. Panel inventory (22.1) and tool strip (22.2) are complete in the current PR branch; the remaining Phase 22 work is the separate CS6 chrome audit (22.5). +**Status:** screenshot audit complete. The tracked screenshot (`docs/img/app-main.png`), 1920×1080 capture, and empty/vector/bitmap state set are recorded below. Panel inventory (22.1) and tool strip (22.2) landed on `main` with the shell-lineage train (#107) on 2026-11-11; the remaining Phase 22 work is the separate CS6 chrome audit (22.5). **Objective:** align the editor's working shell with the clean-room CS6 reference notes while keeping controls visible and usable at ordinary browser sizes. From 5900f420d199e3f3c985b05277f732798a483a3a Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Wed, 11 Nov 2026 11:28:14 -0600 Subject: [PATCH 02/37] docs: repair the stale command-count and menu-census numbers The post-train tree's gated truth is 253 registered commands (xtask reachability: 164 bound = 64.82%) and 2 inert of 296 (menu_item_total_is_pinned / inert_count_never_rises). Seven docs still quoted the pre-train numbers (252 / 294): README, GAPS, FEATURES, HANDOFF, CS6-PARITY, PROGRESS and NEXT. Dated point-in-time measurements ("245 ... as of 2026-11-10") stay as history; GAPS's dated gate note gains the post-train measurement alongside the original. Co-Authored-By: Claude Code --- README.md | 2 +- docs/CS6-PARITY.md | 2 +- docs/FEATURES.md | 4 ++-- docs/GAPS.md | 12 +++++++----- docs/HANDOFF.md | 4 ++-- docs/NEXT.md | 2 +- docs/PROGRESS.md | 2 +- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2e9304d..8867cf7 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The goal is not to reproduce Adobe's code or redistribute its assets. The goal i The workspace version is 0.2.5. Development continues beyond that release: the active roadmap includes editor reachability, daily-driver canvas workflows, and a dedicated CS6-inspired shell-fidelity campaign. FireCraft is functional software under active development—not yet a feature-complete replacement for every Fireworks CS6 workflow. -The current documented engine surface includes **252 registered commands** and a CS6 DOM parity matrix of **268 carried, 3 partial (evidence-gated), and 0 missing**. These figures describe the engine/DOM surface, not complete GUI parity: some commands are available through the command palette or automation surfaces before they have a corresponding menu or polished inspector workflow. +The current documented engine surface includes **253 registered commands** and a CS6 DOM parity matrix of **268 carried, 3 partial (evidence-gated), and 0 missing**. These figures describe the engine/DOM surface, not complete GUI parity: some commands are available through the command palette or automation surfaces before they have a corresponding menu or polished inspector workflow. ### What is implemented diff --git a/docs/CS6-PARITY.md b/docs/CS6-PARITY.md index 711a407..5f63a4a 100644 --- a/docs/CS6-PARITY.md +++ b/docs/CS6-PARITY.md @@ -308,7 +308,7 @@ the matrix does not read them as missing CS6 features. | Addition | Why it exists | Evidence | |---|---|---| -| Command palette (Ctrl+P) over the whole registry | CS6 had no palette; FireCraft's registry is 252 commands and a palette makes every one reachable | `S/palette.rs` | +| Command palette (Ctrl+P) over the whole registry | CS6 had no palette; FireCraft's registry is 253 commands and a palette makes every one reachable | `S/palette.rs` | | Rust-native `.fw.png` engine, CLI, journal, MCP server | headless automation and scripting parity beyond CS6's surface | `crates/app-cli` | | ExtendScript host running the CS6 `.jsf` corpus | scripting parity, headless | `crates/scripting` | | The **Web Layer** panel | FireCraft's own always-present web panel; CS6's web state lives in the Properties/Slices panels | `S/dialogs.rs::web_panel` | diff --git a/docs/FEATURES.md b/docs/FEATURES.md index a1e65b5..2528948 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -27,7 +27,7 @@ host, and the browser bridge all drive. ## The command registry One registry serves every surface. The live count is -`engine::catalog::ids()` — 252 as of 2026-11-07 (a point-in-time +`engine::catalog::ids()` — 253 as of 2026-11-11 (a point-in-time number; the call is the authority). The CS6 DOM parity matrix stands at **268 carried / 3 partial (evidence-gated) / 0 missing** across 356 verbs. @@ -35,7 +35,7 @@ verbs. Surfaces that drive it: - **GUI** — the shell (`crates/app/src/shell/`); menus map CS6 menu - ids to actions (`crates/app/src/menus.rs`; 2 of 294 items still + ids to actions (`crates/app/src/menus.rs`; 2 of 296 items still render inert — the 19.6 burn-down closed the rest, and the census is derived (`menus::tests::inert_worklist`) and test-gated), and the Ctrl+P command palette makes **every** registry command executable from diff --git a/docs/GAPS.md b/docs/GAPS.md index 488c9b6..601f770 100644 --- a/docs/GAPS.md +++ b/docs/GAPS.md @@ -20,7 +20,7 @@ | Surface | State | Evidence | |---|---|---| | Fireworks PNG format | Complete | `crates/fwpng`, `crates/doc/src/fwmap.rs`; node tree round-trips | -| Engine command registry | **252 commands** | `engine::catalog::ids()` — 252 as of 2026-11-07 | +| Engine command registry | **253 commands** | `engine::catalog::ids()` — 253 as of 2026-11-11 | | CS6 DOM verb parity | **268 C / 3 P / 0 M / 85 N** | `docs/planning/generated/dom-parity.md` (356 verbs) | | ExtendScript host | Complete | `crates/scripting` — runs the CS6 `.jsf` corpus headless | | Web bridge | Exposes **all** commands | `web/src/main.rs` — `apply(name, payload)` | @@ -41,7 +41,7 @@ shell reaches 72; after Phase 11's paint family it reaches 77; > **Note (2026-11-02):** the reachability picture above is a > point-in-time audit snapshot. The command palette (19.4, > `4458f3a`) makes **every** registry command executable from the -> GUI, and the inert count has fallen 190 → **2 of 294** menu +> GUI, and the inert count has fallen 190 → **2 of 296** menu > items (19.1–19.6 batches 1–17 + 19b.1/batch 2; derived + gated by > `menus::tests::inert_count_never_rises`). The family table below is > superseded by [`NEXT.md`](NEXT.md) Phases 19–21 as the work list; @@ -53,6 +53,8 @@ shell reaches 72; after Phase 11's paint family it reaches 77; > it to a floor in `.reachability-floor.tsv` (one-way ratchet). The > measurement it took on `main`: **245 registry commands, 146 bound = > 59.59%**, 99 unreachable — the floor is pinned at 59.59%. The +> post-train measurement (2026-11-11, after #107): **253 registry +> commands, 164 bound = 64.82%** — same floor, higher share. The > `comm` line above counts *any* occurrence of a command name in the > shell crate; the gate counts the same bindings outside `#[cfg(test)]` > code and reports them as a share, so the two numbers are close but @@ -83,7 +85,7 @@ $ comm -23 <(engine::catalog::ids()) <(command names in crates/app/src) Supporting evidence: - **190 of 265 CS6 menu items rendered disabled** (`Action::Inert`, - `crates/app/src/menus.rs`) **at audit time** — now 2 of 294, and + `crates/app/src/menus.rs`) **at audit time** — now 2 of 296, and the census is test-gated. The shell refuses to pretend. - **The app could not open a raster image.** *(fixed 2026-10-21)* `File > Open` called `Editor::open` → `app_cli::io::open`, which @@ -133,8 +135,8 @@ authoritative source that supersedes this table. | **aegis** | Baseline clean; scan 0.17 s | `.aegisignore` excludes `target/`, `web/dist/`, `fuzz/`; baseline is content-keyed (decision 0074), which supersedes the rule-class and per-finding suppression of decision 0070 | | **Coverage** | floors 81.1 % lines / 78.7 % funcs (`xtask/src/coverage.rs`) | Local `llvm-cov` fails on stale artifacts; CI works | | **Code** | 144,122 Rust lines | No `unwrap()`/`panic!()` outside `#[cfg(test)]`; no `todo!`/`unimplemented!` | -| **Registry** | 252 commands | Every command executable from the GUI via the Ctrl+P palette (19.4); menu reachability is the remaining gap | -| **Menu reachability** | 2 inert of 294 items | *live* — derived + gated (`menus::tests::inert_count_never_rises`) | +| **Registry** | 253 commands | Every command executable from the GUI via the Ctrl+P palette (19.4); menu reachability is the remaining gap | +| **Menu reachability** | 2 inert of 296 items | *live* — derived + gated (`menus::tests::inert_count_never_rises`) | | **Parity** | 268 C / 3 P / 0 M / 85 N | 3 P rows are evidence-gated (Phase 12 oracle) | | **Decision docs** | 90 (0001–0090) | Next: 0091 | | **Web bundle** | 21,608,249 B observed; 25,000,000 B warning / 50,000,000 B hard cap | Policy decision 0090; web build uses Rust opt-level=z and Binaryen wasm-opt=z. Cap is a guardrail, not a target; A/B size evidence remains required | diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 4aa4488..59317bd 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -23,11 +23,11 @@ the latest tag is `v0.2.5`). The tag and current `main` are different snapshots. See [`PROGRESS.md`](PROGRESS.md) for build and release evidence and [`TASKS.md`](TASKS.md) for current work. -- **Engine and parity:** 252 registry commands (`engine::catalog::ids()` +- **Engine and parity:** 253 registry commands (`engine::catalog::ids()` is the live authority); 268 carried / 3 partial / 0 missing of the 356 DOM verbs. Live generated files and source calls are authoritative for counts. -- **Menu census:** 2 of 294 menu rows remain non-dispatching. The 19.6 +- **Menu census:** 2 of 296 menu rows remain non-dispatching. The 19.6 wiring campaign is complete; remaining rows belong to future feature work or evidence gates. The live census is derived and gated by `menus::tests::inert_count_never_rises`. diff --git a/docs/NEXT.md b/docs/NEXT.md index 02b1a72..009a313 100644 --- a/docs/NEXT.md +++ b/docs/NEXT.md @@ -463,7 +463,7 @@ evidence work, tracked outside that campaign. drag (0.5×–3×, Reset to platform default) applies to the context each frame and rides `ShellLayout`, so it persists like the panel set. Gate: `preferences_scale_round_trips_the_layout`. The - Preferences menu row also left the inert census, now 2 of 294. + Preferences menu row also left the inert census, now 2 of 296. - **21.5 accesskit** desktop + web re-audit (0067 records the web blocker). - **21.6 In-app scripting** (S): Commands menu → run `.jsf`/`.fwsteps`. diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 37623d3..c7e198e 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -33,7 +33,7 @@ cannot execute the Rust suite; the current PR head has no GitHub Actions run/status receipt visible. Do not treat the new tests as passing until the repository CI or a local `cargo run -p xtask -- ci` completes. -- **Engine and parity:** 245 command IDs (source is authoritative); +- **Engine and parity:** 253 command IDs (source is authoritative); 268 carried / 3 partial / 0 missing of the 356 DOM verbs. - **CS6 keymap parity (2026-11-10, decisions 0080 + 0085):** every accelerator the menu bar prints is bound at the printed key — From 653a2a164833a9a41c69d1d7cec78d6c4606bf28 Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Wed, 11 Nov 2026 11:28:39 -0600 Subject: [PATCH 03/37] docs(ledger): record the post-train triage, #117, and the doc repair Header re-reconciled at b61f198; closed table gains rows for the post-train RustSec clear (#117, with #120 named for the serde_yaml removal), the evidence-based issue triage (8 closed, 6 updated, #121 filed), and the command-count/census doc repair in this branch. Co-Authored-By: Claude Code --- docs/TASKS.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/TASKS.md b/docs/TASKS.md index e34a761..c0d2e77 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -1,8 +1,9 @@ # FireCraft — Live task board -> **Live ledger.** Reconciled against `main` at `658f015` on 2026-11-11, +> **Live ledger.** Reconciled against `main` at `b61f198` on 2026-11-11, > after the shell-lineage train (#107) and the release-engineering train -> (#108, merged into the train as `1884c04`) landed. Use [`NEXT.md`](NEXT.md) +> (#108, merged into the train as `1884c04`) landed, plus the post-train +> dependency work (#117, #120). Use [`NEXT.md`](NEXT.md) > for phase detail and [`tasks/`](tasks/) for task tickets. Historical plans > and session notes are not current status sources. > @@ -157,6 +158,9 @@ progress: | Host fork-bomb from a throwaway `/proc/self/exe` probe — ~5800 processes at load 2057 starved the GitForge runner's sandbox; terminated by per-PID cmdline+exe verification and the probe directory moved aside | 2026-11-09 | | Task-board tracking scaffold — `docs/TASKS.md` plus the `docs/tasks/` per-task ticket set (one file per task, same objective/inputs/authority/stopping-condition/verification shape as the milestone tickets). The scaffold is this board and the `docs/tasks/` directory; the row it carried in the queued table is closed by this reconciliation | 2026-11-09 | | Shell-lineage and release-engineering trains merged — #107 squash `658f015` carrying #8, #13, #15, #41, #83, #84, #100, #102, #103 and (via #108 → `1884c04`) #85, #101, #104, #105, #106; the 14 constituent PRs were closed as merged-by-train, and Phase 20.5–20.7 plus all of Phase 21 shipped in the same landing | 2026-11-11 | +| Post-train RustSec lockfile clear — #117 (`b61f198`): `zbus_xml` 5.1.0→5.2.1 (drops `quick-xml` 0.38.4, clearing RUSTSEC-2026-0194/0195) and `tokio` 1.53.2→1.54.1 (clears RUSTSEC-2026-0386); `cargo audit` exit 0. The `serde_yaml`/`unsafe-libyaml` removal (RUSTSEC-2024-0449) rides PR #120 (saphyr swap in xtask's Flatpak parse) | 2026-11-11 | +| Post-train issue triage — closed with evidence: #79, #81, #86, #94, #98, #109, #111, #112 (all fixed by #107/#108's content or #14; squash broke the auto-close links); progress-commented and left open: #75, #76, #78, #93, #97, #110; filed #121 (`xtask changelog` cannot regenerate main's committed CHANGELOG after a squash merge) | 2026-11-11 | +| Command-count and menu-census doc repair — README, GAPS, FEATURES, HANDOFF, CS6-PARITY, PROGRESS and NEXT quoted stale pre-train numbers (252 commands / 294 items); corrected to the gated truth: **253 registered commands** (measured by `xtask reachability`, 164 bound = 64.82%) and **2 inert of 296** (the pinned census) | 2026-11-11 | ## Blocked or evidence-gated From 6f19a0f8a6a2247cdb6c694db3f16dbda5c84590 Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Wed, 11 Nov 2026 11:35:33 -0600 Subject: [PATCH 04/37] docs(progress): refresh the live snapshot for the post-train tree The snapshot still described 2026-11-07's PR #8 branch: unknown deployed revision, no CI receipts, 19.6 in flight, 22.1/22.2 'in this PR branch'. Refresh to 2026-11-11 (main at b61f198): #104's deployment reconciliation, the double-gate receipts (#107/#115/#117), Phase 21 done and Phase 20's remainder, and the post-train reachability measurement (253/164 = 64.82%) alongside the dated 2026-11-10 one. Dated build receipts are left as history. Co-Authored-By: Claude Code --- docs/PROGRESS.md | 58 +++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index c7e198e..a868674 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -5,17 +5,21 @@ > Historical narrative: [`HISTORY.md`](HISTORY.md) and > [`SESSIONS.md`](SESSIONS.md). -## Snapshot (2026-11-07, PR #8 branch; based on `main` at `5fac7a2`) +## Snapshot (2026-11-11, post-train; based on `main` at `b61f198`) -- **Release:** `v0.2.5` is the latest tag. `main` has additional work - since that tag. The public Pages manifest was checked on 2026-11-04 - 20:01 local time; its JavaScript, wasm, and index hashes differ from - the verified local optimized distribution. The deployed source - revision is unknown. +- **Release:** `v0.2.5` is the latest tag; `main` carries the + shell-lineage train (#107) and the post-train dependency work + (#117) beyond it. The live Pages deployment was reconciled on + 2026-11-11 (#104): its JavaScript, wasm and `appinfo` match the + released v0.2.5 web bytes; `host.html`/`index.html` differ only by + Cloudflare's injected analytics beacon. Decision recorded in #104: + the release bytes are the source of truth; republishing from the + release artifact is the pending next step (T18 row in + [`TASKS.md`](TASKS.md)). - **Build evidence:** the earlier optimized `dist/web/` distribution, built 2026-11-04 16:45 local time, had a 21,274,323-byte wasm (below the 21,500,000-byte ceiling). It was built from `56ee1bf`, @@ -27,12 +31,12 @@ captures and interaction checks covered this rebuilt artifact. The 18:21 `web/dist/` output was a raw 95,583,065-byte wasm bundle, not a release distribution. Neither directory is tracked by Git. -- **CI evidence:** PR #7's GitForge 8-job receipt and GitHub Actions - gate are recorded in the session notes. PR #8 review remediation now - has targeted regression tests in the branch, but this audit environment - cannot execute the Rust suite; the current PR head has no GitHub Actions - run/status receipt visible. Do not treat the new tests as passing until - the repository CI or a local `cargo run -p xtask -- ci` completes. +- **CI evidence:** PRs since #107 each carry a double GitHub `gate` + receipt — a full `cargo run -p xtask -- ci` at roughly 30 minutes — + plus fmt, CodeQL and the language analysis jobs. The train itself + (#107: 32m52s + 32m48s), #115 (32m36s + 28m7s) and #117 (32m50s + + 29m6s) are all double-green. Local full-gate receipts exist for the + post-train branches as well (`EXIT=0`, "all gates green"). - **Engine and parity:** 253 command IDs (source is authoritative); 268 carried / 3 partial / 0 missing of the 356 DOM verbs. - **CS6 keymap parity (2026-11-10, decisions 0080 + 0085):** every @@ -52,10 +56,13 @@ `menus::tests::inert_worklist`; ceiling: `menus::tests::inert_count_never_rises`. - **Current UI priority:** Phase 22.1 (panel inventory) and 22.2 - (tool strip) are complete in this PR branch; 22.5 (CS6 chrome audit) - remains partial. The screenshot acceptance work is complete, with - 1280×800 and 1920×1080 captures and empty/vector/bitmap states - recorded in [T22](tasks/T22-screenshot-ui.md). + (tool strip) landed on `main` with the shell-lineage train (#107); + 22.5 (CS6 chrome audit) remains partial. Phase 21 is complete + (2026-11-11); Phase 20 continues with Optimize (T7), animation + timeline (T8) and the mask stack (PR #113). The screenshot + acceptance work is complete, with 1280×800 and 1920×1080 captures + and empty/vector/bitmap states recorded in + [T22](tasks/T22-screenshot-ui.md). - **Completed foundations:** M0–M15, DOM verb-surface campaign, Phases 19.1–19.5, 19.6 menu wiring, and 19b. Three partial DOM rows and the other evidence-gated items remain parked pending new @@ -70,22 +77,27 @@ | Earlier optimized `dist/web/` | 2026-11-04 16:45 local; 21,274,323-byte wasm; manifest verified | Build from `56ee1bf`, whose Git tree matches `5fac7a2`; deployment comparison and earlier bridge smoke | | T22 optimized rebuild in `dist/web/` | 2026-11-04; 21,271,259-byte wasm | `5fac7a2` plus dock and inspector changes; six browser captures and interaction checks in [T22](tasks/T22-screenshot-ui.md#receipts--2026-11-04) | | Raw `web/dist/` | 2026-11-04 18:21 local; 95,583,065-byte wasm | Development output; not the optimized distribution | -| Browser smoke | Earlier optimized artifact: bridge smoke in session history; T22 rebuild: six captures and interaction checks in T22 | Local end-to-end proof for each recorded artifact; live deployed revision still unverified | -| Live Pages | Manifest fetched 2026-11-04 20:01 local | JS/wasm/index hashes differ from the earlier 21,274,323-byte optimized distribution; deployed revision unknown | +| Browser smoke | Earlier optimized artifact: bridge smoke in session history; T22 rebuild: six captures and interaction checks in T22 | Local end-to-end proof for each recorded artifact; the live deployment was reconciled against the release bytes on 2026-11-11 (#104) | +| Live Pages | Reconciled 2026-11-11 (#104) | JS/wasm/appinfo match the released v0.2.5 web bytes; `host.html`/`index.html` differ only by Cloudflare's injected beacon; release bytes are the source of truth | -- **Active work — the daily-driver expansion** (Phase 19 → 21, +- **Active work — the daily-driver expansion** (Phases 20–22, `docs/NEXT.md`): the engine is complete but the shell exposes a fraction of it, so the program is reachability + canvas, not - repair. 19.1–19.5 landed (transform handles, path-node editing, - gradient editor, command palette, guides/grid/snap); 19.6 - (inert-menu burn-down) is in flight. + repair. 19.1–19.6 all landed (transform handles, path-node editing, + gradient editor, command palette, guides/grid/snap, and the + inert-menu burn-down to 2 of 296); Phases 20 and 21 are the active + program — 20.1 and 20.5–20.7 plus all of Phase 21 shipped with + #107, leaving Optimize, animation timeline and the mask stack + (#113) open. - **UI-work gates landed (2026-11-10, issue #94):** the reachability gate (`cargo run -p xtask -- reachability`, wired into `ci`) derives the shell's bound command set from the shell crate's own source and holds it to a one-way floor in `.reachability-floor.tsv` — **245 - registry commands, 146 bound = 59.59%**, 99 unreachable. The panel + registry commands, 146 bound = 59.59%**, 99 unreachable as measured + on 2026-11-10; post-train (2026-11-11): **253 registry commands, + 164 bound = 64.82%**. The panel snapshot (`crates/app/panels.snapshot`, 14 panels) pins the panel set's structure; `egui_kittest` is obtainable (0.36.2 matches the locked egui) but its pixel path needs a wgpu adapter the CI image From 4a55f6b25aa5be479f9a4efafb8022df92d5da15 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:46:23 -0600 Subject: [PATCH 05/37] docs(ledger): reconcile current Phase 20 and release states --- docs/TASKS.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/TASKS.md b/docs/TASKS.md index c0d2e77..0a94478 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -44,7 +44,7 @@ |---|---|---|---| | P0 | Refresh user-visible CS6 parity matrix | **Done — matrix published** | [T26](tasks/T26-parity-matrix.md) → [`CS6-PARITY.md`](CS6-PARITY.md): every CS6 menu, tool, panel, inspector field set, workflow, import/export surface, canvas interaction, keymap area, and selection state classified with an evidence citation and an owning ticket. The browser-sampling check the ticket named was performed on 2026-11-04 against a fresh optimized bundle and is recorded in T22. | | P0 | Phase 22: CS6 shell fidelity and screenshot audit | In progress | [T22](tasks/T22-screenshot-ui.md) — screenshot acceptance is complete; 22.1 panel inventory and 22.2 tool strip landed on `main` with the shell-lineage train (#107); 22.5 chrome remains partial, and 22.4 still has evidence-gated bitmap transform/fill-stroke work. [Phase 22](NEXT.md#phase-22--cs6-shell-fidelity-p0-the-looks-and-acts-like-fireworks-phase) | -| P1 | Phase 20: daily-driver editing features | **In progress — 20.1, 20.5–20.7 landed** | In-canvas text editing landed 2026-11-06 ([T20](tasks/T20-text-editing.md)); multi-document tabs (20.5), history-panel rewind (20.6) and slice/hotspot behavior editing with HTML preview (20.7) landed 2026-11-11 with the shell-lineage train (#107). Remaining: Optimize ([T7](tasks/T7-optimize-panel.md)), animation timeline ([T8](tasks/T8-animation-timeline.md); compose-side onion skin landed as #100), mask stack (PR #113 in flight); [details](NEXT.md#phase-20--daily-driver-features-p1) | +| P1 | Phase 20: daily-driver editing features | **In progress — 20.1, 20.5–20.7 on main; 20.2–20.4 in PRs** | In-canvas text editing landed 2026-11-06 ([T20](tasks/T20-text-editing.md)); multi-document tabs (20.5), history rewind (20.6), and slice/hotspot behavior editing with HTML preview (20.7) landed 2026-11-11 in #107. Optimize panel and animation timeline are implemented in open PR #118; mask stack is in open PR #113. Do not count open PR work as shipped until merged and validated. [details](NEXT.md#phase-20--daily-driver-features-p1) | | P1 | Phase 21: modern differentiators | **Done — all items landed 2026-11-11** | Autosave/crash recovery, HiDPI, command palette v2 (fuzzy scoring, recents, Save Steps As Command), preferences, accesskit accessibility and in-app scripting (`.jsf`/`.fwsteps`) all landed with the shell-lineage train (#107, PR #15); [details](NEXT.md#phase-21--modern-differentiators) | | P1 | Reconcile live web deployment | **Reconciled — republish pending** | #104 (`docs/web-deployment-reconciliation`) reconciled the live site against v0.2.5: the JS, wasm and `appinfo` match; `host.html`/`index.html` fail the site's own manifest because Cloudflare injects an analytics beacon after it is written. Decision recorded there: the release bytes are the source of truth. Next: republish from the release artifact. See [T18](tasks/T18-release.md). | | P2 | Next-release asset breadth and platform verification | Open | [T23](tasks/T23-release-assets.md); recipes exist, but non-Linux artifacts need real platform build/launch receipts. | @@ -56,7 +56,7 @@ | # | Task | Ticket | Status | Owner | Next action | |---|---|---|---|---|---| -| 5 | 19.6 inert-menu burn-down — Modify/File families (83 of 289; batch 8 = Attach to Path landed 2026-11-03) | [tasks/T5-inert-burndown.md](tasks/T5-inert-burndown.md) | `IN PROGRESS` | UI/verb lane | continue the per-family burn-down; each batch carries its own evidence gate. The current census: batches 1–17 landed with 2 inert rows of 296 (the pinned total, `menus::tests::menu_item_total_is_pinned`), derived by `menus::tests::inert_count_never_rises` (ceiling 2) | +| 5 | 19.6 inert-menu wiring campaign | [tasks/T5-inert-burndown.md](tasks/T5-inert-burndown.md) | `DONE — 2026-11-11` | UI/verb lane | Batches 1–17 are complete. The current pinned census is 2 inert rows of 296; eight other rows remain explicitly feature/evidence-gated and are not part of an active wiring campaign (`menus::tests::inert_count_never_rises`, `menus::tests::menu_item_total_is_pinned`). | | 194 | Aegis gate: content-keyed baseline, so a doc edit no longer fails the gate (decision 0074) | [decisions/0074-aegis-content-keyed-baseline.md](decisions/0074-aegis-content-keyed-baseline.md) | `IMPLEMENTED` — the content-keyed gate and its decision record are in the tree; the gate has been exercised on this branch's tree | CI/tooling lane | **landed in `main` (#18)** and merged here; attach a run id before claiming the fleet-wide state | | 27 | Cross-platform release engineering: Windows, macOS, Linux package matrix, Android feasibility, source, SBOM/provenance, signing, CI aggregation and certification | [tasks/T27-cross-platform-release.md](tasks/T27-cross-platform-release.md) | `IN PROGRESS` — implementation is ahead of verification; **no target is `CERTIFIED`** and nothing is signed | release-workflow lane | land an end-to-end tag run of the repaired workflow and attach the run id as the RP-07 receipt; consolidate the duplicated `dist --source`/`--sbom` verbs (B-3) | | 26 | Refresh user-visible CS6 parity matrix | [tasks/T26-parity-matrix.md](tasks/T26-parity-matrix.md) | `IMPLEMENTED` — matrix published | parity lane | every CS6 menu, tool, panel, inspector field set, workflow, import/export surface, canvas interaction, keymap area, and selection state is classified with an evidence citation and an owning ticket in [`CS6-PARITY.md`](CS6-PARITY.md); the browser-sampling check the ticket named was performed on 2026-11-04 against a fresh optimized bundle and is recorded in T22 | @@ -64,17 +64,18 @@ | 20 | 20.1 In-canvas text editing (egui TextEdit overlay; kittest focus tests) | [tasks/T20-text-editing.md](tasks/T20-text-editing.md) | `IMPLEMENTED` — landed 2026-11-06 (`shell::begin_text_edit` / `text_edit_overlay`) | editing lane | the remaining Phase 20 items (Optimize, animation timeline, mask stack, tabs, history rewind, slice behavior) stay queued below | -## Queued (Phase 20 — daily-driver features) +## Phase 20 — remaining work (open PRs) | # | Task | Ticket | |---|---|---| -| 20 | 20.1 In-canvas text editing (egui TextEdit overlay; kittest focus tests) | [tasks/T20-text-editing.md](tasks/T20-text-editing.md) | -| 7 | 20.2 Optimize panel (palette/bitrate over `ExportOptions` + live preview) | [tasks/T7-optimize-panel.md](tasks/T7-optimize-panel.md) | -| 8 | 20.3 Animation timeline (frames strip, timing, onion skinning, `symbol.tween`) | [tasks/T8-animation-timeline.md](tasks/T8-animation-timeline.md) | -| — | 20.4 Mask stack UI (add/remove/mode/link/move) | PR #113 (in flight) | +| 7 | 20.2 Optimize panel | [tasks/T7-optimize-panel.md](tasks/T7-optimize-panel.md) | PR #118 (open; not on main) | +| 8 | 20.3 Animation timeline | [tasks/T8-animation-timeline.md](tasks/T8-animation-timeline.md) | PR #118 (open; not on main) | +| — | 20.4 Mask stack UI | [decision 0093](decisions/0093-mask-stack-levels-and-folding.md) | PR #113 (open; not on main) | -## Queued (Phase 21 — modern differentiators) +20.1 and 20.5–20.7 are already on `main`; do not reopen them. + +## Phase 21 — delivered modern differentiators **All Phase 21 items landed 2026-11-11** with the shell-lineage train (#107, PR #15): autosave/crash recovery, HiDPI, command palette v2 @@ -87,7 +88,7 @@ Commands menu). Scope detail stays in | # | Task | Ticket | Status | Owner | Next action | |---|---|---|---|---|---| -| 18 | Ship v0.2.5: release assets + web deploy | [tasks/T18-release.md](tasks/T18-release.md) | `BLOCKED` — blocked on T23's asset breadth. The v0.2.5 release exists as published artifacts, but the **live web deployment serves a bundle that corresponds to no identifiable release** (B-6), and the published set was published out of band rather than by the release workflow (B-21) | release-workflow lane | reconcile the deployed bundle against a tagged release by hashing the deployed assets individually and recording the producing commit; do not re-cut v0.2.5 — B-19 means the next artifact must be rebuilt and re-measured, not re-tagged | +| 18 | Republish the reconciled v0.2.5 web artifact | [tasks/T18-release.md](tasks/T18-release.md) | `RECONCILED — REPUBLISH PENDING` | release-workflow lane | #104 established that the live JavaScript, Wasm and `appinfo` match the v0.2.5 release bytes; the remaining `host.html`/`index.html` differences are Cloudflare's injected analytics beacon. Republish from the canonical release artifact and verify the deployed hashes/cache stamp; do not describe the deployment as an unidentified bundle. | | 23 | Broaden release assets to photocraft breadth (dmg, AppImage, Flatpak, win installer) | [tasks/T23-release-assets.md](tasks/T23-release-assets.md) | `IMPLEMENTED` for the recipe set, `NOT STARTED` for every off-fleet artifact — the AppImage, Flatpak, Windows and macOS recipes exist and are parse-checked (or existence-checked) by the gate, but **none has ever been produced**: `linuxdeploy`, `flatpak`/`flatpak-builder`, `pwsh`/`ISCC`, and `lipo`/`hdiutil`/Xcode CLT are all absent from the fleet (B-8, B-11, B-12) | release-workflow lane | either provision a host with each SDK and produce the artifact, or keep the recipes recipe-only and let the scope decision in 0075 exclude those targets — do not advertise them as supported | | 19 | Quality ratchet: coverage → 99%, `deny(missing_docs)` on geom/color, WCAG AAA | — | `NOT STARTED` | quality lane | schedule after the release lane; the coverage floor is a workspace-wide change | | 21 | egui_kittest snapshot gates per panel/toolbar | — | `NOT STARTED` | quality lane | needs a stable per-panel harness | From f86fd750231005f67056ab814cebe4ba2d0ed3b1 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:46:43 -0600 Subject: [PATCH 06/37] docs(roadmap): refresh phase status and measured parity gates --- docs/NEXT.md | 74 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/docs/NEXT.md b/docs/NEXT.md index 009a313..b601202 100644 --- a/docs/NEXT.md +++ b/docs/NEXT.md @@ -1,5 +1,14 @@ # FireCraft — Roadmap detail +> **Current execution snapshot (2026-11-11; main `b61f198`):** Phase 21's +> user-facing deliverables have landed. Phase 20.1 and 20.5–20.7 are on +> main; Optimize/timeline are in open PR #118 and the mask stack is in +> open PR #113. Phase 22 remains partial: the user-visible parity matrix +> is published, but bitmap inspector capabilities and remaining CS6 chrome +> are still open/evidence-gated. Use [TASKS.md](TASKS.md) for live status +> and [PROGRESS.md](PROGRESS.md) for measured receipts. An open PR is not +> a landed feature. + > Current task state is tracked in [`TASKS.md`](TASKS.md), with a dated > snapshot in [`PROGRESS.md`](PROGRESS.md). This file is the detailed > phase plan, not a second live ledger. @@ -373,11 +382,13 @@ evidence work, tracked outside that campaign. one-way ratchet: `--bless` may raise it (reachability improved) and refuses to lower it (a regression is fixed, not forgiven). Measured on `main` at 2026-11-10: **245 registry commands, 146 bound by the - shell = 59.59%**, 99 unreachable; the floor is pinned at 59.59%. - (The command palette makes the *palette* reach 100% — the gate - deliberately measures the CS6-visible surface instead, which is the - surface the 19.x batches widen. Decision - [`0087`](decisions/0087-ui-work-gates.md).) + shell = 59.59%**, 99 unreachable; the floor was pinned at 59.59%. + **Latest post-train measurement (2026-11-11): 253 registry commands, + 164 shell-bound = 64.82%.** The floor remains 59.59%; the improvement + is recorded, not used to silently re-bless a higher floor. The command + palette reaches all registry commands, but this gate deliberately + measures the CS6-visible surface. Decision + [`0087`](decisions/0087-ui-work-gates.md). - **19b.3 Inert-drift test** (S): every non-Help/Command `Action::Inert` item carries a tracking reference, so an inert item cannot be added silently. — **LANDED 2026-11-02** in the stronger form: the census @@ -385,7 +396,9 @@ evidence work, tracked outside that campaign. (`INERT_CEILING`), so a newly inert row fails the test until the ceiling is deliberately re-pinned. Per-item tracking references were dropped as unnecessary — the count is the honest metric and the gate - refuses any rise in it. + refuses any rise in it. **Latest census (2026-11-11): 2 inert rows of + 296 total**, with eight separate feature/evidence-gated rows. The + 19.6 wiring campaign is complete; do not keep it in progress. - **19b.4 Wasm budget re-pin** (S) — **DONE (2026-11-03)**: re-measured and re-pinned with evidence. `xtask dist --web` observed **21,235,599 B** (trunk --release, wasm-opt 2, rustc 1.99, wasm-opt @@ -407,25 +420,36 @@ evidence work, tracked outside that campaign. double-click enters, Esc cancels, focus loss / tool switch commits ([T20](tasks/T20-text-editing.md)). Kittest focus tests deferred — see the ticket's residual note. -- **20.2 Optimize panel** (M): palette/bitrate over `ExportOptions` + - live preview (export preview exists). -- **20.3 Animation timeline** (M): frames strip, per-frame timing, - onion skinning, `symbol.tween`. -- **20.4 Mask stack UI** (M): add/remove/mode/link/move. -- **20.5 Multi-document tabs** (M): **LANDED 2026-11-07** — Open/New - park the active document as a `DocTab`; Close promotes the newest - parked tab (refuses dirty documents); the tab strip shows the - active doc plus parked tabs, click to switch, a dot marks unsaved - edits. Gate: `open_parks_the_previous_document`, - `activate_tab_swaps_state`, `close_promotes_the_last_parked_tab`, - `new_parks_the_current_document`, - `close_refuses_a_dirty_document`. (Window-menu panel toggles landed - in Phase 19.6 batches 3 and 10.) -- **20.6 History panel click-to-rewind** (S): journal replay to seq N. -- **20.7 Slice/hotspot behavior editing + HTML preview** (M). +- **20.2 Optimize panel** (M): palette/bitrate over `ExportOptions` + plus live preview. **Implemented in open PR #118**; do not mark + shipped until merge and the release/e2e evidence is attached. +- **20.3 Animation timeline** (M): frame strip, per-frame timing, + onion skinning, and frame operations. **Implemented in open PR #118**; + the compositor-side onion-skin renderer landed earlier in #100. +- **20.4 Mask stack UI** (M): add/remove/mode/link/move. **In open PR + #113**; this is a FireCraft extension, not a CS6 parity claim. +- **20.5 Multi-document tabs** (M): **LANDED 2026-11-11** in #107 — + Open/New park the active document as a `DocTab`; Close promotes the + newest parked tab and refuses dirty documents; the tab strip switches + documents and marks unsaved edits. +- **20.6 History panel click-to-rewind** (S): **LANDED 2026-11-11** + in #107; the session-scoped rewind command is also discoverable from + the command palette and MCP list/run surface in open PR #122. +- **20.7 Slice/hotspot behavior editing + HTML preview** (M): + **LANDED 2026-11-11** in #107. ### Phase 21 — Modern differentiators (P2) +**Delivery status (2026-11-11):** all six planned user-facing +deliverables landed on main with #107: autosave/recovery, HiDPI canvas, +command palette v2, preferences, accessibility work, and in-app +scripting. Decision 0067 continues to document the known screen-reader +limitations of the web canvas; landing the desktop/accesskit work does +not mean the web canvas has full screen-reader parity. The remaining +effect-cache view-transform optimization noted under 21.2 is a separate +performance follow-up, not a reason to reopen the delivered MVP features. + + - **21.1 Autosave + crash recovery** (M): periodic journal snapshot to a sidecar; restore prompt on open. — **LANDED 2026-11-07**, per surface: the web build persists the whole document (canonical save @@ -464,8 +488,10 @@ evidence work, tracked outside that campaign. each frame and rides `ShellLayout`, so it persists like the panel set. Gate: `preferences_scale_round_trips_the_layout`. The Preferences menu row also left the inert census, now 2 of 296. -- **21.5 accesskit** desktop + web re-audit (0067 records the web - blocker). +- **21.5 accesskit** desktop + web re-audit — **LANDED 2026-11-11** + in #107 for the supported desktop/accessibility surface. Decision + 0067 remains the authority for the web-canvas screen-reader limitation; + do not describe that limitation as resolved. - **21.6 In-app scripting** (S): Commands menu → run `.jsf`/`.fwsteps`. — **LANDED 2026-11-07**: `.jsf` running through the scripting host had landed with the automation milestone (Commands ▸ Run Script / From 93fa7b0af28cec8668b5bbbb229fe6b6848949a8 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:47:00 -0600 Subject: [PATCH 07/37] docs(handoff): refresh current main and open work snapshot --- docs/HANDOFF.md | 53 ++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 59317bd..8b5b96b 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -17,29 +17,42 @@ --- -## 1. State snapshot (2026-11-07; PR #8 working branch) - -- **Source state:** `main` is at `5fac7a2` (v0.2.5-era development; - the latest tag is `v0.2.5`). The tag and current `main` are different - snapshots. See [`PROGRESS.md`](PROGRESS.md) for build and release - evidence and [`TASKS.md`](TASKS.md) for current work. -- **Engine and parity:** 253 registry commands (`engine::catalog::ids()` - is the live authority); 268 carried / 3 partial / 0 missing of the 356 - DOM verbs. Live generated files and source calls are authoritative - for counts. -- **Menu census:** 2 of 296 menu rows remain non-dispatching. The 19.6 - wiring campaign is complete; remaining rows belong to future feature - work or evidence gates. The live census is derived and gated by - `menus::tests::inert_count_never_rises`. -- **Current UI front:** Phase 22 shell fidelity and screenshot-driven - responsive review. The tracked screenshot was replaced on 2026-11-04 - with a capture of the current shell; its receipts and limits are in - [`tasks/T22-screenshot-ui.md`](tasks/T22-screenshot-ui.md). - +## 1. State snapshot (2026-11-11; main `b61f198`) + +- **Source and release:** canonical `main` is `b61f198` after the + shell-lineage/release trains and post-train RustSec work. The latest + published release remains `v0.2.5` (2026-11-03); current source has + moved beyond that tag. See [PROGRESS.md](PROGRESS.md) for dated build, + CI and deployment receipts. +- **Engine and parity:** 253 registered commands; the CS6 DOM matrix is + 268 carried / 3 partial / 0 missing of 356 verbs. The latest + shell-reachability measurement is 164/253 = 64.82%; the one-way floor + remains 59.59%. These measures answer different questions: DOM verbs, + shell-bound commands, and complete end-user UI/workflow parity must + not be conflated. +- **Menu census:** 2 inert rows of 296. The 19.6 menu-wiring campaign is + complete; eight additional rows are explicitly feature/evidence-gated. +- **Delivered work:** Phase 21's user-facing deliverables landed with + #107. Phase 20.1 and 20.5–20.7 are on main. Optimize/timeline work is + in open PR #118; the mask stack is in open PR #113. Check the live + [TASKS.md](TASKS.md) before selecting work. +- **Phase 22:** screenshot acceptance and panel/tool/context-menu + foundations landed; bitmap inspector gaps and remaining CS6 chrome + keep the phase partial. The full user-visible inventory is + [CS6-PARITY.md](CS6-PARITY.md). +- **Release/deployment:** #104 reconciled the deployed JavaScript, + Wasm and WebOS `appinfo` with v0.2.5 release bytes. Cloudflare's + analytics injection explains the remaining HTML hash difference. + Republish from the exact release artifact is pending (T18). No + non-Linux native artifact is certified by recipe or cross-compile + alone; see [ARTIFACT-MATRIX.md](release/ARTIFACT-MATRIX.md). +- **Open integration work:** #120 removes the deprecated YAML parser; + #122 improves history-rewind command discovery; #123 reconciles docs. + Recheck each PR's current state before depending on it. - **Clean-room invariants:** `source/` and Adobe-derived local extracts are reference-only and never committed. Adobe-authored corpus files are test oracles. Assets require an attribution row in - [`ATTRIBUTION.md`](ATTRIBUTION.md). + [ATTRIBUTION.md](ATTRIBUTION.md). ## 2. Where everything lives From 079f6142ca2d6758b1bdba38d51146c4eaf6ebe5 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:47:32 -0600 Subject: [PATCH 08/37] docs(plan): refresh current baseline and remove duplicated references --- docs/PRODUCTION-READINESS-PLAN.md | 60 +++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/docs/PRODUCTION-READINESS-PLAN.md b/docs/PRODUCTION-READINESS-PLAN.md index 23f5ead..3ea5357 100644 --- a/docs/PRODUCTION-READINESS-PLAN.md +++ b/docs/PRODUCTION-READINESS-PLAN.md @@ -48,8 +48,6 @@ The expanded delivery matrix and shared-workflow adoption plan are tracked in complete product delivery matrix and RP-09 SDK/interoperability work package. The companion host-side roadmap is [ArtCraft-WebOS PR #36](https://github.com/aliasfoxkde/ArtCraft-WebOS/pull/36). -The host-side architecture work is tracked in -[ArtCraft-WebOS PR #36](https://github.com/aliasfoxkde/ArtCraft-WebOS/pull/36). The FireCraft-side requirements, security boundary, library strategy, and cross-repository test matrix are in [WEBOS-PLATFORM-INTEGRATION.md](WEBOS-PLATFORM-INTEGRATION.md). @@ -67,19 +65,51 @@ independently compiled Craft WASM apps. ## 2. Current baseline and known work in flight -The initial audit and current GitHub tree establish these starting points. Refresh them at the start of each work session: - -- The workspace uses Rust edition 2024 and declares Rust 1.95. -- The production web entry is the Trunk-built Rust/WASM app in the web crate. -- The previous build selected Trunk/Binaryen optimization level 4, which prioritizes speed rather than minimum output size. -- The root release profile already uses ThinLTO. The web build now adds a scoped Cargo opt-level=z override and Trunk wasm-opt=z without changing native desktop release settings. -- The measured Phase 21/22 baseline is 21,608,249 raw Wasm bytes, recorded 2026-11-10. Decision 0090 sets a 25,000,000-byte warning and 50,000,000-byte hard ceiling. The hard ceiling is a safety limit, not a target. -- The browser bridge smoke is implemented in xtask. GitHub tag CI can run it; the GitForge workflow still contains a temporary smoke-skip path tracked by PR #40. A skipped smoke is not a release receipt. -- The current application and release work is distributed across feature and infrastructure PRs. The 2026-11-10 snapshot included PR #15, #40, #41, #73, #74, #82, and #83 among other open work. This is a snapshot, not a substitute for querying GitHub. -- Known release issues include live web deployment reconciliation (#30/#81), DEB runtime dependencies (#39), release orchestration (#33), provenance/signing (#32), native Windows/macOS receipts (#31), and final certification (#34). -- Phase 21/22 feature work, desktop integration, web smoke, campaign mandate, execution board, coverage diagnostics, and size-policy work are separate branches/PRs. Preserve the existing stack rather than recreating or overwriting it. - -The live GitHub source and CI receipts outrank this snapshot. Historical audits should remain dated and clearly identified as historical; do not silently rewrite historical evidence to make it look current. +This is a dated execution baseline, not a substitute for refreshing GitHub +before each session. The current live task ledger and release artifact matrix +are authoritative for task and platform status. + +- **Canonical source:** `main` at `b61f198` on 2026-11-11. The latest + published version remains `v0.2.5` (2026-11-03); the source tree has + advanced beyond that tag. +- **Editor surface:** 253 registered engine commands; 164 are bound in the + CS6-visible shell surface (64.82%, latest measurement 2026-11-11). The + generated DOM matrix is 268 carried / 3 partial / 0 missing of 356 verbs. + These are separate measurements and neither establishes complete + end-user GUI parity. +- **Menus and panels:** 2 inert menu rows of 296; eight additional rows + remain explicitly feature/evidence-gated. The 19.6 inert-menu wiring + campaign is complete. The CS6 user-visible matrix is published in + `docs/CS6-PARITY.md`. +- **Recent delivered work:** Phase 21's user-facing deliverables and Phase + 20.1/20.5–20.7 landed in the 2026-11-11 shell-lineage train (#107). + Optimize/timeline work is in open PR #118; the mask stack is in open + PR #113. These are not shipped until merged. +- **WASM/release policy:** the web-only Cargo `opt-level=z` and Binaryen + `wasm-opt=z` path is scoped to Trunk; decision 0090 sets a + 25,000,000-byte investigation warning and 50,000,000-byte hard ceiling. + The ceiling is a safety boundary, not a target. The 21,608,249-byte + observation from 2026-11-10 is a dated feature-branch measurement, not + a new main-branch release receipt. +- **Deployment:** #104 reconciled the deployed JavaScript, Wasm and + `appinfo` with v0.2.5 release bytes; Cloudflare injects an analytics + beacon into the served HTML, which explains the remaining HTML hash + difference. Republish from the canonical release artifact is pending + (T18). +- **Release certification:** Linux x86_64 desktop/CLI archives, DEB and + the web bundle have published receipts for v0.2.5. Off-fleet Windows, + macOS, AppImage and Flatpak recipes are not target-native release + receipts. No target may be called certified without build, install, + launch, functional smoke and publication evidence. See + `docs/release/ARTIFACT-MATRIX.md` and T27. +- **Open integration changes:** #120 replaces deprecated `serde_yaml` + in the packaging-manifest parser; #122 extends command discovery for + session-scoped history rewind; #123 reconciles the live docs. Refresh + their current review and CI state before depending on them. + +The live GitHub source, current PR heads, and target receipts outrank this +snapshot. Historical audits should remain dated and clearly identified as +historical; do not silently rewrite their measurements to look current. ## 3. Agent roles and file ownership From ae723cda6e5bf9a52f923525b1057854fe0411a3 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:47:34 -0600 Subject: [PATCH 09/37] docs(features): refresh audit date and parity caveat --- docs/FEATURES.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 2528948..14292cf 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -1,12 +1,12 @@ # FireCraft — Feature surface -> Audited 2026-11-01 against the main tree. Every claim here is -> backed by a gate in the repository: the command registry -> (`engine::catalog::ids()`), the parity matrix -> (`docs/planning/generated/dom-parity.md`), the menus -> (`crates/app/src/menus.rs`), and the CLI (`crates/app-cli`). +> Feature inventory originally audited 2026-11-01; status and +> command/reachability counts refreshed 2026-11-11 against `main` +> (`b61f198`). Claims are grounded in the command registry, +> generated DOM parity, menu census, CLI and current task ledger. > Where a feature is a *recipe* rather than a built artifact, it says -> so. +> so. A DOM verb or CLI command is not by itself proof of a complete, +> polished GUI workflow. FireCraft is a clean-room reimplementation of Adobe Fireworks CS6 — the hybrid vector + bitmap web-design tool Adobe discontinued in 2013 From 8671874c2006d137c30e4deb255d3c5d02299195 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:47:37 -0600 Subject: [PATCH 10/37] docs(parity): refresh matrix review metadata --- docs/CS6-PARITY.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/CS6-PARITY.md b/docs/CS6-PARITY.md index 5f63a4a..db0c508 100644 --- a/docs/CS6-PARITY.md +++ b/docs/CS6-PARITY.md @@ -1,10 +1,12 @@ # CS6 user-visible parity matrix -> Audited 2026-11-04 against the `main` tree; **revised 2026-11-07** -> after the Phase 20/21/22 landings (tabs, autosave, Preferences, -> Run Script, in-canvas text editing, and the five Window panels). -> This is the -> **user-visible** inventory demanded by +> Initial inventory audited 2026-11-04; refreshed against +> `main` at `b61f198` on 2026-11-11 after the shell-lineage train: +> multi-document tabs, history rewind, slice/hotspot editing, the +> Phase 21 deliverables, and the completed menu wiring campaign. +> Remaining Phase 20/22 work is called out with its current PR or +> evidence gate in this matrix and [TASKS.md](TASKS.md). +> This is the **user-visible** inventory demanded by > [`tasks/T26-parity-matrix.md`](tasks/T26-parity-matrix.md): every > Fireworks CS6 workflow and UI area a person can reach, classified > with a citation. It is *not* the DOM verb matrix From ef2b9e37ff8fd0c7f04e2e8716358c390bba67d8 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:47:40 -0600 Subject: [PATCH 11/37] docs(index): add distribution and platform integration references --- docs/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 2dcf03d..015f909 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,7 +8,9 @@ This page is the documentation map. Start with the overview that matches your go 1. [Usage](USAGE.md): install/build, CLI examples, keyboard shortcuts, and browser embedding. 2. [Features](FEATURES.md): implemented surfaces and their verification gates. -3. [WebOS embedding](WEBOS.md): host page contract and browser bridge. +3. [Release engineering](RELEASE-ENGINEERING-PLAN.md): standalone platform matrix, artifact evidence, SDK distribution and shared CI adoption. +4. [WebOS embedding](WEBOS.md): current host page contract and browser bridge. +5. [Platform integration](WEBOS-PLATFORM-INTEGRATION.md): future versioned SDK, command/capability contract and WebOS interoperability. ### I want to understand project status From 8a8b195834b3a117416bc99f994e66a0271ffc45 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:48:37 -0600 Subject: [PATCH 12/37] docs(wiki): refresh FireCraft project status --- docs/wiki/Project-Status.md | 43 ++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/docs/wiki/Project-Status.md b/docs/wiki/Project-Status.md index 08157f2..de835f4 100644 --- a/docs/wiki/Project-Status.md +++ b/docs/wiki/Project-Status.md @@ -1,26 +1,39 @@ # Project Status -## Current snapshot - -The last audited source snapshot is `main` at `5fac7a2` (2026-11-04); the latest release tag is `v0.2.5`. The detailed [Progress page](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md) is the authority for current counts and validation receipts. +**Snapshot reviewed:** 2026-11-11 +**Source:** `main` at `b61f198` +**Latest published release:** [v0.2.5](https://github.com/aliasfoxkde/FireCraft/releases/tag/v0.2.5) (2026-11-03) -The source snapshot has a recent optimized web distribution whose manifest verifies. The public Pages manifest has different JavaScript, wasm, and index hashes from that local distribution; its deployed source revision is unknown. Do not infer the live build from the source version alone. +FireCraft is a functional Rust graphics editor with a shared document engine and command registry across the desktop GUI, WebAssembly app, CLI, scripting host, and MCP server. The current source is newer than the latest published release; do not assume the hosted app contains every change on `main`. -## Where work stands +## Current snapshot - +| Surface | Current state | +|---|---| +| Engine commands | 253 registered command IDs | +| Shell reachability | 164/253 = 64.82% in the 2026-11-11 measurement; the command palette exposes the full registry, but this gate measures the CS6-visible shell | +| CS6 DOM matrix | 268 carried / 3 partial / 0 missing of 356 verbs; this is scripting/API parity, not GUI parity | +| Menu census | 2 inert rows of 296; eight other rows are explicitly feature/evidence-gated | +| User-visible parity | Full inventory published in [CS6-PARITY.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md) | +| Phase 20 | 20.1 and 20.5–20.7 are on main; Optimize/timeline are in [PR #118](https://github.com/aliasfoxkde/FireCraft/pull/118), mask stack in [PR #113](https://github.com/aliasfoxkde/FireCraft/pull/113) | +| Phase 21 | User-facing modern deliverables landed in the 2026-11-11 train | +| Phase 22 | Partial: core panel/tool/context surfaces landed; remaining inspector and chrome details are tracked | +| Published artifacts | Linux x86_64 GUI/CLI archives, DEB, and web bundle in v0.2.5 | +| Other native formats | Recipes exist, but Windows, macOS, AppImage and Flatpak need target-native build/install/launch receipts before being called supported | - +## Deployment and release -- M0–M15 and the DOM verb-surface campaign are complete. -- The 19.6 menu-wiring campaign is complete; 2 of 296 rows are inert and eight additional rows remain feature- or evidence-gated. -- Phase 22 shell fidelity is the active UI front. Phase 20 daily-driver features and Phase 21 modern additions are queued. -- T22 recorded a replacement 1280×800 vector screenshot and empty, vector, and bitmap captures at both 1280×800 and 1920×1080. See the [build and capture receipts](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/tasks/T22-screenshot-ui.md#receipts--2026-11-04) for the tested artifact and limits. +The 2026-11-11 deployment reconciliation (#104) found that the live site's JavaScript, Wasm and WebOS app metadata match the v0.2.5 release bytes. Cloudflare injects an analytics beacon into the served HTML, which accounts for the remaining HTML-manifest difference. Republish from the canonical release artifact is pending. - +The current release program keeps standalone FireCraft and embeddable developer artifacts as complementary targets. A packaging recipe or cross-compile is not a verified release. -## Live sources +## Where to go next +- [Current task board](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TASKS.md) - [Detailed roadmap](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md) -- [Build and deployment evidence](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md) -- [Release notes](https://github.com/aliasfoxkde/FireCraft/tree/main/docs/releases) +- [Progress and receipts](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md) +- [User-visible CS6 parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md) +- [Release artifact matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/release/ARTIFACT-MATRIX.md) +- [Known gaps](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/GAPS.md) (historical audit; use TASKS/PROGRESS for current status) + +The full measured state, including limitations and dates, is in the repository documentation. This page is a navigation summary, not a certification claim. From 6d68987ce5d6db3d1b101176682d77a2c6860124 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:48:41 -0600 Subject: [PATCH 13/37] docs(wiki): reconcile parity roadmap and delivered phases --- docs/wiki/Parity-Roadmap.md | 87 ++++++++++++------------------------- 1 file changed, 28 insertions(+), 59 deletions(-) diff --git a/docs/wiki/Parity-Roadmap.md b/docs/wiki/Parity-Roadmap.md index deafaff..ca90fde 100644 --- a/docs/wiki/Parity-Roadmap.md +++ b/docs/wiki/Parity-Roadmap.md @@ -1,73 +1,42 @@ # Fireworks CS6 Parity Roadmap -This page collects the currently documented work toward Fireworks CS6 feature and UI/UX/layout parity. It separates parity work from FireCraft's modern additions. The sequence is a practical work order; individual phases may move when evidence or dependencies require it. +This page summarizes FireCraft's current user-visible parity work. It does not claim that every undocumented Fireworks behavior has been reproduced. The detailed, evidence-bearing inventory is [CS6-PARITY.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md). -## Ordered work at a glance +**Status reviewed:** 2026-11-11 against `main` at `b61f198`. -Status below is the audited source snapshot at `5fac7a2` (2026-11-04). Check [Project Status](Project-Status) for the current deployment and validation evidence. +## How to read parity -| Order | Work | State | -|---|---|---| -| 1 | Finish CS6 shell presentation and responsive layout (Phase 22) | Active; panel reachability and screenshot review lead | -| Alongside | Refresh the complete user-visible parity inventory | Needed before any full-parity claim; DOM parity alone does not cover UI/workflows | -| 2 | Complete daily-driver workflows (Phase 20) | Queued | -| 3 | Add modern FireCraft capabilities (Phase 21) | Queued; separate from CS6 parity | +Keep three independent measures separate: -## Cross-cutting gate: complete the parity inventory +- **DOM/API parity:** 268 carried, 3 partial, 0 missing of 356 verbs. This describes scripting/API compatibility. +- **Shell command reachability:** 164 of 253 registered engine commands are bound in the CS6-visible shell surface (64.82%, measured 2026-11-11). The command palette exposes the full command registry, but that does not mean every operation has a polished contextual GUI. +- **User-visible feature parity:** each menu, tool, panel, inspector field, workflow, import/export path, canvas interaction, keymap and selection state is classified in the [parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md). -1. **Refresh the user-visible parity matrix.** Map the CS6 menus, tools, panels, inspectors, document workflows, and important selection states to `implemented`, `partial`, `missing`, or `evidence-gated` behavior. Start this audit alongside the active shell work; finish it before claiming full parity. -2. **Keep source evidence attached.** For each gap, link the code path, research note, decision, screenshot, or behavior observation that supports the status. The existing DOM parity matrix covers scripting verbs; it is not a complete UI or workflow parity inventory. -3. **Protect the clean-room boundary.** Use documentation and behavioral observation. Do not copy Adobe code, icons, or artwork. +A DOM command being carried does not prove that its GUI surface exists. A row appearing in a menu does not prove that the behavior is complete. Each claim needs a working UI path and evidence. -Until the inventory refresh is complete, this roadmap is the known backlog, not a proof that no other gaps exist. Track detailed phase criteria in [NEXT.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md). +## Current order of work -## Then: finish the visible shell (Phase 22) +| Workstream | State at 2026-11-11 | +|---|---| +| User-visible parity inventory | Complete and published (T26); update it as real behavior lands | +| Phase 22 — CS6 shell fidelity | In progress; panel inventory, tool strip, adaptive context menus and icon pack landed; inspector/chrome follow-ups remain | +| Phase 20 — daily-driver editor workflows | Partially delivered: text editing and multi-document/history/slice workflows on main; Optimize/timeline in PR #118; mask stack in PR #113 | +| Phase 21 — modern additions | User-facing deliverables landed: autosave/recovery, HiDPI, command palette, preferences, accessibility work and scripting | +| Phase 19.6 — menu wiring | Complete: 2 inert of 296 rows; eight explicit feature/evidence gates remain | -This is the current UI priority. The context menu and open-license icon pack are complete; the remaining work is: +## Remaining parity and quality work - +1. **Inspector completeness:** bitmap transform and fill/stroke behavior remain constrained by the document model and recorded decision 0019; do not fake unsupported fields. +2. **CS6 chrome and toolbar:** the main-toolbar contents and remaining presentation details are tracked in Phase 22 and the parity matrix. +3. **Open Phase 20 PRs:** #118 contains the Optimize panel and timeline; #113 contains the mask-stack extension. They are not shipped until merged and verified. +4. **Evidence and regressions:** maintain screenshot/interaction receipts, round-trip and malformed-file tests, undo/redo checks, and the generated DOM and shell-reachability gates. - +## Authoritative references -1. **Panel reachability and layout (22.1):** make active panels usable at normal viewport sizes, finish the documented Optimize, Common Library, CSS Properties, Find and Replace, and Slices surfaces, and verify persistence and movement. -2. **Tool strip and flyouts (22.2):** align tool order, grouping, flyout behavior, and keyboard access with the reference notes. -3. **Property inspector (22.4):** finish per-object fields and close the documented bitmap transform/resample gap (decision 0019); X/Y/W/H remains read-only. Bitmap fill/stroke editing requires a separate format decision because `IMGv` carries no fill or stroke nodes. See the [bitmap evidence](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/research/fw-ui-evidence.md#where-the-bitmap-specific-surface-lives-phase-22-ticket-224). -4. **CS6 chrome (22.5):** review menu, tabs, status area, panel headers, and the overall shell layout. -5. **Screenshot and responsive proof:** capture representative empty, vector, and bitmap states at 1280×800 and 1920×1080; record the build and replace the stale sample only after review. +- [CS6 user-visible parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md) +- [Live task board](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TASKS.md) +- [Detailed phased roadmap](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md) +- [Progress and dated receipts](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md) +- [Generated DOM parity report](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/planning/generated/dom-parity.md) - - -Detailed acceptance criteria are in [Phase 22](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md#phase-22--cs6-shell-fidelity-p0-the-looks-and-acts-like-fireworks-phase); release and gate receipts are in [PROGRESS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md). - -## Next: close daily-driver feature gaps (Phase 20) - -1. **In-canvas text editing (20.1)** -2. **Optimize panel and live export preview (20.2)** -3. **Animation timeline, frame timing, and onion skinning (20.3)** -4. **Mask stack editing (20.4)** -5. **Multi-document tabs (20.5)** -6. **History panel rewind (20.6)** -7. **Slice/hotspot behavior editing and HTML preview (20.7)** - -## Then: add modern capabilities (Phase 21) - -These items extend the discontinued product rather than reproduce a CS6 feature. They should remain clearly labeled as FireCraft additions: - -1. Autosave and crash recovery (21.1) -2. HiDPI rendering and display-scale handling (21.2) -3. Command palette improvements (21.3) -4. Preferences and platform storage (21.4) -5. Accessibility re-audit and supported accesskit surfaces (21.5) -6. In-app scripting access (21.6) - -## Known menu and model gaps - - - - - -- 2 of 296 menu rows are currently inert. Eight additional rows remain feature- or evidence-gated. Clickable `ReportGap` rows, such as printing and document templates, report missing features without implementing them. The inert-row count is not a census of all menu gaps; see the [parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md) for the distinction. The menu wiring campaign is complete; remaining features need implementation or supporting evidence. - - -- The DOM verb matrix has 3 partial, evidence-gated verbs and 85 entries classified as not applicable to the current API surface. See the [generated parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/planning/generated/dom-parity.md). -- For detailed phase criteria and dated validation receipts, use [NEXT.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md) and [PROGRESS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md). +The 2026-11-04 screenshot audit remains a dated capture receipt; it is not evidence that every UI surface or workflow has since been certified. From 83e93bd89f88e35de1757beefbc82a2f08cf355b Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:48:44 -0600 Subject: [PATCH 14/37] docs(wiki): update editor and panel layout guidance --- docs/wiki/Editor-and-Layout.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/wiki/Editor-and-Layout.md b/docs/wiki/Editor-and-Layout.md index 0f22558..32cf8ee 100644 --- a/docs/wiki/Editor-and-Layout.md +++ b/docs/wiki/Editor-and-Layout.md @@ -1,23 +1,19 @@ # Editor and Layout -FireCraft uses one editing model across the browser and desktop shells. The exact set of visible controls is still being brought closer to Fireworks CS6. +FireCraft uses one editing model across its native desktop and WebAssembly shells. The user-visible controls are being aligned with Fireworks CS6 while retaining FireCraft's modern document engine and command registry. ## Canvas and tools -The canvas supports document navigation, object selection, vector editing, bitmap tools, and command-driven edits. See [Usage](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/USAGE.md) for current shortcuts and [Features](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/FEATURES.md) for implemented surfaces. +The canvas supports document navigation, object selection, vector editing, bitmap tools, path and gradient manipulation, transforms, guides, grid, snapping, zoom and selection-aware context menus. The CS6-oriented tool strip and flyout model are implemented. See [Usage](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/USAGE.md) for shortcuts and [Features](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/FEATURES.md) for the current feature surface. ## Panels - +The shell has a persistent, resizable right-side panel dock with a scrolling stack of collapsible panels. The panel inventory includes Properties, Layers, Pages, States, Swatches, Color Mixer, Info, History, Optimize, Symbols, Styles, Common Library, CSS Properties, Auto Shapes, URL, Behaviors, Find and Replace, Slices, and Web Layer. Panels can be toggled from the Window menu; availability and fresh-document defaults are defined in the app. - +The panel inventory and tool strip are implemented, but that does not mean every inspector field is complete. Bitmap transform and fill/stroke behavior remain partial/evidence-gated, and the CS6 chrome/Main toolbar audit still has follow-up work. Optimize/timeline changes are in open [PR #118](https://github.com/aliasfoxkde/FireCraft/pull/118); the mask-stack extension is in [PR #113](https://github.com/aliasfoxkde/FireCraft/pull/113). -The current shell has a left tool area and a resizable right-side dock with a default width of 258 pt, containing a scrolling column of collapsible panel sections. The earlier floating-window layout required very tall captures to see lower panels. [T22](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/tasks/T22-screenshot-ui.md) records all open panels reachable at 1280×800 and working dock scroll at 1280×400. Together with the completed panel inventory in [TASKS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TASKS.md), this supports reachability at ordinary viewport sizes. The newer dock and inventory still need a fresh capture; inspector completeness and the CS6 chrome audit remain separate work. - - - -See the [Parity Roadmap](Parity-Roadmap) and [Phase 22](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md#phase-22--cs6-shell-fidelity-p0-the-looks-and-acts-like-fireworks-phase) for the ordered shell work and visual acceptance criteria. +See the [CS6 parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md), [task board](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TASKS.md), and [Phase 22](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md#phase-22--cs6-shell-fidelity-p0-the-looks-and-acts-like-fireworks-phase) for exact status and evidence. ## Visual references -The tracked [sample screenshot](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/img/app-main.png) is dated and should not be treated as a capture of the latest shell. Clean-room reference notes are in [fw-ui-evidence.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/research/fw-ui-evidence.md). +Repository screenshots are dated build evidence, not guaranteed captures of the latest main. The [T22 screenshot audit](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/tasks/T22-screenshot-ui.md) records tested viewports, states and limitations. Clean-room reference notes are in [fw-ui-evidence.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/research/fw-ui-evidence.md). From 5e7cc50e9247406c25b874abdda67844cac5190f Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:48:46 -0600 Subject: [PATCH 15/37] docs(wiki): clarify current automation and command coverage --- docs/wiki/Automation.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/wiki/Automation.md b/docs/wiki/Automation.md index 25f6bb0..d09fe6f 100644 --- a/docs/wiki/Automation.md +++ b/docs/wiki/Automation.md @@ -1,17 +1,23 @@ # Automation -FireCraft's CLI, script host, GUI, and browser bridge share the command registry. Automation is useful for repeatable edits, batch export, document inspection, and agent-driven workflows. +FireCraft's GUI, CLI, scripting host, journal, MCP server and browser bridge are designed to use the same engine command service. This makes repeatable edits, batch export, document inspection, replay and agent-driven workflows possible without implementing a second document mutation model. -## Command line +## Command coverage -`firecraft-cli` can inspect and convert documents, apply command steps, import/export, batch-process folders, replay scripts, and serve a JSON-lines or MCP interface. See [USAGE.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/USAGE.md) for the complete command list and argument shapes. +The engine currently registers **253 command IDs**. The latest shell-reachability measurement is **164/253 (64.82%)** in the CS6-visible UI. The command palette exposes the full registry; the reachability metric deliberately measures the designed shell surface, not the palette. DOM/API parity is tracked separately at 268 carried / 3 partial / 0 missing of 356 verbs. -## ExtendScript and steps +These figures must not be described as complete GUI parity. The [CS6 user-visible matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md) records menus, tools, panels, inspector fields, workflows and evidence-gated gaps. -The script host runs a supported subset of Fireworks `.jsf` automation in a sandbox. Its exact behavior and gaps are recorded in the [script report](https://github.com/aliasfoxkde/FireCraft/blob/main/corpus/scripts-report.json) and [decision records](https://github.com/aliasfoxkde/FireCraft/tree/main/docs/decisions). +## Command line and scripts + +The native `firecraft-cli` supports document inspection and conversion, imports/exports, command application, batch operations, journal/step replay, and JSON-lines control. The scripting host runs a supported subset of Fireworks `.jsf` automation; the app also replays `.fwsteps` journals. See [USAGE.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/USAGE.md), the [script corpus report](https://github.com/aliasfoxkde/FireCraft/blob/main/corpus/scripts-report.json), and current decisions for exact limits. ## MCP and browser bridge -The CLI MCP server exposes document inspection, command application, undo/redo, export, and command discovery. The browser host accepts the documented `postMessage` protocol. See [WEBOS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS.md) for message details. +The native MCP server exposes document inspection, command application, undo/redo, export and command discovery. The browser host uses a documented `postMessage` bridge. The same command semantics should be preserved across GUI, CLI, MCP, and the future WebOS SDK adapter; browser apps use a host bridge, not an in-browser TCP listener. + +- [Browser/WebOS protocol](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS.md) +- [FireCraft platform integration and SDK direction](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS-PLATFORM-INTEGRATION.md) +- [Automation usage guide](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/USAGE.md) -Automation coverage does not imply that every operation has an equivalent polished GUI control. The [Parity Roadmap](Parity-Roadmap) tracks the shell work separately. +Automation coverage does not imply that every operation has an equivalent polished menu, panel or inspector workflow. From 429e6fd79841a3d6567862257299238523432a56 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:48:52 -0600 Subject: [PATCH 16/37] docs(wiki): distinguish standalone web and host integration --- docs/wiki/Browser-and-WebOS.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/wiki/Browser-and-WebOS.md b/docs/wiki/Browser-and-WebOS.md index 7ef1f9e..33122dd 100644 --- a/docs/wiki/Browser-and-WebOS.md +++ b/docs/wiki/Browser-and-WebOS.md @@ -1,13 +1,15 @@ # Browser and WebOS -## Browser app +## Standalone browser application -FireCraft's web shell runs as WebAssembly. Open the [hosted web app](https://firecraft-web.pages.dev) over HTTPS; browser file access and downloads go through the host UI. The deployed artifact can differ from the latest source build, so check [Project Status](Project-Status) before relying on its version. +FireCraft's web shell runs as WebAssembly and is independently usable over HTTPS. Browser file access and downloads go through the host UI. The deployed build is versioned separately from the latest source commit; see [Project Status](Project-Status) and [release notes](https://github.com/aliasfoxkde/FireCraft/tree/main/docs/releases). -## Embedding +## Embedding and host integration -The host uses an iframe-friendly canvas and a `postMessage` bridge for opening documents, applying commands, and exporting results. The authoritative message schema and host requirements are in [WEBOS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS.md). +The current host contract uses an iframe-friendly canvas and a `postMessage` bridge for document opening, command application, liveness checks and export. The canonical message schema and host requirements are in [WEBOS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS.md). + +FireCraft is both a standalone product and an embeddable application component. WebOS is one integration target, not a runtime requirement. The longer-term versioned command/capability SDK and shared-library strategy are described in [WEBOS-PLATFORM-INTEGRATION.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS-PLATFORM-INTEGRATION.md) and [RELEASE-ENGINEERING-PLAN.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/RELEASE-ENGINEERING-PLAN.md). ## Building locally -Use the repository's `xtask dist --web` workflow to build the optimized bundle and run the bridge smoke. Keep `wasm32-unknown-unknown` dependencies browser-safe. Full commands and the release recipe are in [TOOLCHAINS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TOOLCHAINS.md) and [RELEASING.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/RELEASING.md). +Use `cargo run -p xtask -- dist --web` to build the optimized bundle and run the bridge smoke. Keep `wasm32-unknown-unknown` dependencies browser-safe. Full commands and release evidence rules are in [TOOLCHAINS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TOOLCHAINS.md) and [RELEASING.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/RELEASING.md). From e46a5b6582a5df27bdd3663358da3293def4275c Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:48:55 -0600 Subject: [PATCH 17/37] docs(wiki): refresh release and build guidance --- docs/wiki/Getting-Started.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/wiki/Getting-Started.md b/docs/wiki/Getting-Started.md index 08610c1..a5b615b 100644 --- a/docs/wiki/Getting-Started.md +++ b/docs/wiki/Getting-Started.md @@ -2,9 +2,9 @@ ## Choose a way to use FireCraft -- **Browser:** open the [FireCraft web app](https://firecraft-web.pages.dev). Its deployed build can differ from the current source; check [Project Status](Project-Status) for the latest manifest comparison. -- **Desktop:** build the `app` workspace package on a supported native system. Platform build requirements are in [TOOLCHAINS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TOOLCHAINS.md). -- **Command line:** build or install `firecraft-cli` to inspect, convert, import, export, batch-process, or script documents. +- **Browser:** open the [FireCraft web app](https://firecraft-web.pages.dev). The latest published release is v0.2.5; current `main` may contain newer work not yet published. +- **Desktop:** the current published native release includes Linux x86_64 desktop and CLI archives plus a Debian package. Other packaging scripts are not proof of a published, tested binary. Check [Release Status](Project-Status) before selecting a platform. +- **Command line:** build or install `firecraft-cli` to inspect, convert, import, export, batch-process or script documents. ## First commands @@ -15,8 +15,8 @@ cargo run -p firecraft-cli -- convert input.fw.png output.fw.png cargo run -p firecraft-cli -- export input.fw.png output.webp ``` -These examples assume a Rust workspace checkout. See the full [Usage Guide](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/USAGE.md) for imports, GUI shortcuts, and release builds. +These examples assume a Rust workspace checkout. See the full [Usage Guide](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/USAGE.md) for imports, GUI shortcuts and release builds. ## Learn the editor -Continue to [Editor and Layout](Editor-and-Layout) for the canvas, tools, panels, and known layout gaps. For file support, see [Documents and Formats](Documents-and-Formats). +Continue to [Editor and Layout](Editor-and-Layout) for the canvas, tools, panels and current parity gaps. For file support, see [Documents and Formats](Documents-and-Formats); for CLI/MCP and scripting, see [Automation](Automation). From de6af827af906353cbadf3fbc8b56aa88db899fe Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:48:58 -0600 Subject: [PATCH 18/37] docs(wiki): add platform adapter and SDK architecture --- docs/wiki/Architecture.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/wiki/Architecture.md b/docs/wiki/Architecture.md index 3eb7729..993b29a 100644 --- a/docs/wiki/Architecture.md +++ b/docs/wiki/Architecture.md @@ -1,30 +1,28 @@ # Architecture -FireCraft is a Rust workspace with a shared document model and command engine behind desktop, browser, CLI, scripting, and MCP surfaces. +FireCraft is a Rust workspace with a shared document model and command engine behind desktop, browser, CLI, scripting and MCP surfaces. ## Dependency layers - - - - | Layer | Crates | Responsibility | |---|---|---| | L0 | `fwpng`, `geom`, `color`, `raster` | Format primitives, geometry, color, tile storage | | L1 | `doc` | Editable document model | | L2 | `vector`, `filters`, `text`, `ops` | Feature engines | | L3 | `compose`, `gpu`, `engine` | Rendering and command orchestration | -| L4 | `io`, `scripting`, `webexport` | Import/export codecs, scripting runtime, and web export | +| L4 | `io`, `scripting`, `webexport` | Import/export codecs, scripting runtime and web export | | L5 | `app`, `app-cli`, `automation`, `firecraft-web` | User and automation shells | | L6–L7 | `testkit`, `xtask` | Test support and verification tooling | - - -The enforced source is [`xtask/src/layers.rs`](https://github.com/aliasfoxkde/FireCraft/blob/main/xtask/src/layers.rs); see [PLANNING.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PLANNING.md) for the complete architecture and decisions. +The enforced dependency graph is [xtask/src/layers.rs](https://github.com/aliasfoxkde/FireCraft/blob/main/xtask/src/layers.rs). See [PLANNING.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PLANNING.md) for the complete architecture. ## Editing model -Mutations flow through the engine command registry and journal. GUI, CLI, script, and bridge surfaces call the same commands, keeping undo, refusal behavior, and document changes consistent. +Mutations flow through the engine command registry and journal. GUI, CLI, script and bridge surfaces call the same commands, keeping undo, refusal behavior and document changes consistent. + +## Platform and shared SDK direction + +Keep FireCraft-owned document semantics, format compatibility and product UX in this repository. Reusable mechanisms may be adopted from [storytold/craft-libs](https://github.com/storytold/craft-libs) only after API/target compatibility and measured benefit are established. The planned SDK uses versioned command/capability schemas and native, browser, CLI/MCP and WebOS adapters over the same command service. See the [platform integration plan](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS-PLATFORM-INTEGRATION.md). ## Rendering From 2637649d6a6ddf981cceb875d8e5d6c2c798c555 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:49:01 -0600 Subject: [PATCH 19/37] docs(wiki): update contribution path and integration rules --- docs/wiki/Contributing.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/wiki/Contributing.md b/docs/wiki/Contributing.md index 982f3f7..60619de 100644 --- a/docs/wiki/Contributing.md +++ b/docs/wiki/Contributing.md @@ -2,19 +2,22 @@ ## Before changing code -1. Read [`AGENTS.md`](https://github.com/aliasfoxkde/FireCraft/blob/main/AGENTS.md) for project rules and the clean-room boundary. -2. Check the [parity roadmap](Parity-Roadmap) and the detailed project plan in [NEXT.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md). -3. Read the relevant [decision](https://github.com/aliasfoxkde/FireCraft/tree/main/docs/decisions), source module, and research note before adding a new model or command. +1. Read [AGENTS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/AGENTS.md) for project rules and the clean-room boundary. +2. Check the live [task board](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TASKS.md), [CS6 parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md), and detailed [roadmap](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md). +3. Read the relevant decision, source module, research note and tests before adding a new model or command. +4. Check existing PRs and issues first; do not start a duplicate audit or a competing implementation of work already in review. ## Engineering rules -- Keep the crate dependency layers valid; register new workspace crates in `xtask/src/layers.rs`. -- Treat file dimensions, lengths, counts, and strings as hostile input; cap proportional allocations and return typed errors. +- Keep crate dependency layers valid; register new workspace crates in `xtask/src/layers.rs`. +- Treat file dimensions, lengths, counts and strings as hostile input; cap proportional allocations and return typed errors. - No unsafe code or panic-based handling of untrusted files in production code. -- Grow the fuzz anchors whenever adding a hostile-input surface. -- Do not commit `source/`, Adobe-derived scratch extracts, or generated `dist/` artifacts. +- Grow fuzz anchors whenever adding a hostile-input surface. +- Do not commit `source/`, Adobe-derived scratch extracts or generated `dist/` artifacts. - Add asset attribution in the same change as any new asset. +- Keep FireCraft standalone; integrations and the future SDK are optional consumers, not product prerequisites. +- Adopt shared crates/workflows only after checking licenses, target compatibility, feature footprint and measurable benefit. ## Validate and close out -Use the gates in [`AGENTS.md`](https://github.com/aliasfoxkde/FireCraft/blob/main/AGENTS.md). Update the task ticket, task board, generated status where needed, and session notes. Any shell or web change requires a real browser check before it is treated as complete. +Use the gates in [AGENTS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/AGENTS.md). Run focused tests during iteration and the full gate at integration/release boundaries; avoid duplicate full builds on an unchanged tree. Update the task ticket, live ledger, generated status where applicable and session notes. Any shell/web change requires a real browser check before it is treated as complete. From bd5f262a8e1a180e5f59d00eb2d02f5b1c277409 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:49:04 -0600 Subject: [PATCH 20/37] docs(wiki): add current release and SDK references --- docs/wiki/Technical-References.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/wiki/Technical-References.md b/docs/wiki/Technical-References.md index 9ee6a03..26bbcfc 100644 --- a/docs/wiki/Technical-References.md +++ b/docs/wiki/Technical-References.md @@ -7,9 +7,11 @@ Use these references when the overview pages are not specific enough: - [UI evidence notes](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/research/fw-ui-evidence.md) - [Code research notes](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/research/fw-code-notes.md) - [Decision records](https://github.com/aliasfoxkde/FireCraft/tree/main/docs/decisions) -- [DOM parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/planning/generated/dom-parity.md) -- [Generated parity floors](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/planning/generated/parity.md) -- [Scorecard](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/planning/generated/scorecard.md) -- [Release and platform matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TOOLCHAINS.md) +- [User-visible CS6 parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md) +- [Generated DOM parity matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/planning/generated/dom-parity.md) +- [Generated parity floors and scorecard](https://github.com/aliasfoxkde/FireCraft/tree/main/docs/planning/generated) +- [Cross-platform release engineering and artifact matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/RELEASE-ENGINEERING-PLAN.md) +- [WebOS integration and SDK contract](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS-PLATFORM-INTEGRATION.md) +- [Progress and build/deployment receipts](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md) -Generated reports may lag source until their generator runs. Check the generation note at the top of each report before using a count as current. +Generated reports may lag source until their generator runs. Check each report's generation note before using a count as current. From fdf1997e26eb58b7f4921381ac1b2044946401d5 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:49:07 -0600 Subject: [PATCH 21/37] docs(wiki): add distribution SDK and current navigation --- docs/wiki/Home.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md index 0ba584e..ce7c501 100644 --- a/docs/wiki/Home.md +++ b/docs/wiki/Home.md @@ -1,17 +1,18 @@ # FireCraft Wiki -FireCraft is a clean-room Rust editor for Fireworks-style `.fw.png` documents. This wiki is organized by what you want to do; the repository docs contain the detailed, versioned specifications. +FireCraft is an independent, clean-room Rust editor for Fireworks-style `.fw.png` documents. It combines vector and bitmap editing with CLI, scripting, MCP and browser-host integration. The repository docs contain the detailed, versioned specifications and current evidence. ## Start here | If you want to… | Start with | |---|---| | Try the editor | [Getting Started](Getting-Started) | -| Learn what is implemented and what is still missing | [Parity Roadmap](Parity-Roadmap) | -| Find tools, panels, and layout guidance | [Editor and Layout](Editor-and-Layout) | -| Open, import, or export a file | [Documents and Formats](Documents-and-Formats) | +| Learn what is implemented and what remains | [Parity Roadmap](Parity-Roadmap) | +| Find tools, panels and layout guidance | [Editor and Layout](Editor-and-Layout) | +| Open, import or export a file | [Documents and Formats](Documents-and-Formats) | | Automate editing | [Automation](Automation) | | Embed the web build | [Browser and WebOS](Browser-and-WebOS) | +| Understand releases and SDK/integration artifacts | [Distribution and SDK](Distribution-and-SDK) | | Contribute or use an AI coding agent | [Contributing](Contributing) | ## Browse by topic @@ -22,6 +23,6 @@ FireCraft is a clean-room Rust editor for Fireworks-style `.fw.png` documents. T ## How to read the roadmap -The [Parity Roadmap](Parity-Roadmap) separates unfinished Fireworks CS6 behavior and presentation from newer FireCraft additions. It is an ordered summary of the known work, not a claim that every undocumented CS6 behavior has been inventoried. For the detailed phase plan and dated receipts, see [NEXT.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/NEXT.md) and [PROGRESS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md). +The [Parity Roadmap](Parity-Roadmap) separates unfinished Fireworks CS6 behavior and presentation from newer FireCraft additions. The [CS6-PARITY.md matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/CS6-PARITY.md) is the detailed user-visible inventory; the generated DOM report measures scripting/API verbs and is not a substitute for GUI parity. See [TASKS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TASKS.md) and [PROGRESS.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/PROGRESS.md) for current status. > **Clean-room boundary:** FireCraft is independent of Adobe. Its behavior references documentation and observation; Adobe source code and artwork are not included. From 3079cdede688a1339b48f85db2c49b48ac7763cd Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:49:18 -0600 Subject: [PATCH 22/37] docs(wiki): add SDK and distribution navigation --- docs/wiki/_Sidebar.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/wiki/_Sidebar.md b/docs/wiki/_Sidebar.md index 33950ee..89182e7 100644 --- a/docs/wiki/_Sidebar.md +++ b/docs/wiki/_Sidebar.md @@ -11,6 +11,7 @@ * [Documents and Formats](Documents-and-Formats) * [Automation](Automation) * [Browser and WebOS](Browser-and-WebOS) +* [Distribution and SDK](Distribution-and-SDK) * [Troubleshooting](Troubleshooting) **DEVELOPING FIRECRAFT** From 2b3a2a724ff14abceb102b8b8a0b6917eb1862a2 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:49:31 -0600 Subject: [PATCH 23/37] docs(wiki): document standalone distribution and SDK strategy --- docs/wiki/Distribution-and-SDK.md | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docs/wiki/Distribution-and-SDK.md diff --git a/docs/wiki/Distribution-and-SDK.md b/docs/wiki/Distribution-and-SDK.md new file mode 100644 index 0000000..d7589df --- /dev/null +++ b/docs/wiki/Distribution-and-SDK.md @@ -0,0 +1,45 @@ +# Distribution and SDK + +FireCraft has two complementary purposes: + +1. A complete, independent graphics editor people can install and use without another product. +2. A reusable creative/automation component that other applications and operating environments can package, embed or orchestrate. + +Prebuilt artifacts serve both purposes. Embedding in ArtCraft WebOS is one use case, not the reason FireCraft has a release matrix. + +## Standalone product distribution + +The latest published release is v0.2.5. Its verified published set includes Linux x86_64 desktop and CLI archives, a Debian package and the WebAssembly/web bundle. Other packaging recipes are not stable binaries until built, installed, launched and functionally tested on the target platform. + +The long-term target matrix includes Windows (x64/ARM64 subject to native verification), macOS (universal or architecture-specific DMG), Linux DEB/RPM/AppImage/Flatpak/Arch/tar.gz, BSD, browser/PWA, CLI/MCP, source and SDK distributions. Android and other mobile targets remain native-feasibility workstreams. Every asset needs a build receipt and target-native verification; a recipe or cross-compile is not a support claim. + +## Developer and embedding distribution + +The planned FireCraft SDK should expose a stable facade over the existing command registry and document engine: + +- Rust API for native applications and plugins. +- Versioned language-neutral schemas for app identity, commands, parameters, results, capabilities, errors and lifecycle. +- WASM module plus browser host bridge/client for web products. +- Native CLI and MCP adapters that invoke the same command service. +- Examples, API documentation, compatibility manifest, licenses, checksums, SBOM and provenance for released SDK components. + +The SDK must remain usable by third-party hosts. WebOS is a primary integration consumer and conformance target, not a runtime dependency. FireCraft's document model, Fireworks compatibility rules, editor UX and product policy remain owned by FireCraft. + +## Shared ArtCraft foundation + +Evaluate the existing ecosystem rather than recreating its useful mechanisms: + +- [craft-libs](https://github.com/storytold/craft-libs) — Rust libraries and the candidate extraction process. +- [craft-common-actions](https://github.com/storytold/craft-common-actions) — reusable CI, packaging lint and cross-platform release automation. +- [artcraft-candidates](https://github.com/artcraft-candidates) — community proving ground for testing compatibility without transferring ownership of the canonical FireCraft repository. + +Adoption is selective: confirm target compatibility, license, feature footprint and real benefit; keep app-specific checks; contribute reusable fixes upstream. See [RELEASE-ENGINEERING-PLAN.md §3.7, §5.3 and RP-09](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/RELEASE-ENGINEERING-PLAN.md) and [WEBOS-PLATFORM-INTEGRATION.md](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/WEBOS-PLATFORM-INTEGRATION.md). + +## Release evidence and current limits + +- [Release plan and artifact matrix](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/RELEASE-ENGINEERING-PLAN.md) +- [Current artifact receipts](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/release/ARTIFACT-MATRIX.md) +- [Release checklist](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/RELEASING.md) +- [Toolchain and packaging recipes](https://github.com/aliasfoxkde/FireCraft/blob/main/docs/TOOLCHAINS.md) + +Support status is per artifact: Stable, Preview/Community or Planned/Unsupported. Never infer Windows/macOS/Flatpak/Android support from a script alone. From 7ac6e79efe1a91a9abacda9f1735654bdecfb507 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:55:27 -0600 Subject: [PATCH 24/37] docs(handoff): align web verification and release runbooks --- docs/HANDOFF.md | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 8b5b96b..70e19db 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -283,10 +283,11 @@ touching `web/` or the smoke.** ### Suggested order -**Current front:** Phase 22 shell fidelity and the screenshot-driven -responsive audit. After that, take queued Phase 20/21 work from -[`TASKS.md`](TASKS.md). Phase 19 and 19b are complete. Re-verify the -browser path after any `web/` change (§6.2). +**Current front:** complete the open Phase 20 PRs (#118 Optimize/timeline; +#113 mask-stack extension), then close the remaining Phase 22 inspector and +chrome gaps with evidence. Phase 21's user-facing deliverables and Phase 19/19b +are landed. Check [`TASKS.md`](TASKS.md) before selecting work; do not restart +completed phases. Re-verify the browser path after any `web/` or shell change (§6.2). ## 5. Parity-matrix regeneration recipe @@ -382,9 +383,14 @@ Phase 10 defects passed every desktop gate. The working pattern `corpus/fixtures/` proves the menu open; `expect_download` proves save. Check `pageerror` after every step (`unreachable` = a wasm panic). -3. Redeploy Pages and repeat step 2 against the live URL — check the - served `MANIFEST.sha256` hash matches `dist/web` before - diagnosing anything (edge propagation lags a few minutes). +3. For the live site, compare the served JavaScript, Wasm and `appinfo.json` + with the tagged release manifest first. Cloudflare Pages injects an + analytics beacon into served `index.html`/`host.html`; those HTML digests + therefore differ from the pre-deploy bundle even when the executable + assets match. This exact discrepancy was reconciled by #104 on + 2026-11-11. Do not call the deployment an unknown revision based only + on the injected HTML. Record the release source SHA, JS/Wasm hashes, + appinfo hash and cache state; then repeat the bridge and file handoff smoke. ### 6.3 Release + deploy doors @@ -397,15 +403,20 @@ Phase 10 defects passed every desktop gate. The working pattern cli tar.gz, deb, MANIFEST.sha256 → `dist/native/`) and `dist --web`. Web zip is manual, files at root: `cd dist/web && zip -qr ../firecraft-web-.zip .` -- **Publish:** tag, `git push gitforge main --tags`, `git push origin - main --tags`, `gh release create vX.Y.Z --notes-file - docs/releases/vX.Y.Z.md <5 assets>`. GitForge has no release-asset - surface (tags only); GitHub carries the assets. The release notes are - tracked in `docs/releases/` (13.3, closed) — `dist/release-notes.txt` - is gitignored staging and can be stale; do not ship it. -- **Pages:** `wrangler pages deploy dist/web --project-name - firecraft-web` (authenticated via `CLOUDFLARE_API_TOKEN`; - , direct-upload project). +- **Tag/release:** follow [RELEASING.md](RELEASING.md). The tag-triggered + GitHub Actions workflow builds native Linux, WebAssembly, source, SBOM, + checksums and the release manifest, validates the aggregate, and creates + a **draft** GitHub Release. Inspect the draft and all receipts; publication + remains an explicit operator action. Do not create a second manual release + with `gh release create` for the same tag. GitForge carries Git refs/tags, + not release assets. Release notes are tracked in `docs/releases/`; + `dist/release-notes.txt` is gitignored staging and can be stale. +- **Pages:** deployment remains manual and is not part of the current tag + workflow: `wrangler pages deploy dist/web --project-name firecraft-web` + (authenticated via `CLOUDFLARE_API_TOKEN`; direct-upload project). Deploy + the exact `dist/web` from the release build and reconcile served JS/Wasm/ + appinfo against the release manifest. Account for Cloudflare's injected + analytics beacon in served HTML (T18/#104). ## 7. Session-close checklist From e2243bba494132fa884baeb9b4ed3be2fc0a1da2 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:56:54 -0600 Subject: [PATCH 25/37] docs(parity): refresh landed Phase 20 evidence and open work --- docs/CS6-PARITY.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/CS6-PARITY.md b/docs/CS6-PARITY.md index db0c508..7222e6d 100644 --- a/docs/CS6-PARITY.md +++ b/docs/CS6-PARITY.md @@ -150,7 +150,7 @@ Eighteen have a Window-menu row; five do not. | Pages (35798) | panel; page list, click selects | **implemented** | `S/panels.rs::pages_section` | — | | States (43410, `cmd_Panels_Frames`) | panel; state list | **implemented** | `S/panels.rs::states_section` | — | | Layers (43412) | panel; name, eye, lock, reorder | **implemented** | `S/panels.rs::layers_section` | — | -| History (43418) | panel; journal rows, Save Steps / Replay | **implemented** | `S/panels.rs::history_section` | 20.6 | +| History (43418) | panel; journal rows, click-to-rewind, Save Steps / Replay | **implemented** — click-to-rewind landed on main 2026-11-11 in #107 | `S/panels.rs::history_section` | 20.6 | | Styles (43415) | panel; style rows, New From Selection, Import | **implemented** | `S/panels.rs::styles_panel` | — | | Document Library (43416, `cmd_Panels_SymLibrary`) | panel; symbol rows, enter/exit symbol | **implemented** | `S/panels.rs::library_panel` | — | | Color Mixer (43405) | panel; fill/stroke pickers + gradient editor | **implemented** | `S/panels.rs::fill_stroke_panel`, `S/panels.rs::gradient_editor_section` | — | @@ -160,11 +160,11 @@ Eighteen have a Window-menu row; five do not. | URL (43414, `cmd_Panels_URLMgr`) | panel; link + alt text, Apply | **implemented** | `S/panels_web.rs::url_panel` | — | | Behaviors (43413) | panel; list, Add menu, Add swap image | **implemented** | `S/panels_web.rs::behaviors_panel` | — | | Tools (35058, `cmd_Toolbars_Art`) | the left tool strip | **implemented** | `S/canvas_ui.rs::tools_panel` | 22.2 | -| **Optimize** (43409, `cmd_Panels_ExportPanel`) | panel; the page's export settings (`EXPv`: format, JPEG quality/progressive, dither, GIF loop, interlace) with an Apply | **implemented** — landed 2026-11-06 | `S/panels.rs::optimize_panel`, `M` id 43409 | — | +| **Optimize** (43409, `cmd_Panels_ExportPanel`) | panel; page export settings (`EXPv`) and preview | **implemented** — base panel landed 2026-11-06; full encoder-backed settings, format-aware clearing and preview are in open PR #118, not on main | `S/panels.rs::optimize_panel`, `M` id 43409 | 20.2 / PR #118 | | **Common Library** (45816) | panel; lists the document's own symbols (drag-to-place like Document Library) | **partial** — CS6's *shipped* libraries are proprietary resources and are deliberately not copied; the panel says so | `S/panels_web.rs::common_library_panel`, `M` id 45816 | 22.1 | | **CSS Properties** (49125) | panel; the selected slice's generated CSS, read-only | **partial** — CS6 edits properties here; FireCraft's edit surfaces are the slice verbs | `S/panels_web.rs::css_properties_panel`, `M` id 49125 | 22.1 | | **Find and Replace** (43402, `cmd_PanelFind`) | panel; find over text objects with per-match replace / replace-all (`text.setText`) | **implemented** — landed 2026-11-06 | `S/panels_web.rs::find_replace_panel`, `M` id 43402 | — | -| **Slices** | panel; the slice list with kind, link and export override, click-to-select | **implemented** — landed 2026-11-06 (CS6's tree also lists hotspots as first-class rows; FireCraft's hotspots ride the URL/Behaviors panels) | `S/panels_web.rs::slices_panel` | 20.7 | +| **Slices** | panel; slice list with kind, link, export override and click-to-select; hotspot behavior editing and HTML preview | **implemented** — panel landed 2026-11-06; behavior editor and HTML preview landed on main 2026-11-11 in #107 | `S/panels_web.rs::slices_panel` | 20.7 | | **Project** (43403, `cmd_PanelProject`) | none | **missing** | **R** | 22.1 | | **Site** (43420, `cmd_Panels_Site`) | none | **missing** | **R** | 22.1 | | **Answers** (43421, `cmd_Panels_Answers`) | none | **not applicable** — CS6 opens it from the Help menu as a web panel | **R** | — | @@ -222,7 +222,7 @@ dispatches at `S/panels.rs::properties_panel`. | Open Recent | one inert-ish row that reports the gap | **missing** (documented refusal) | `M` (File ▸ Open Recent) | — | | Export Wizard | present | **implemented** | `M` id 35181 | — | | Batch Process | reports the gap | **missing** (documented refusal) | `M` id 35302 | — | -| **Multi-document tabs** | open a second document parks the first in a tab strip; Close promotes the last parked tab, dirty documents refuse to close silently, the strip folds away in Full Screen (**20.5, landed 2026-11-07**) | **implemented** | `M` id 57648, `S/mod.rs::activate_tab` | — | +| **Multi-document tabs** | open a second document parks the first in a tab strip; Close promotes the last parked tab, dirty documents refuse to close silently, the strip folds away in Full Screen (**20.5, landed on main 2026-11-11 in #107**) | **implemented** | `M` id 57648, `S/mod.rs::activate_tab` | — | | Print / Page Setup | report the gap (no printing) | **not applicable** — FireCraft has no printing story | `M` id 57605, id 57607 | — | | **Autosave / crash recovery** | web: whole-document localStorage persistence with boot restore; desktop: journal sidecar snapshot with a Recover/Discard offer, undo intact across the boundary (**21.1, landed 2026-11-07**) | **implemented** | `S/mod.rs::check_recovery`, `S/mod.rs::recovery_ui` | — | | **Preferences dialog** | Edit ▸ Preferences… opens a real dialog (UI scale, persisted in `ShellLayout`) (**21.4, landed 2026-11-07**) | **implemented** | `M` id 35034, `S/panels.rs::preferences_ui` | — | @@ -331,10 +331,10 @@ acceptance hook. Ordered by how much of the product it unlocks. | 3 | The right dock's five-tab-group structure and the bottom Properties dock — the **panel inventory landed 2026-11-06** (18 panels in CS6's order, collapse/close headers, scrolling column); what is left is the *structure*: CS6 stacks them as five tab-groups with Properties in the bottom dock, FireCraft runs one flat column | C | 22.1 | P0 | | 4 | ~~In-canvas text editing~~ **CLOSED 2026-11-06** — double-click edits in place: `TextEdit` overlay on the text frame, commit/cancel/focus routing (§G) | E, H, I | 20.1 | — | | 5 | The CS6 tool strip's remaining items: the 3D tool (the screen-mode cycle and the Alt-hold variants **landed 2026-11-06**) | B | 22.5 | P2 | -| 6 | ~~Multi-document tabs~~ **CLOSED 2026-11-07** — park on Open/New, Close promotes the last tab, dirty dots, the strip folds in Full Screen (§E) | E | 20.5 | — | -| 7 | The animation timeline (States panel) | C | 20.3 | P1 | -| 8 | History click-to-rewind | C, E | 20.6 | P1 | -| 9 | Slice/hotspot behaviour editing and the HTML preview surface | C, F, I | 20.7 | P1 | +| 6 | ~~Multi-document tabs~~ **CLOSED — landed on main 2026-11-11 in #107** — park on Open/New, Close promotes the last tab, dirty dots, the strip folds in Full Screen (§E) | E | 20.5 | — | +| 7 | The animation timeline (States panel) — **open PR #118; not yet on main** | C | 20.3 | P1 | +| 8 | ~~History click-to-rewind~~ **CLOSED — landed on main 2026-11-11 in #107**; command-palette/MCP discoverability refinement remains in PR #122 | C, E | 20.6 | — | +| 9 | ~~Slice/hotspot behaviour editing and HTML preview~~ **CLOSED — landed on main 2026-11-11 in #107** | C, F, I | 20.7 | — | | 10 | Autosave and crash recovery — **LANDED 2026-11-07** — web: whole-document localStorage persistence with boot restore; desktop: journal sidecar snapshot with Recover/Discard prompt, undo intact across the crash boundary | E | 21.1 | P1 | | 11 | The Keyboard Shortcuts editor and the four alternative keymaps — the **Preferences dialog CLOSED 2026-11-07** (§E) | E, H | 21.4 | P1 | | 12 | The in-app script console and saved commands — **LANDED 2026-11-07**: Commands ▸ Run Script runs `.jsf` (scripting host, landed with automation) and `.fwsteps` (journal replay onto the live document); CS6's broader extension installer remains a recorded gap | A, E | 21.6 | P1 | @@ -342,7 +342,7 @@ acceptance hook. Ordered by how much of the product it unlocks. | 14 | ~~The Text ▸ Font submenu, *Repeat Filter*, the F1 grouping mismatch~~ **CLOSED 2026-11-06** — Font dispatches `text.setFont` over the renderer's five families (`RT_MENU` 128 ships a runtime-populated placeholder; the static list is the substitute, recorded as the evidence gap); Repeat Filter re-applies the session's last preset; the F1 groups now tile the table exactly, each binding carrying its own section (`menus::Shortcut.group`, gate `menus::tests::shortcut_sections_are_contiguous`). | A, H | — | — | | 15 | ~~The Window menu's window-arrangement rows~~ **CLOSED 2026-11-06** — the trio (57650/57651/57652) is transcribed with CS6's labels (see §A) | A | — | — | | 16 | ~~HiDPI `pixels_per_point` rendering~~ **CLOSED 2026-11-07** — the canvas raster renders at zoom × pixels_per_point under the 16 MiPix budget; the canvas is crisp on hidpi displays at any zoom | — | 21.2 | P2 | -| 17 | accesskit desktop + web re-audit | H | 21.5 | P2 | +| 17 | ~~accesskit desktop + web re-audit~~ **CLOSED — re-audit landed 2026-11-11 in #107; web-canvas screen-reader limitation remains explicitly documented in decision 0067** | H | 21.5 | — | ## L. Verification performed for this matrix From 95801f57ffa87ef2fdfe71b94e942947c0e34da4 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:56:58 -0600 Subject: [PATCH 26/37] docs(ledger): clarify Phase 20 panel completion and PR scope --- docs/TASKS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/TASKS.md b/docs/TASKS.md index 0a94478..a5f8fd1 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -69,9 +69,9 @@ | # | Task | Ticket | |---|---|---| -| 7 | 20.2 Optimize panel | [tasks/T7-optimize-panel.md](tasks/T7-optimize-panel.md) | PR #118 (open; not on main) | +| 7 | 20.2 Optimize panel export-settings/preview completion | [tasks/T7-optimize-panel.md](tasks/T7-optimize-panel.md) | PR #118 (open; base panel already exists) | | 8 | 20.3 Animation timeline | [tasks/T8-animation-timeline.md](tasks/T8-animation-timeline.md) | PR #118 (open; not on main) | -| — | 20.4 Mask stack UI | [decision 0093](decisions/0093-mask-stack-levels-and-folding.md) | PR #113 (open; not on main) | +| — | 20.4 Mask stack UI | [PR #113](https://github.com/aliasfoxkde/FireCraft/pull/113) | Open; not on main; requires diff reduction/review and merge-conflict resolution | 20.1 and 20.5–20.7 are already on `main`; do not reopen them. From dbdd34f2f87a6cfe3f6c96f11b93a8ae7481d4fe Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:57:31 -0600 Subject: [PATCH 27/37] docs(ledger): qualify mask-stack PR mergeability status --- docs/TASKS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/TASKS.md b/docs/TASKS.md index a5f8fd1..6fef914 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -71,7 +71,7 @@ |---|---|---| | 7 | 20.2 Optimize panel export-settings/preview completion | [tasks/T7-optimize-panel.md](tasks/T7-optimize-panel.md) | PR #118 (open; base panel already exists) | | 8 | 20.3 Animation timeline | [tasks/T8-animation-timeline.md](tasks/T8-animation-timeline.md) | PR #118 (open; not on main) | -| — | 20.4 Mask stack UI | [PR #113](https://github.com/aliasfoxkde/FireCraft/pull/113) | Open; not on main; requires diff reduction/review and merge-conflict resolution | +| — | 20.4 Mask stack UI | [PR #113](https://github.com/aliasfoxkde/FireCraft/pull/113) | Open; not on main; reports `mergeable: false`; diagnose whether conflicts or review state are blocking and consider splitting the model/persistence, compositor and UI/test layers | 20.1 and 20.5–20.7 are already on `main`; do not reopen them. From 4d98aaa6322454932983bcd16cc65aaabe7c6c21 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 11:57:34 -0600 Subject: [PATCH 28/37] docs(wiki): clarify open Optimize panel work From a3fe33bb8900ea871c65f1355c4617ee157f95be Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Wed, 11 Nov 2026 13:14:24 -0600 Subject: [PATCH 29/37] fix(aegis): adjudicate the wiki's GraphQL-batch prose finding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gate failed on one finding: graphql-batch-limit at docs/wiki/Automation.md:13. The rule fires when a bulk-operation word and a bound word share a line, and that sentence ("batch operations ... for exact limits") is prose about the CLI's automation surface. FireCraft serves no GraphQL endpoint, so the missing depth guard the rule reports does not exist here. The occurrence is adjudicated as a false positive: a class note records the reason next to the rows it covers, and the baseline gains the two content keys (the wiki line, and the gate's own class-name literal, which carries rows like every other class). The rule stays armed — a new literal, a new file, or an extra copy of a known literal still fails the gate. Verified on this tree: `xtask aegis` passes (0 uncovered findings), `cargo fmt --all -- --check` clean, `cargo clippy -p xtask --all-targets -- -D warnings` clean. Co-Authored-By: Claude Code --- .aegis-baseline.tsv | 7 +++++++ xtask/src/aegis.rs | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/.aegis-baseline.tsv b/.aegis-baseline.tsv index d28ba0c..95218c1 100644 --- a/.aegis-baseline.tsv +++ b/.aegis-baseline.tsv @@ -91,6 +91,13 @@ gdpr-reference ./docs/release/EXECUTION-BOARD.md 8b16477e3abe1de345a6e82f360db77 gdpr-reference ./docs/tasks/T27-11-reproduce-aegis-gate-failure.md 8b16477e3abe1de345a6e82f360db77b5e238983ad685cec9fef0d0bc009aed3 1 gdpr-reference ./docs/tasks/T27-12-adjudicate-aegis-findings.md 8b16477e3abe1de345a6e82f360db77b5e238983ad685cec9fef0d0bc009aed3 7 gdpr-reference ./xtask/src/aegis.rs 8b16477e3abe1de345a6e82f360db77b5e238983ad685cec9fef0d0bc009aed3 2 +# Fires on English prose where a bulk-operation word and a bound word +# share one line: the automation wiki's sentence about the CLI's bulk +# work and the bounds it reports. FireCraft serves no GraphQL endpoint +# and ships no GraphQL schema, so the missing depth guard this rule +# reports does not exist here. +graphql-batch-limit ./docs/wiki/Automation.md ab6b3237ab28e713976df30ac7efe4871e983337248a8bef9fa68ffddcaca0e9 1 +graphql-batch-limit ./xtask/src/aegis.rs 623e18d37f4ff3f0c0acf509bcbc0b05490287b62a01eabef8d9b48776356521 1 # Matches the build metadata of a Cargo.lock version string # (0.6.0+11769913). international-phone ./Cargo.lock af21a1bff1718128c96522dc5f3a4136e66feeb8aee345e9676fda1199e5378e 1 diff --git a/xtask/src/aegis.rs b/xtask/src/aegis.rs index c1975c1..dab74cd 100644 --- a/xtask/src/aegis.rs +++ b/xtask/src/aegis.rs @@ -114,6 +114,14 @@ const CLASS_NOTES: &[(&str, &str)] = &[ category in order to record that it is absent; the repository \ holds no such data.", ), + ( + "graphql-batch-limit", + "Fires on English prose where a bulk-operation word and a bound \ + word share one line: the automation wiki's sentence about the \ + CLI's bulk work and the bounds it reports. FireCraft serves no \ + GraphQL endpoint and ships no GraphQL schema, so the missing \ + depth guard this rule reports does not exist here.", + ), ( "international-phone", "Matches the build metadata of a Cargo.lock version string \ From 4816835fb58a2c79aced1ca478ecff06d776a475 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 13:15:02 -0600 Subject: [PATCH 30/37] ci: skip FireCraft heavy GitForge jobs for docs-only commits --- .gitforge.yml | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/.gitforge.yml b/.gitforge.yml index 9015388..95d583a 100644 --- a/.gitforge.yml +++ b/.gitforge.yml @@ -37,7 +37,7 @@ # - Images must be pre-warmed on every runner host before a commit that # needs them lands (60-second sandbox acquisition cap; the runner # never pulls). Ship with: -# docker save firecraft-ci-rust:1 | ssh docker load +# docker save firecraft-ci-rust:2 | ssh docker load # - Step logs are head-capped: cargo's compile spam comes first, so a # failure late in a long step can be truncated. Keep steps small. # @@ -52,19 +52,38 @@ trigger_on: - tag environment: {} jobs: + - name: detect-changes + image: firecraft-ci-rust:2 + steps: + - name: Classify the diff; unknown/empty diffs fail closed + run: bash scripts/detect-changes.sh + timeout: 5m + - name: fmt-layers - image: firecraft-ci-rust:1 + image: firecraft-ci-rust:2 + needs: [detect-changes] steps: - name: Rust formatting check run: cargo fmt --all -- --check - - name: Layer-table gate - # Compiles xtask alone; the gate itself is cargo metadata. + - name: Web crate formatting check + run: cargo fmt --manifest-path web/Cargo.toml -- --check + - name: Whitespace/conflict-marker check + run: git diff --check origin/main...HEAD + timeout: 20m + + - name: layers + image: firecraft-ci-rust:2 + needs: [fmt-layers] + skip_if: '[[ "$CI_CHANGE_INCLUDE_CODE" == "1" || "$CI_CHANGE_INCLUDE_CRATES" == "1" || "$CI_CHANGE_INCLUDE_TESTS" == "1" || "$CI_CHANGE_IS_TAG" == "1" ]]' + steps: + - name: Workspace layer-table gate run: CARGO_TARGET_DIR=/tmp/ci-target cargo run --locked -p xtask -- layers timeout: 20m - name: clippy-test - image: firecraft-ci-rust:1 - needs: [fmt-layers] + image: firecraft-ci-rust:2 + needs: [layers] + skip_if: '[[ "$CI_CHANGE_INCLUDE_CODE" == "1" || "$CI_CHANGE_INCLUDE_CRATES" == "1" || "$CI_CHANGE_INCLUDE_TESTS" == "1" || "$CI_CHANGE_IS_TAG" == "1" ]]' steps: - name: Cargo clippy (deny warnings, all targets) run: CARGO_TARGET_DIR=/tmp/ci-target cargo clippy --workspace --all-targets --locked -- -D warnings @@ -79,8 +98,9 @@ jobs: timeout: 90m - name: wasm-web - image: firecraft-ci-rust:1 + image: firecraft-ci-rust:2 needs: [clippy-test] + skip_if: '[[ "$CI_CHANGE_INCLUDE_CODE" == "1" || "$CI_CHANGE_INCLUDE_CRATES" == "1" || "$CI_CHANGE_INCLUDE_TESTS" == "1" || "$CI_CHANGE_IS_TAG" == "1" ]]' steps: - name: Wasm compile gate + smoke suite + trunk bundle # CARGO_TARGET_DIR is inherited by xtask's child cargo calls and @@ -92,8 +112,9 @@ jobs: timeout: 60m - name: corpus-golden - image: firecraft-ci-rust:1 + image: firecraft-ci-rust:2 needs: [wasm-web] + skip_if: '[[ "$CI_CHANGE_INCLUDE_CODE" == "1" || "$CI_CHANGE_INCLUDE_CRATES" == "1" || "$CI_CHANGE_INCLUDE_TESTS" == "1" || "$CI_CHANGE_IS_TAG" == "1" ]]' steps: - name: Corpus digests + doc-model round-trips run: CARGO_TARGET_DIR=/tmp/ci-target cargo run --locked -p xtask -- corpus @@ -102,8 +123,9 @@ jobs: timeout: 30m - name: perf-budgets - image: firecraft-ci-rust:1 + image: firecraft-ci-rust:2 needs: [corpus-golden] + skip_if: '[[ "$CI_CHANGE_INCLUDE_CODE" == "1" || "$CI_CHANGE_INCLUDE_CRATES" == "1" || "$CI_CHANGE_IS_TAG" == "1" ]]' steps: - name: Performance budgets (open / frame / save / peak memory) # M12: the parity table's ceilings, enforced on the runner @@ -113,8 +135,9 @@ jobs: timeout: 20m - name: fuzz - image: firecraft-ci-rust:1 + image: firecraft-ci-rust:2 needs: [corpus-golden] + skip_if: '[[ "$CI_CHANGE_INCLUDE_CODE" == "1" || "$CI_CHANGE_INCLUDE_CRATES" == "1" || "$CI_CHANGE_IS_TAG" == "1" ]]' steps: - name: Stable fuzz drivers (anchors + panic_hunt + scripting arms) # The stable-toolchain driver set from `xtask ci`; the @@ -134,8 +157,9 @@ jobs: timeout: 60m - name: generated-docs - image: firecraft-ci-rust:1 + image: firecraft-ci-rust:2 needs: [fuzz] + skip_if: '[[ "$CI_CHANGE_INCLUDE_CODE" == "1" || "$CI_CHANGE_INCLUDE_CRATES" == "1" || "$CI_CHANGE_INCLUDE_GENERATED" == "1" || "$CI_CHANGE_IS_TAG" == "1" ]]' steps: - name: Parity floors + scorecard + stamps + reachability + panel snapshot, then drift check # The committed generated docs must byte-equal what the gates @@ -176,8 +200,9 @@ jobs: timeout: 20m - name: release - image: firecraft-ci-rust:1 + image: firecraft-ci-rust:2 needs: [generated-docs] + skip_if: '[[ "$CI_CHANGE_INCLUDE_CODE" == "1" || "$CI_CHANGE_INCLUDE_CRATES" == "1" || "$CI_CHANGE_IS_TAG" == "1" ]]' steps: - name: Ref report # GitForge stamps every push AND every tag push as TriggerType:: From 45cce2feaa163605f3c34d900b46571cc3f0d8a5 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 13:15:05 -0600 Subject: [PATCH 31/37] ci: add git to FireCraft CI image for change detection --- infrastructure/docker/ci-rust.Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infrastructure/docker/ci-rust.Dockerfile b/infrastructure/docker/ci-rust.Dockerfile index 6e77e9e..147f6d0 100644 --- a/infrastructure/docker/ci-rust.Dockerfile +++ b/infrastructure/docker/ci-rust.Dockerfile @@ -31,7 +31,7 @@ # cp --parents fuzz/Cargo.toml fuzz/Cargo.lock "$tmp"/ # cp --parents -r fuzz/src fuzz/fuzz_targets "$tmp"/ # docker build -f infrastructure/docker/ci-rust.Dockerfile \ -# -t firecraft-ci-rust:1 "$tmp" +# -t firecraft-ci-rust:2 "$tmp" # # cargo fetch needs each workspace member's manifest plus its declared # targets (src/ and benches/ — compose's criterion bench breaks manifest @@ -41,7 +41,7 @@ # the GitForge runner has a hard 60-second sandbox-acquisition cap and # will never pull the image itself: # -# docker save firecraft-ci-rust:1 | ssh docker load +# docker save firecraft-ci-rust:2 | ssh docker load # # Size guard: keep the image within a few GB — both known daemons run # overlay2, so the practical limits are LAN transfer time and fleet disk. @@ -82,7 +82,7 @@ FROM rust:1.99-slim-bookworm # lockfile comes from a git source. No libssl: nothing in the graph # builds openssl-sys. RUN apt-get update \ - && apt-get install -y --no-install-recommends ca-certificates \ + && apt-get install -y --no-install-recommends ca-certificates git \ && rm -rf /var/lib/apt/lists/* \ && rustup component add rustfmt clippy \ && rustup target add wasm32-unknown-unknown From f7010bf9c18c2ecd3090e34fe76d4d2753bd0706 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 13:15:08 -0600 Subject: [PATCH 32/37] ci: keep FireCraft backup CI lightweight for docs-only changes --- .github/workflows/ci.yml | 133 ++++++++++++++++++++++++--------------- 1 file changed, 84 insertions(+), 49 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9c7295..59b2b29 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,133 +1,168 @@ -# GitHub Actions backup CI — mirrors the GitForge 7-job pipeline. -# GitForge is primary; this is the fallback if GitForge is unavailable. -# -# Two-job design: -# fmt — fast (~30s), fails fast, no expensive tool installs needed -# gate — the full `xtask ci-no-fmt` suite; only runs if fmt passes -# -# Both run on all pushes and PRs. The fmt job prevents wasted runner -# time on formatting errors that would fail clippy anyway. - +# GitHub Actions backup CI. GitForge is primary; this is the fallback. +# Docs-only changes get a fast whitespace/conflict-marker check and do not +# install Rust/Aegis/coverage tooling or run the full xtask gate. The workflow +# remains active for every PR/push so required checks are not path-filtered +# into a permanently pending state. name: CI (backup) - on: push: branches: ["**"] tags: ["v*"] pull_request: branches: [main] - -# Least privilege: this workflow only reads the repository. Declaring -# it explicitly keeps the default `GITHUB_TOKEN` from inheriting a -# broader (write) grant from the org/repo settings — the rule -# `actions/missing-workflow-permissions` fires without this block. permissions: contents: read - env: CARGO_TERM_COLOR: always - jobs: + changes: + name: classify-change + runs-on: ubuntu-latest + outputs: + docs_only: ${{ steps.classify.outputs.docs_only }} + code_changed: ${{ steps.classify.outputs.code_changed }} + steps: + - name: Checkout full history + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Classify changed paths (fail closed on unknown/empty diff) + id: classify + shell: bash + env: + EVENT_NAME: ${{ github.event_name }} + REF: ${{ github.ref }} + BEFORE_SHA: ${{ github.event.before }} + PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} + run: | + set -euo pipefail + if [[ "$EVENT_NAME" == "workflow_dispatch" || "$REF" == refs/tags/* ]]; then + echo "docs_only=false" >> "$GITHUB_OUTPUT" + echo "code_changed=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + base="$BEFORE_SHA" + if [[ "$EVENT_NAME" == "pull_request" ]]; then base="$PR_BASE_SHA"; fi + if [[ -z "$base" || "$base" =~ ^0+$ ]] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then + echo "docs_only=false" >> "$GITHUB_OUTPUT" + echo "code_changed=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + if [[ "$EVENT_NAME" == "pull_request" ]]; then + files=$(git diff --name-only "$base...$GITHUB_SHA") + else + files=$(git diff --name-only "$base" "$GITHUB_SHA") + fi + if [[ -z "$files" ]]; then + echo "docs_only=false" >> "$GITHUB_OUTPUT" + echo "code_changed=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + docs_only=true + while IFS= read -r file; do + [[ -z "$file" ]] && continue + case "$file" in + docs/*|README.md|CHANGELOG.md|CONTRIBUTING.md|LICENSE|CODE_OF_CONDUCT.md) ;; + *) docs_only=false; break ;; + esac + done <<< "$files" + echo "docs_only=$docs_only" >> "$GITHUB_OUTPUT" + if [[ "$docs_only" == "true" ]]; then + echo "code_changed=false" >> "$GITHUB_OUTPUT" + else + echo "code_changed=true" >> "$GITHUB_OUTPUT" + fi + printf 'Changed files:\n%s\n' "$files" + docs: + name: docs-only-check + runs-on: ubuntu-latest + needs: [changes] + if: needs.changes.outputs.docs_only == 'true' + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Validate whitespace and merge markers + run: | + set -euo pipefail + if grep -RInE '^(<<<<<<<|=======|>>>>>>>)' docs README.md CONTRIBUTING.md 2>/dev/null; then + echo "Unresolved merge-conflict marker found in documentation." + exit 1 + fi fmt: name: fmt runs-on: ubuntu-latest + needs: [changes] + if: needs.changes.outputs.code_changed == 'true' steps: - name: Checkout uses: actions/checkout@v4 - - name: Install Rust uses: dtolnay/rust-toolchain@stable with: components: rustfmt - - name: Check formatting run: cargo fmt --all -- --check - - # Also check the workspace-excluded web crate explicitly. - name: Check web formatting run: cargo fmt --manifest-path web/Cargo.toml -- --check - gate: name: gate runs-on: ubuntu-latest - needs: [fmt] + needs: [changes, fmt] + if: needs.changes.outputs.code_changed == 'true' steps: - name: Checkout uses: actions/checkout@v4 - - name: Install Rust uses: dtolnay/rust-toolchain@stable with: components: clippy, rustfmt - - - name: Install aegis + - name: Install Aegis run: | - # aegis 0.6.3 — must match the version pinned in the GitForge CI - # image, or the baseline findings shift and the gate fails on - # tool drift rather than on a real finding. set -euo pipefail url=https://github.com/aliasfoxkde/aegis/releases/download/v0.6.3/aegis-linux-x86_64.tar.gz curl -sSL -o aegis.tar.gz "$url" - echo "835fad56172f8977a91424a580d0a3ec0c5b59fea99f4c2eb4c0a88fce30ff9e aegis.tar.gz" \ - | sha256sum -c - + echo "835fad56172f8977a91424a580d0a3ec0c5b59fea99f4c2eb4c0a88fce30ff9e aegis.tar.gz" | sha256sum -c - tar xzf aegis.tar.gz aegis sudo mv aegis /usr/local/bin/aegis aegis --version - - name: Install wasm32 target run: rustup target add wasm32-unknown-unknown - - name: Cache cargo registry uses: actions/cache@v4 with: path: ~/.cargo/registry key: cargo-registry-${{ hashFiles('**/Cargo.lock') }} - - name: Cache cargo index uses: actions/cache@v4 with: path: ~/.cargo/git key: cargo-index-${{ hashFiles('**/Cargo.lock') }} - - name: Cache build artifacts uses: actions/cache@v4 with: path: target key: cargo-build-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: cargo-build-${{ runner.os }}- - - # Cache cargo-llvm-cov and trunk binaries between runs (~2 min saved per run). - # --locked pins the version so the cache key matches the locked version. - name: Cache cargo-llvm-cov id: cache-llvc uses: actions/cache@v4 with: path: ~/.cargo/bin/cargo-llvm-cov key: cargo-llvm-cov-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} - - name: Install cargo-llvm-cov (if uncached) if: steps.cache-llvc.outputs.cache-hit != 'true' run: cargo install cargo-llvm-cov --locked - - name: Cache trunk id: cache-trunk uses: actions/cache@v4 with: path: ~/.cargo/bin/trunk key: trunk-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }} - - name: Install trunk (if uncached) if: steps.cache-trunk.outputs.cache-hit != 'true' run: cargo install trunk --locked - - # `ci-no-fmt` skips the fmt step so the two jobs stay independent — - # fmt is owned by the `fmt` job above. - name: Full gate (xtask ci-no-fmt) run: cargo run --package xtask -- ci-no-fmt - continue-on-error: false - - # Smoke for the web bundle — only runs on tag pushes (release candidates) - name: Web bundle smoke if: startsWith(github.ref, 'refs/tags/v') run: cargo run --package xtask -- dist --web - continue-on-error: false From 294c75ec5adf087a3b0208610cddf4856d215018 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 13:15:10 -0600 Subject: [PATCH 33/37] ci: add conservative FireCraft path classifier --- scripts/detect-changes.sh | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 scripts/detect-changes.sh diff --git a/scripts/detect-changes.sh b/scripts/detect-changes.sh new file mode 100644 index 0000000..f83aabb --- /dev/null +++ b/scripts/detect-changes.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# Conservative diff classifier for GitForge's downstream skip_if jobs. +set -euo pipefail +git fetch --quiet origin main --tags 2>/dev/null || true +BASE="" +if git rev-parse --verify origin/main >/dev/null 2>&1; then + BASE=$(git merge-base origin/main HEAD 2>/dev/null || true) +fi +if [[ -z "$BASE" || "$BASE" == "$(git rev-parse HEAD)" ]]; then + BASE=$(git rev-parse HEAD^1 2>/dev/null || true) +fi +CHANGED_FILES="" +if [[ -n "$BASE" ]]; then CHANGED_FILES=$(git diff --name-only "$BASE" HEAD 2>/dev/null || true); fi +IS_TAG=0 +if git tag --points-at HEAD | grep . >/dev/null; then IS_TAG=1; fi +CODE=0; DOCS=0; CRATES=0; TESTS=0; INFRA=0; GENERATED=0 +if [[ -z "$CHANGED_FILES" && "$IS_TAG" == "0" ]]; then CODE=1; fi +while IFS= read -r file; do + [[ -z "$file" ]] && continue + case "$file" in + docs/planning/generated/*|crates/app/panels.snapshot) + DOCS=1; GENERATED=1; continue ;; + docs/*|README.md|CHANGELOG.md|CONTRIBUTING.md|LICENSE|CODE_OF_CONDUCT.md) + DOCS=1; continue ;; + tests/*|*/tests/*|*_test.rs|*.fw.png|corpus/*|*/fixtures/*) + TESTS=1; continue ;; + .github/*|.gitforge.yml|infrastructure/*|docker/*|scripts/*) + INFRA=1; CODE=1; continue ;; + crates/*/Cargo.toml|crates/*/src/*|xtask/*|web/*|Cargo.toml|Cargo.lock|rust-toolchain*|.cargo/*) + CODE=1 + if [[ "$file" == crates/* ]]; then CRATES=1; fi + continue ;; + *.rs|*.toml|*.lock|*.yml|*.yaml|*.sh|*.py|*.js|*.ts|*.tsx|*.jsx|*.html|*.css|*.json) + CODE=1; continue ;; + *) CODE=1 ;; + esac +done <<< "$CHANGED_FILES" +if [[ "$IS_TAG" == "1" ]]; then CODE=1; fi +COUNT=0 +if [[ -n "$CHANGED_FILES" ]]; then COUNT=$(printf '%s\n' "$CHANGED_FILES" | wc -l | tr -d ' '); fi +echo "CI_CHANGE_FILE_COUNT=$COUNT" +echo "CI_CHANGE_INCLUDE_CODE=$CODE" +echo "CI_CHANGE_INCLUDE_DOCS=$DOCS" +echo "CI_CHANGE_INCLUDE_CRATES=$CRATES" +echo "CI_CHANGE_INCLUDE_TESTS=$TESTS" +echo "CI_CHANGE_INCLUDE_INFRA=$INFRA" +echo "CI_CHANGE_INCLUDE_GENERATED=$GENERATED" +echo "CI_CHANGE_IS_TAG=$IS_TAG" From 1ef97d5ab5aab37e3591848cbb088d6aabe651b9 Mon Sep 17 00:00:00 2001 From: AliasFox Date: Wed, 11 Nov 2026 13:15:13 -0600 Subject: [PATCH 34/37] test: cover FireCraft docs-only and source change detection --- tests/detect-changes-selftest.sh | 53 ++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tests/detect-changes-selftest.sh diff --git a/tests/detect-changes-selftest.sh b/tests/detect-changes-selftest.sh new file mode 100644 index 0000000..6d2cb4a --- /dev/null +++ b/tests/detect-changes-selftest.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +DETECT="$ROOT/scripts/detect-changes.sh" +WORK=$(mktemp -d) +trap 'rm -rf "$WORK"' EXIT +fail(){ echo "FAIL: $*" >&2; exit 1; } +get(){ sed -n "s/^$2=//p" <<< "$1"; } +make_repo(){ + local name=$1 + mkdir -p "$WORK/$name" + git -C "$WORK/$name" init -q -b main + git -C "$WORK/$name" config user.name Test + git -C "$WORK/$name" config user.email test@example.invalid + echo base > "$WORK/$name/README.md" + git -C "$WORK/$name" add . + git -C "$WORK/$name" commit -qm base + git -C "$WORK/$name" init -q --bare "$WORK/$name-origin.git" + git -C "$WORK/$name" remote add origin "$WORK/$name-origin.git" + git -C "$WORK/$name" push -q -u origin main + git -C "$WORK/$name" fetch -q origin main +} +run(){ (cd "$1" && bash "$DETECT"); } +make_repo docs +git -C "$WORK/docs" checkout -qb docs-only +mkdir -p "$WORK/docs/docs" +echo notes > "$WORK/docs/docs/architecture.md" +git -C "$WORK/docs" add . +git -C "$WORK/docs" commit -qm docs +git -C "$WORK/docs" push -q origin docs-only +git -C "$WORK/docs" fetch -q origin main +OUT=$(run "$WORK/docs") +[[ "$(get "$OUT" CI_CHANGE_INCLUDE_DOCS)" == 1 ]] || fail "docs flag missing" +[[ "$(get "$OUT" CI_CHANGE_INCLUDE_CODE)" == 0 ]] || fail "docs-only classified as code" +make_repo code +git -C "$WORK/code" checkout -qb source +mkdir -p "$WORK/code/crates/app/src" +echo 'fn main() {}' > "$WORK/code/crates/app/src/main.rs" +git -C "$WORK/code" add . +git -C "$WORK/code" commit -qm source +git -C "$WORK/code" push -q origin source +git -C "$WORK/code" fetch -q origin main +OUT=$(run "$WORK/code") +[[ "$(get "$OUT" CI_CHANGE_INCLUDE_CODE)" == 1 ]] || fail "Rust change not classified" +[[ "$(get "$OUT" CI_CHANGE_INCLUDE_CRATES)" == 1 ]] || fail "crate flag missing" +make_repo mainpush +echo 'fn main() {}' > "$WORK/mainpush/main.rs" +git -C "$WORK/mainpush" add . +git -C "$WORK/mainpush" commit -qm main-change +git -C "$WORK/mainpush" push -q origin main +OUT=$(run "$WORK/mainpush") +[[ "$(get "$OUT" CI_CHANGE_INCLUDE_CODE)" == 1 ]] || fail "main-push fallback missed source" +echo "FireCraft detect-changes self-test: passed" From cd6184b12453971c1ba1842376febad47a2b1d66 Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Wed, 11 Nov 2026 13:42:42 -0600 Subject: [PATCH 35/37] fix(aegis): adjudicate the self-test's reserved-domain Git identity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The change-detection self-test configures a throwaway Git identity for its temporary repositories, and the address it uses trips the email-address rule. The domain is the .invalid top-level domain that RFC 2606 reserves for exactly this purpose, so the address can never resolve to a real mailbox; the finding is a false positive. Adjudicate it in the repo's content-keyed form: a class note recording why the occurrence is a false positive, and one baseline row for the content key. The rule stays armed — a new literal, a new file, or an extra copy of this one still fails the gate. Co-Authored-By: Claude Code --- .aegis-baseline.tsv | 6 ++++++ xtask/src/aegis.rs | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/.aegis-baseline.tsv b/.aegis-baseline.tsv index 95218c1..8c8d522 100644 --- a/.aegis-baseline.tsv +++ b/.aegis-baseline.tsv @@ -58,6 +58,12 @@ credit-card-amex ./xtask/src/aegis.rs ae9b46ed1c3eff9a64786a2171b0f694350bb58947 # rule. credit-card-number-generic ./crates/text/tests/layout.rs ae9b46ed1c3eff9a64786a2171b0f694350bb589478b4327f5f82836c23e8da9 1 credit-card-number-generic ./xtask/src/aegis.rs ae9b46ed1c3eff9a64786a2171b0f694350bb589478b4327f5f82836c23e8da9 1 +# Matches the throwaway Git identity the change-detection self-test +# configures for its temporary repositories. The address uses the +# .invalid top-level domain reserved by RFC 2606 for exactly this +# purpose, so it can never resolve to a real mailbox; the repository +# holds no personal addresses. +email-address ./tests/detect-changes-selftest.sh 852e7b941ea2052143c1b0a0f7b007a06c49c056312aac64e2649dc35d13f994 1 # The scripting crate's own boa context.eval() call — that crate # implements the CS6 scripting DOM's eval() — plus Rust curve-segment # .eval(u) calls. diff --git a/xtask/src/aegis.rs b/xtask/src/aegis.rs index dab74cd..2f153a2 100644 --- a/xtask/src/aegis.rs +++ b/xtask/src/aegis.rs @@ -90,6 +90,15 @@ const CLASS_NOTES: &[(&str, &str)] = &[ "The same glyph-position golden value, seen by the generic \ card-number rule.", ), + ( + "email-address", + "Matches the throwaway Git identity the change-detection \ + self-test configures for its temporary repositories. The \ + address uses the .invalid top-level domain reserved by \ + RFC 2606 for exactly this purpose, so it can never resolve \ + to a real mailbox; the repository holds no personal \ + addresses.", + ), ( "eval-usage", "The scripting crate's own boa context.eval() call — that crate \ From c49b2087db11f3f6733d0d89559fa98854da2d98 Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Wed, 11 Nov 2026 14:15:17 -0600 Subject: [PATCH 36/37] docs: drop trailing whitespace from the project status header The CI whitespace gate (`git diff --check origin/main...HEAD`) rejects trailing spaces, but Markdown hard line breaks are written as two trailing spaces. The three header lines were written with the two-space break form, so the gate failed on the branch's own new content. Use the backslash hard-break form instead, which renders identically and leaves no trailing whitespace. Co-Authored-By: Claude Code --- docs/wiki/Project-Status.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/wiki/Project-Status.md b/docs/wiki/Project-Status.md index de835f4..c8e67f8 100644 --- a/docs/wiki/Project-Status.md +++ b/docs/wiki/Project-Status.md @@ -1,7 +1,7 @@ # Project Status -**Snapshot reviewed:** 2026-11-11 -**Source:** `main` at `b61f198` +**Snapshot reviewed:** 2026-11-11\ +**Source:** `main` at `b61f198`\ **Latest published release:** [v0.2.5](https://github.com/aliasfoxkde/FireCraft/releases/tag/v0.2.5) (2026-11-03) FireCraft is a functional Rust graphics editor with a shared document engine and command registry across the desktop GUI, WebAssembly app, CLI, scripting host, and MCP server. The current source is newer than the latest published release; do not assume the hosted app contains every change on `main`. From c13eb8134ed2f02da8f766ed92626b2216bc472a Mon Sep 17 00:00:00 2001 From: Michael Kinney Date: Wed, 11 Nov 2026 15:46:38 -0600 Subject: [PATCH 37/37] ci: size the pipeline watchdogs from the fleet's measured wall-clock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A job's `timeout:` is a watchdog, not a gate: it kills the container and records `timed_out` with no diagnostic about what was slow. The budgets were sized by guess, and the guess is now falsified by the fleet's own record — a job was killed at 20.2 min and at 20.3 min while still working, and the release job's worst successful run finished 1.7 minutes inside its 90-minute budget. The runner holds 4 concurrent containers on a 16-core host and each compiles the workspace, so a co-tenant wave inflates a job roughly 4x. Measured on 2026-11-11 with 9 runs in flight (idle in parentheses): job budget worst success idle fmt-layers 20m 20.1 min 0.3 min clippy-test 90m 76.9 min 10.3 min wasm-web 60m 45.6 min 9.0 min corpus-golden 30m 19.6 min 2.5 min perf-budgets 20m 14.3 min 3.2 min fuzz 60m 52.9 min 10.6 min generated-docs 20m 16.1 min 2.1 min release 90m 88.3 min 38.8 min Each budget below is ~2.5x the worst successful duration, so a loaded job still fits and a genuinely hung job is still killed: fmt-layers 45m, clippy-test 150m, wasm-web 90m, corpus-golden 45m, perf-budgets 45m, fuzz 120m, generated-docs 45m, release 180m No gate is weakened: the budgets decide when a container is killed, not whether a check passes. Refs #126 Co-Authored-By: Claude Code --- .gitforge.yml | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/.gitforge.yml b/.gitforge.yml index 95d583a..c67bb6f 100644 --- a/.gitforge.yml +++ b/.gitforge.yml @@ -40,6 +40,18 @@ # docker save firecraft-ci-rust:2 | ssh docker load # - Step logs are head-capped: cargo's compile spam comes first, so a # failure late in a long step can be truncated. Keep steps small. +# - A job's `timeout:` is a WATCHDOG, not a gate: it kills the +# container and records `timed_out`, with no diagnostic about what +# was slow. The budgets below are therefore sized from the fleet's +# measured wall-clock, not from a round guess. The runner holds 4 +# concurrent containers on a 16-core host and each compiles the +# workspace, so a co-tenant wave inflates a job roughly 4x: +# fmt-layers measured 0.3 min idle and 20.1 min loaded; perf-budgets +# 3.2 min idle and 14.3 min loaded. Each budget below is ~2.5x the +# worst *successful* duration observed on 2026-11-11 with 9 runs in +# flight, so a loaded job still fits its budget and a genuinely hung +# job is still killed. A budget that a passing job can outrun is +# indistinguishable from a failure (issue #126). # # The image recipe is infrastructure/docker/ci-rust.Dockerfile; rebuild # and re-ship it when a pinned tool version or the Rust minor moves. A @@ -78,7 +90,11 @@ jobs: steps: - name: Workspace layer-table gate run: CARGO_TARGET_DIR=/tmp/ci-target cargo run --locked -p xtask -- layers - timeout: 20m + # 45m: the gate compiles xtask, so it carries the workspace's + # build wave. Measured 20.1 min on 2026-11-11 with 9 runs in + # flight (0.3 min idle); the previous 20m budget killed a run that + # was 0.5 min from finishing. + timeout: 45m - name: clippy-test image: firecraft-ci-rust:2 @@ -95,7 +111,8 @@ jobs: run: CARGO_TARGET_DIR=/tmp/ci-target cargo test --workspace --locked --no-fail-fast -- --test-threads=2 # The egui/eframe graph is the bulk of the workspace; the wall # absorbs co-tenant build waves on these shared hosts. - timeout: 90m + # 150m: measured 76.9 min on 2026-11-11 with 9 runs in flight. + timeout: 150m - name: wasm-web image: firecraft-ci-rust:2 @@ -109,7 +126,8 @@ jobs: # the image, the fwpng smoke suite executes for real (no # compile-only downgrade), and trunk builds the web bundle. run: CARGO_TARGET_DIR=/tmp/ci-target cargo run --locked -p xtask -- wasm - timeout: 60m + # 90m: measured 45.6 min on 2026-11-11 with 9 runs in flight. + timeout: 90m - name: corpus-golden image: firecraft-ci-rust:2 @@ -120,7 +138,8 @@ jobs: run: CARGO_TARGET_DIR=/tmp/ci-target cargo run --locked -p xtask -- corpus - name: Golden render pins + determinism run: CARGO_TARGET_DIR=/tmp/ci-target cargo run --locked -p xtask -- golden - timeout: 30m + # 45m: measured 19.6 min on 2026-11-11 with 9 runs in flight. + timeout: 45m - name: perf-budgets image: firecraft-ci-rust:2 @@ -132,7 +151,11 @@ jobs: # fleet. The report line names the host, so a trip is # diagnosable as regression vs environment shift. run: CARGO_TARGET_DIR=/tmp/ci-target cargo run --locked -p xtask -- perf - timeout: 20m + # 45m: measured 14.3 min on 2026-11-11 with 9 runs in flight, but + # two runs were killed at the previous 20m budget while still + # working (one on 2026-11-11 at 20.2 min, one at 20.3 min). The + # budget must exceed what a passing job can take. + timeout: 45m - name: fuzz image: firecraft-ci-rust:2 @@ -154,7 +177,9 @@ jobs: # 30m proved too tight: a cold sandbox target dir spends ~20m # compiling before fuzz-quick starts (dfd7f46 run was killed by # the watchdog 10m into the campaign itself). - timeout: 60m + # 120m: measured 52.9 min on 2026-11-11 with 9 runs in flight, so + # the 60m budget left less than a quarter of an hour of margin. + timeout: 120m - name: generated-docs image: firecraft-ci-rust:2 @@ -197,7 +222,8 @@ jobs: CARGO_TARGET_DIR=/tmp/ci-target cargo run --locked -p xtask -- panel-snapshot cmp /tmp/parity.committed docs/planning/generated/parity.md cmp /tmp/scorecard.committed docs/planning/generated/scorecard.md - timeout: 20m + # 45m: measured 16.1 min on 2026-11-11 with 9 runs in flight. + timeout: 45m - name: release image: firecraft-ci-rust:2 @@ -292,4 +318,8 @@ jobs: # directory, so verify from inside each one. (cd artifacts/web && sha256sum -c MANIFEST.sha256) (cd artifacts/native && sha256sum -c MANIFEST.sha256) - timeout: 90m + # 180m: measured 88.3 min on 2026-11-11 with 9 runs in flight — + # 1.7 minutes inside the previous 90m budget. The release job is + # the longest in the chain and runs last, when the fleet is most + # loaded, so it is the job most likely to be killed by its budget. + timeout: 180m