* Data: Solver Sensitivity report Builds on the Answer and Limits reports. reports: [sensitivity] (on data.solver and data.solverReport) writes a Sensitivity report for models solved by Simplex LP or GRG Nonlinear without integer constraints and with a Max or Min objective. Simplex LP: the model is linearised at the solution and solved again, and the report is read from the final tableau: each variable's reduced cost and the range of its objective coefficient over which the basis stays optimal, and each constraint's shadow price and the range of its right side over which that price holds (1E+30 for no limit). GRG Nonlinear: difference gradients at the solution give each binding constraint's Lagrange multiplier (a least-squares fit on the variables inside their bounds, dropping constraints whose multiplier has the wrong sign) and each variable's reduced gradient. The Solver Results dialog offers the report. * Data: Solver Results offers the Sensitivity report only where it applies Integer and binary models, the Evolutionary method and Value Of goals have no Sensitivity report, and choosing it with other reports made the whole report request fail. Solver Results now disables the Sensitivity choice for such models (with the reason on hover) and leaves it out of the request, so the other chosen reports are still written. sensitivity_applies (in cmd::solver) reads the model from data.solver params, as the dialog holds them; a test checks that it agrees with the report for each kind of model. * Data: Solver bounds the nonlinear Sensitivity report's work The Lagrange multipliers of a GRG Nonlinear model are found by least squares over the binding constraints; a constraint whose multiplier has the wrong sign is dropped and the rest are solved again. Each pass costs about 2·k²·f operations for k binding constraints and f free variables, and each pass drops at most one constraint, so a model at the 1,000-constraint limit could take minutes and hold the window. The passes now share a limit of about 10⁹ operations (about a second). Past it the report is refused with a message, before anything changes: the workbook and the Undo history stay as they were, as for the other report refusals. The limit is lowered in tests so the refusal can be reached with a small model. * Data: Solver refuses a Simplex Sensitivity report for a point that is not optimal The Simplex LP Sensitivity report solves the linearised model again to read its final tableau, but shows the final values it was given. data.solverReport accepts any values, so a report could pair values that are not optimal (or not feasible) with the shadow prices, reduced costs and ranges of the true optimum. The report now checks that the given point satisfies every constraint and bound and reaches the optimal objective (both within the constraint precision; another optimal point with the same objective is accepted) and is refused otherwise, before anything changes. * Data: Solver compares the Sensitivity report's objective in both directions The check that a point is optimal compared its objective with the optimum in one direction only, as for an inequality. A point just outside a bound (within the constraint precision) can still have an objective far below the minimum when its costs are large, and that point was accepted. The objective is now compared by the size of the difference, so such a point is refused. * Data: Solver refuses a nonlinear Sensitivity report for a point that is not optimal data.solverReport accepts any finite variable values. The Simplex LP report already refuses values that are not optimal, but the GRG Nonlinear report described whatever point it was given: for example, a minimisation of A1^2 given A1 = 1 found no binding rows and reported a reduced gradient of 2 instead of requiring the optimum at A1 = 0. The nonlinear report now checks, from the gradients it already computes, that the values are a Karush-Kuhn-Tucker point before anything changes: every constraint holds within the tolerance the nonlinear method accepts a solution within, every bound holds within the constraint precision, each variable inside its bounds has a reduced gradient near zero, and a variable at a bound has a reduced gradient that points only out of that bound for the objective's direction. A binding row whose multiplier has the wrong sign is still dropped, and the gradient it would have explained now causes the refusal. The stationarity tolerance is 1E-3 of the largest objective-gradient component (at least 1), well above the reduced gradients left at optima the method solves. * Data: Solver writes the other reports when the Sensitivity report does not apply to the solution Since the nonlinear Sensitivity report refuses values that are not optimal, data.solver with reports that include sensitivity failed as a whole when the run stopped before an optimum (an evaluation limit) or the values were not one, so the solution and the Answer and Limits reports were lost. Solver Results also offered Sensitivity after any solve, and ticking it with Answer after such a run wrote no report. data.solver now writes the Sensitivity report only when the run reached an optimal or converged solution that the report accepts. Otherwise the solve still applies, the other reports are written, and the result lists the report in skippedReports with the reason. Models that have no Sensitivity report (integer, Evolutionary, Value Of) are refused as before. data.solverReport still refuses values that are not optimal; its new skipNotOptimal parameter leaves the report out instead. Solver Results offers Sensitivity only after an optimal or converged status, with the reason on hover, passes skipNotOptimal, and shows the reason when the report is left out. * Data: Solver skips a Sensitivity report in a protected workbook without refusing the call Structure protection is now checked only when a report sheet will be written. A data.solverReport request with skipNotOptimal whose only report is skipped changes nothing, so it succeeds in a workbook whose structure is protected and returns skippedReports; a request that would write a sheet is still refused. * Data: Solver refuses report sheets in a protected workbook before building them A request that must write a report sheet (any Answer or Limits report, or a Sensitivity report that is not allowed to be skipped) is refused before any report is built, so a protected workbook does not run the Limits report's optimisations first. The check after the reports are built remains for a Sensitivity report that may be skipped. * Data: Solver reports Simplex sensitivity only at the vertex it describes The Simplex LP Sensitivity report solves the linearised model again and takes its prices and ranges from that final tableau, but it discarded the vertex the solve returned and showed the values it was given. When the optimum is not unique, another optimal point passed the optimality check, so the report paired those values with the ranges of a different vertex. The report now also requires the given values to match the re-solved vertex within the constraint precision, and refuses another optimum with a message that says so. A Sensitivity report that data.solver or Solver Results may skip is left out instead, as for other points the report does not support. Values from a Simplex LP solve still match, so the usual Solver Results flow is unchanged. * Data: Solver gives a redundant constraint's right side no allowable change The Simplex LP Sensitivity report ranges each right side over the basic values of the real columns only. A row that the other rows make redundant (max x with x = 2 and 2x = 4) keeps its artificial column basic at zero after phase one, and changing either right side alone moves that artificial, so no change has a solution. The report showed 1E+30 and 2 for the first row instead. When a basic artificial has a nonzero entry in the column of the right side being changed, both allowable changes are now 0. The objective-coefficient ranges are unaffected: such a row has no cost and no entries in the real columns, and a cost change does not affect feasibility. * Data: Solver builds the Simplex Sensitivity report's program at the solve's start values The Simplex LP solve linearises the model at the start values, but the Sensitivity report linearised it again at the solution. The difference coefficients then differ in their last bits, and when the optimum is not unique that can break a tie between pivots the other way: the report's solve returned the other vertex and refused the solve's own values. With max 0.1x + 0.1y over a tied edge, more than half of the sampled starting points were refused. The solve and the report now build the program with one function, simplex_program, and the report builds it from the start values it is given (data.solver's start values, which Solver Results passes back as original), so its solve repeats the solve's pivots and returns the same vertex. Start values at which the model cannot be evaluated fall back to the solution, and values that are not the solve's are still refused by the vertex check. * Data: Solver's Sensitivity report sets its noise levels from the coefficients, not the objective's value The figures a Sensitivity report prints as 0 were those below 1E-9 of the objective's value (1E-6 for the nonlinear figures), so a constant in the objective hid real prices: max 1E9 + x with x <= 10 wrote the row's shadow price, exactly 1, as 0, although the constant changes nothing about the optimisation. A shadow price and a reduced cost are combinations of the objective coefficients, so Simplex LP now takes the noise level from the largest coefficient; a reduced gradient is a part of the objective's gradient and a Lagrange multiplier objective per unit of its row's gradient, so GRG Nonlinear takes it from the gradient's size, and the multipliers' sign test compares lambda times the row's gradient size with it. Allowable changes keep the tableau's pivot tolerance as before. * Data: Solver Sensitivity report tests for variables at a bound and for both goals Hand-derived cases pin the report's conventions. Simplex LP: a maximum's variable at its upper bound (reduced cost 1, Allowable Increase 1E+30, Allowable Decrease 1), a minimum with a >= row and a variable at its upper bound (reduced cost -1, Allowable Increase 1, Allowable Decrease 1E+30), and Winston's Dakota Furniture problem, whose variable at zero has reduced cost -5 with Allowable Increase 5 and Allowable Decrease 1E+30, with every shadow price and allowable range worked out from the final basis. GRG Nonlinear: the Lagrange multiplier is the derivative of the optimal objective with respect to the right side and the reduced gradient that with respect to the variable's bound for a minimum (-1) and the negated maximum (+1), and the mirror image of the existing minimum with a variable at its bound (multiplier +2, reduced gradient -4). * Docs: ROADMAP.md records the Solver Sensitivity report The detail documents (docs/gaps.md, docs/target-app-parity.md) record the report, but the roadmap summary did not: its header change note, progress log and revision history now carry it. * Data: Solver's Sensitivity report bounds each figure's rounding noise by its own terms, not the model's largest coefficient or gradient The noise level a figure had to exceed to print was 1E-9 of the largest objective coefficient (Simplex LP) or 1E-6 of the largest gradient component (GRG Nonlinear) for every figure, so an unrelated large coefficient hid real values: max 1E9*x + y with x <= 1 and y <= 1 as rows wrote the second row's shadow price, exactly 1, as 0, and the same model's Lagrange multiplier 1 and a third variable's reduced cost or gradient -1 went the same way. The rounding error of a sum scales with the sum of its terms' sizes, so each figure now has its own bound from the terms it is made of. Simplex LP: a shadow price y_i = sum over the basis rows of c_B(r) * Binv(r, i) is bounded by 1E-9 of those terms' sizes (the row's unit column of the final tableau holds Binv's column i); a reduced cost cf_j - sum of a_ij * y_i by 1E-9 of |cf_j| plus |a_ij| times each price's term sizes, so a price that is a small difference of large terms carries their error into the reduced costs it is used in. GRG Nonlinear: a multiplier solved from its row of the normal equations is bounded by 1E-6 of its own terms (the row's gradient times the objective's, and its coupling terms with the other active rows times their multipliers) over the row's squared norm; the multipliers' sign test uses the same bound, so a row leaves the active set on the criterion the report rounds with; a reduced gradient is bounded by 1E-6 of its own component and the multipliers' terms plus the multipliers' bounds times |g_ij|. Nearly parallel active gradients amplify every multiplier's error beyond a bound local to a row; such multipliers print as computed. A constant in the objective still changes no bound, since none depends on the objective's value. The nonlinear method stops on the 1E9 model from (0, 0) with "unbounded", so its two regression tests ask for the report at the optimum through data.solverReport. * Data: Solver's Sensitivity report tests a nonlinear point's optimality by each variable's and row's own scale, not the model's largest The Karush-Kuhn-Tucker check that refuses a Sensitivity report for a point that is not optimal accepted a reduced gradient within 1E-3 of the largest gradient component, and a row violation within ten times the constraint precision of the largest constant right side. Both scales were the model's, not the figure's: on max 1E9*x + y with x <= 1 and y <= 1 as rows the tolerance was 1E6, so (1, 0.5), where raising y gains 1 per unit, passed as optimal and the report was written for it; on max y - (x - 2)^2 with x <= 1E9 and y <= 1, (2, 1.0001) passed although the second row is over by 1E-4 against its own precision of 2E-5. Each reduced gradient is now tested against 1E-3 of the terms it is made of (the objective's component and the multipliers' parts, at least 1, the same floor as before), and each row against ten times the constraint precision of its own right side. The nonlinear method itself accepts a solution relative to the largest constant right side; a row over by more than its own precision is not satisfied whatever the other rows' sizes, so the report refuses it. The term sizes are shared with the reduced gradients' rounding bound. Two regression tests, each proving the workbook is left as it was and that the optimum is still reported. * Data: Solver refuses a Sensitivity report the model has none of before any report is built or the solve runs The refusals that apply to the model rather than the solution (integer or binary constraints, the Evolutionary method, a Value Of goal) were made inside the report loop, when it reached the Sensitivity report, so a request listing the Limits or Answer report first built those reports for an error: a Value Of model asking for limits and sensitivity ran the Limits report's two optimisations per variable and received only the refusal, and data.solver ran its whole solve before it. prepare_reports now checks the model's refusal before the loop, in both modes (a refusal of the model was already an error in both; only the solution's not-optimal refusal is skipped under skipNotOptimal), and data.solver checks it before the solve. The regression test asks for limits and sensitivity on an integer model, which now gets the Sensitivity refusal instead of the Limits report's, and on a Value Of model, which gets the Sensitivity refusal with no sheet written. --------- Co-authored-by: FredApps <FredApps@users.noreply.github.com>
43 KiB
GridCraft roadmap
Stage: alpha · next: beta, ~25 points of "ready for real work" and ~160–240 h away
Last reviewed: 2026-11-01 · Last updated: 2026-11-02 · Change: minor (What-if and analysis: Solver Sensitivity report for Simplex LP and GRG Nonlinear; earlier: floating objects: one selection, eight resize handles, keyboard delete; earlier: Chart data tables: live source values beneath column, bar, line, area and compatible combo charts; legend keys and borders; XLSX round-trip and print/PDF; earlier: Formulas › Function Library as labelled buttons with category menus; Recently Used and Insert Function categories; XLSX workbook-view selection, bounded tab ratios and sheet-edit regressions; readiness estimates unchanged; earlier: CSV and text open detects each column's date order, so day-first dates are not silently swapped) · Target: Microsoft Excel (Microsoft 365)
GridCraft aims at full Microsoft Excel parity, and at being better in places: faster, open (XLSX is the native format), fully scriptable by agents (MCP, control channel, CLI), and on the web. This page is the summary. The detail is in:
docs/target-app-parity.md: the authoritative assessment, method and weightsdocs/gaps.md: every known shortfall, ranked; the work listdocs/roadmap.md: milestones, current focus, what's nextdocs/parity-checklist.md: generated bycargo xtask parity(ribbon commands)- Area checklists: functions · charts · file formats · UI · hardware · localization
docs/architecture.md: how it is built
Headline numbers
| Number | Value | Kind |
|---|---|---|
| 2026-10-14 | Editing a cell with text that would read back as a number, boolean, date or formula (entered with a leading apostrophe) shows the apostrophe in the editor and formula bar, so Enter unchanged keeps it text (#1362) | |
| Feature breadth (weighted) | ~75% | estimated, anchored on two measurements: ribbon catalog 276 / 292 (94.5%), worksheet functions 513 / 523 (98.1%; 504 working, 96.4%) |
| Ready for real work | ~50% | estimated from written weights (51.6); target-app-parity.md |
| Mainstream practitioner | ~50% | estimated: typical analyst/finance user, weekly features, × 0.90 interaction × 0.92 stability × 0.88 file exchange; method |
| Essentials user | ~63% | estimated: core features only, × 0.92 launch/stability × 0.95 clarity × 0.90 opening sent files; method |
| Remaining to beta | ~160–240 Opus 5.5 agent-hours | estimated; itemized in roadmap.md |
| Remaining to full parity | ~700–1,100 Opus 5.5 agent-hours | estimated; sum of the dimension rows below |
| Audience | Ready % | Opus 5.5 agent wall-clock hours to ~95% | Work that dominates |
|---|---|---|---|
| Full target (ready for real work) | ~50% | ~650–1,050 | Get & Transform and the data model, localization (twelve languages), charts depth, file fidelity (.xls, corpus, pass-through), PivotTables, collaboration, mobile |
| Mainstream practitioner | ~50% | ~200–310 | File exchange with Excel users (corpus and Excel verification, pass-through, large files, .xls, encryption: 63–97 h), common-chart depth (30–45 h), PivotTables (20–30 h), keyboard and interaction (18–28 h), calc correctness and functions (20–33 h) |
| Essentials user | ~63% | ~60–100 | Opening files people send (.xls import and saving with a password 24–36 h; macOS Finder open 2–4 h), launch stability (6–10 h), basic chart resize and polish (6–10 h), print and Page Layout (8–12 h), small editing and UI fixes (10–16 h) |
Each tier is a subset of the one above, so its hours are too. Calibrated as in Effort and
calibration (~6–10 h per readiness point for the remaining, verification-heavy
work; single features measured from PRs #66, #100, #101). Parallelism: the full and mainstream
work splits ~65–70% across 4–6 agents by area; the essentials work is mostly small fixes plus one
long .xls track, so about half parallelizes (≈30–50 wall-clock hours with three agents).
Why alpha: all six core workflows in the alpha gate pass end to end on macOS with save and reopen, and the core workflow works end to end (open an XLSX, enter formulas and data, format, sort
and filter, chart, pivot, print to PDF, save XLSX), but users still hit blocking gaps on real
files: 100 MB workbooks don't open (#175), there's no .xls (#121), Arabic and Devanagari text
isn't shaped (Chinese text still reported in #142), charts lose their type and options on round trip, and
nobody has yet confirmed that Excel opens our output without a repair prompt across a real
corpus. Beta needs those closed (see beta gates).
The 2026-10-07 numbers (catalog 89%, "feature depth ~65%", "~215 h to full parity") were
re-measured. Catalog and function counts held or rose; the depth and hours moved because of new
evidence: 82 issues filed by users and contributors in the repo's first five days, and scope the
old estimate left out (localization, legacy .xls, Power Query and the data model,
collaboration, mobile, AI).
By dimension
| Dimension | Ready for real work | Hours to parity | Doc |
|---|---|---|---|
| Features (13 areas, table below) | ~59% (breadth ~75%) | 300–485 | target-app-parity.md |
| UI/UX fidelity | ~55% | 50–80 | ui-parity.md |
| File formats | ~50% | 80–120 | file-format-parity.md |
| Performance | ~35% | 35–55 | target-app-parity.md |
| Stability | ~60% | 15–25 | gaps.md |
| Localization | ~10% (ribbon in 6 languages) | 100–165 | localization-parity.md |
| Hardware (multi-core calc, GPU, pen, multi-window) | ~40% | 25–40 | hardware-parity.md |
| Platforms | ~80% (no iOS/Android; ahead on Linux, BSD, RISC-V) | 30–60 | target-app-parity.md |
| Ecosystem / add-ins | ~10% (VBA out of scope; own scripts, MCP, CLI) | 25–40 | target-app-parity.md |
| AI features | ~15% (agent control strong; no in-app assistant) | 30–50 | target-app-parity.md |
| Total | ~50% | ~700–1,100 |
Features
| Area | Breadth | Ready | Hours | Doc |
|---|---|---|---|---|
| Formula language and calculation | ~92% | ~72% | 20–30 | target-app-parity.md |
| Worksheet functions | 96.6% measured | ~82% | 16–26 | function-parity.md |
| Editing, navigation, clipboard, fill | ~90% | ~70% | 15–25 | ui-parity.md |
| Cell formatting, styles, conditional formatting | ~95% | ~80% | 8–14 | target-app-parity.md |
| Sort, filter, tables, validation, outline | ~82% | ~70% | 10–16 | target-app-parity.md |
| PivotTables | ~65% | ~45% | 25–40 | target-app-parity.md |
| Charts and sparklines | ~50% | ~30% | 40–60 | chart-parity.md |
| Page layout, print, PDF | ~80% | ~55% | 12–20 | target-app-parity.md |
| What-if and analysis (Goal Seek, Solver, ToolPak, Forecast) | ~50% | ~40% | 22–35 | target-app-parity.md |
| Get & Transform, external data, data model | ~15% | ~10% | 60–100 | target-app-parity.md |
| Insert objects (pictures, shapes, ink, SmartArt, equations) | ~55% | ~45% | 25–40 | target-app-parity.md |
| Review, comments, protection, collaboration | ~55% | ~40% | 35–55 | target-app-parity.md |
| Automation (recorded scripts; typed macros with a recorder, a Macros dialog and a step editor; no VBA) | ~30% | ~20% | 12–20 | target-app-parity.md |
Languages
The ribbon is translated into Japanese, Simplified Chinese, Korean, Brazilian Portuguese, Russian and German (266–268 labels each, ~12% of ~2,200 strings; merged 10-10 in #31, #104, #82, German added 10-11), the interface follows the system language, and CJK, Thai and Hebrew text falls back to system fonts (#38). Japanese (10-17) and Brazilian Portuguese also translate the dialog titles and labels, message boxes, Backstage/File-view items, template names and native menus: 943 strings each, ~43%. The remaining dialogs, menus and messages are English; formulas and number formats are en-US only. Localized German formulas and numbers are in PR #163. Detail: localization-parity.md.
| Language | Code | Status | UI strings |
|---|---|---|---|
| English | en | full (source language) | 100% |
| Simplified Chinese | zh-Hans | menus only | ~12% |
| Spanish | es | none | 0% |
| Hindi | hi | none | 0% |
| Arabic | ar | none (no RTL layout, no shaping) | 0% |
| French | fr | none | 0% |
| Portuguese | pt-BR | menus, File view, dialogs | ~43% |
| Indonesian | id | none | 0% |
| Japanese | ja | menus, File view, dialogs, messages | ~43% |
| German | de | menus only | ~12% |
| Korean | ko | menus only | ~12% |
| Vietnamese | vi | none | 0% |
Other shipped languages: 3 (Russian and German, menus only, ~12%; Dutch, menus, File view and dialog titles, ~24%).
Upcoming
Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in docs/roadmap.md.
- Land the open PR queue (50 open PRs on 2026-10-10, many fixing listed gaps: recalc and spill correctness, chart kind round-trip, CJK font fallback, macOS Finder open, German and Chinese UI). Review and merge: 8–15 h.
- XLSX fidelity on a real-world corpus, with Excel opening our output without repair: 25–35 h.
- Large workbooks and recalc speed: 100 MB XLSX, 1M rows, multi-threaded recalc: 40–60 h.
- Charts depth: kinds and options round-trip, axes, trendlines, error bars: 25–35 h.
- Text in every script (CJK, Thai, Arabic, Devanagari) in cells and PDF: 12–20 h.
- Legacy
.xlsimport and password-protected workbooks: 20–30 h. - Localization: extend the catalog past the ribbon, then the twelve languages: 100–165 h.
Progress log
| Date | What landed |
|---|---|
| 2026-11-02 | Solver writes a Sensitivity report: Simplex LP shadow prices, reduced costs and allowable ranges from the final tableau; GRG Nonlinear reduced gradients and Lagrange multipliers from difference gradients, at a Karush-Kuhn-Tucker point only; Solver Results offers it where it applies (no score change) |
| 2026-11-02 | Floating objects: charts, pictures, shapes and slicers share one selection with a frame of eight resize handles (each moves only its own edges, also on right-to-left sheets); Delete or Backspace deletes the selected object and Escape drops the selection; slicers follow row and column edits and sorts like the other objects; chart series follow cut-moves and sheet renames and deletes; a copied sheet gives its objects fresh ids; ui.inspect reports selectedObject and ui.object.select selects any object (#190, #213) |
| 2026-11-01 | Chart data tables are available from Chart Design › Add Chart Element and Format Chart Area. Tables follow live source values and number formats, keep blank cells blank, offer legend keys and border settings, and survive XLSX save/reopen; the shared renderer includes them in print and PDF. Readiness estimates unchanged. |
| 2026-11-01 | XLSX keeps the first visible workbook window's active sheet and display settings together, falling back to the first view when all are hidden. Tab ratios are normalized to 0–1000 on import and export; invalid numeric text uses 600. Synthetic round trips cover isolated attributes, missing views, and active tabs after sheet deletion/reordering; firstSheet remains separate #2264 work (#3057). |
| 2026-10-31 | Esc in File › Info, Print or Options first leaves the text field; the next Esc returns to the sheet (#3035) |
| 2026-10-31 | CSV and text open detects each column's date order: a value that reads only day first (31/05/2026) makes the column day first, a value that reads only month first (12/31/2026) makes it month first, an all-ambiguous column keeps month first with a warning, and a column with both kinds stays text with a warning (#2765) |
| 2026-10-31 | Recently Used lists the functions most recently entered in a formula from any source (ribbon, control channel, MCP, scripts), kept with the preferences and returned by formulas.recentlyUsed; the Insert Function dialog takes Excel's title and a working category list (Most Recently Used, All, each category) |
| 2026-10-31 | Formulas › Function Library as a big Insert Function button, the AutoSum split button and three columns of labelled small buttons, each category book in its own colour; category menus end with Insert Function… on that category; More Functions cascades into the remaining categories; Home › Editing shares the AutoSum menu; the MR key tip opens Recently Used |
| 2026-10-25 | AutoSum over a selection does what Excel does: a selected row gets one total to its right (in its last cell if that is empty), not a one-cell total under each cell; a block whose last column is empty gets each row's total there, one whose last row is empty each column's, and with both the corner gets the total of the block; otherwise totals go under each column as before |
| 2026-10-24 | Macro interface (macros.md): an Automate › Macros group (Record Macro, which turns into Stop Recording, Use Relative References, Run Macro with recent macros); "Recording · N steps" with Stop in the status bar; a Record Macro dialog (checked name, free Ctrl+Shift shortcut, description); the Macros dialog lists macros beside Automate scripts and a VBA project, with Run, Step Into, Edit, Create, Delete and Options; Ctrl+Shift+letter macro shortcuts; questions that offer Run, Overwrite, Shift Down or Shift Right; a step editor with a breakpoint gutter, drag to reorder, a command picker, reference boxes that switch between relative tokens and absolute references, Inputs and Output tabs, a debug bar (Check, Run, Step, Continue, Run to Here, Stop with keep or undo) and grid overlays for inputs, writes, conflicts and the current step |
| 2026-10-24 | Go To lists the named ranges of every sheet (Sheet2!Name for a name scoped to another sheet; hidden names, constants and formulas left out) and the references entered before, a double-click goes to an entry, and the Reference box takes several names or references separated by commas (Price, Type, B14:C22,F19:G30) |
| 2026-10-24 | Status bar: a right-click opens a menu that sets which selection statistics show (Average, Count and Sum by default; Numerical Count, Minimum and Maximum are new), kept with the preferences (view.statusBar) |
| 2026-10-24 | Ctrl+Shift+U (Control+Shift+U on a Mac) expands and collapses the formula bar, on the grid and while editing (view.expandFormulaBar); on Windows and Linux it used to underline |
| 2026-10-24 | Fill handle: from a date, the right-drag menu and the Auto Fill Options button offer Fill Days, Fill Weekdays (Saturday and Sunday skipped), Fill Months and Fill Years |
| 2026-10-24 | PivotTables: Enable show details (pivot.options enableShowDetails); turned off, Show Details and double-clicking a value cell list no records, and XLSX files keep the setting (enableDrill) |
| 2026-10-24 | PivotTables: right-clicking a value, subtotal or grand total cell offers Show Details in the cell menu, which lists the cell's source records on a new sheet as double-clicking does |
| 2026-10-24 | Sheet tabs: dragging the handle between the tabs and the horizontal scrollbar gives the tabs more or less of the bar, as in Excel; each open workbook keeps its own share |
| 2026-10-24 | Charts: 100% Stacked Area (insert.chart {type: "area", subtype: "stacked100"}), drawn as each value's share of its category's total; XLSX percentStacked area charts open as 100% stacked instead of stacked |
| 2026-10-23 | Accounting negatives in text: $(1,234), $ (5) and (5)% read as negative numbers when typed, coerced by arithmetic or passed to VALUE, like Excel 365; (-5), ((5)), $5% and dates or times in parentheses stay text |
| 2026-10-23 | Calc: INDEX(A1:C3,2) (one index on a reference of several rows and columns) is #REF! as in Excel, instead of the whole row; INDEX(A1:C3,2,) still gives the row |
| 2026-10-22 | Formula hardening: digits too many for a finite number are text, so "1 <400 digits>/<400 digits>" no longer coerces to NaN; a NaN column index in VLOOKUP, HLOOKUP and the D-functions is #VALUE! instead of an index underflow; REGEXREPLACE stops building a result as soon as it can only be too long (a worst case went from 1 GB to 7 MB) (#2163, #2162) |
| 2026-10-22 | View › New Window and Arrange All on the ribbon. Arrange All tiles, stacks side by side or top to bottom, or cascades the native windows over the main window's monitor, the active one first. Two windows on one workbook show different sheets without copying the workbook or marking it changed; Save records the sheet of the window used last. A dialog stays in the window it was opened in |
| 2026-10-22 | On the desktop every workbook window is a native window of its own: New, Open and New Window open one, each keeps its own cell draft, dialog and ribbon, and the macOS menu bar acts on the window focused last. Closing one of several windows on a workbook doesn't ask; closing a workbook's last window, or quitting, asks about unsaved changes in that window. The last window closed quits on Windows and Linux; macOS keeps running with the menu bar. First craft-libs craft-window use (window list and viewport driver) |
| 2026-10-22 | View › New Window opens a second window on the same workbook (it used to open a copy whose Save overwrote the original): each window has its own selection, active sheet and scroll, titles read "Book1:1" / "Book1:2", and Switch Windows, Hide, Unhide and Close act per window. The control channel, CLI send and MCP tools take an optional window or doc id and default to the active window; window.list (MCP list_windows) lists the windows |
| 2026-10-22 | Typing in a cell and then choosing File › New no longer strands the first workbook: the entry is committed into its own workbook before any File or window command (a refused entry stays open and stops the command), View › Switch Windows and the macOS Window menu list the open workbooks with unsaved markers, view.switchWindows {doc} switches by a stable workbook id, and the macOS Quit item asks about unsaved workbooks |
| 2026-10-21 | Page Setup paper sizes match Japanese Excel: B4/B5/B6 are the JIS sizes (ISO B4/B5/B6 stay reachable by name), so a Japanese B5 worksheet prints at 182×257 mm; Japanese Postcard (100×148 mm), Double Postcard (148×200 mm), Envelope #3/#4 (120×235/90×205 mm), Kaku #2/#3 (240×332/216×277 mm) and A6 are added, both sizes reach the PDF page (file.exportPdf/file.print MediaBox) and the size survives an XLSX round-trip; the Page Layout Size menu lists them. B4/B5 used to be the ISO sizes, which is changed here |
| 2026-10-20 | Japanese interface catalog covers every key the Brazilian Portuguese catalog translates: the 398-label shared core plus 545 dialog, message, Backstage and menu strings (943 total, ~43% of ~2,200). A test parses pt.rs's source, so the two catalogs stay in step |
| 2026-10-20 | Interface translated into Dutch (518 labels: ribbon, context menus, File view, dialog titles, Options); nl, nl-NL, nl-BE locale tags resolve to Dutch |
| 2026-10-19 | Long flat operator chains (=A1+A2+…) up to Excel's 8,192-character limit (4,096 operands): entering, filling, inserting rows, undo, Evaluate Formula and XLSX save no longer overflow the stack; chains past 64 operands are saved as plain formulas, not dynamic arrays; Spanish formula entry accepts chains past 256 operands (#916) |
| 2026-10-19 | Linux: "Use system setting" for the theme keeps following the desktop when the XDG Desktop Portal stops answering: each read gives up after 2 s and the next poll reconnects, where one unanswered call stalled the watcher for the rest of the session |
| 2026-10-16 | Memory: undo steps share a sheet's picture bytes and the workbook's VBA project instead of copying them: 50 edits on a sheet with a 20 MB picture keep 22 MB instead of 992 MB |
| 2026-10-16 | Memory: floating pictures are decoded at about the size they are drawn, with limits, into a cache bounded by bytes and dropped with their workbook, instead of at full size into one that never let go; two open workbooks no longer show each other's picture. 12 large pictures scrolled through keep 40 MB of textures instead of 258 MB, and none once the workbook closes |
| 2026-10-16 | The web app keeps its preferences between visits (#1562): theme (dark mode), interface size, language, editing options and the rest of what the desktop app saves in ui.json and prefs.json are kept in the browser's localStorage, written as soon as they change |
| 2026-10-16 | Memory: the interface and script fallback fonts are read once per run and shared with egui instead of copied into it: an empty workbook settles at 158 MB instead of 258 MB on macOS |
| 2026-10-15 | File › Options › Formulas: Maximum Iterations and Maximum Change fields for iterative calculation, disabled while it is off, with Excel's limits (1 to 32767, 0 or more) |
| 2026-10-15 | Function help follows the interface language: argument hints, autocomplete, Insert Function (search and readable categories) and the Formulas-tab menus read per-language tables of descriptions and argument names; Spanish keeps its 10 functions in the new format |
| 2026-10-15 | Row auto-fit counts a cell's line breaks only when the cell wraps, as Excel does: a file whose unwrapped cells hold multi-line text no longer opens with tall rows (typing a break still turns wrap on and grows the row) |
| 2026-10-14 | Lookups (MATCH, XMATCH, VLOOKUP, HLOOKUP, XLOOKUP, LOOKUP) compare numbers exactly like Excel, so a computed key such as =0.1+0.2 no longer finds 0.3; = and COUNTIF/SUMIF keep their 15-digit comparison |
| 2026-10-14 | Functions: EOMONTH, EDATE, WORKDAY, NETWORKDAYS, YEARFRAC, WEEKNUM, the bond and coupon functions, DISC, BIN2DEC, IM* and the other Analysis ToolPak functions give #VALUE! for a reference to more than one cell in a value argument, as Excel 365 does, instead of spilling; array constants and computed arrays still lift |
| 2026-10-14 | Protect Sheet on a protected sheet: Home › Format, its keytips (HOP, RPS) and the tab menu now read Unprotect Sheet… and unprotect (straight away without a password); a protected sheet that forbids selecting locked (or unlocked) cells is enforced for clicks, arrows and Go To, and the Protect Sheet dialog has the select options (#1346) |
| 2026-10-14 | .xls (Excel 97-2003) files open with their formatting: fonts, solid and pattern fills, borders (with diagonals), alignment (rotation, indent, wrap, shrink), locked and hidden cells, the workbook's custom colour palette, its Normal font and its user-defined cell styles |
| 2026-10-14 | XLSX: formulas opened with dynamic-array metadata (cm) keep it on save, with xl/metadata.xml. Before, a formula returning one value lost it (11 of 40 corpus files that have the part lost it entirely), and Excel recalculated some of them with implicit intersection (SUMPRODUCT(IFERROR(...)) changed value) |
| 2026-10-14 | Recalculation: a dynamic array's anchor given a new formula that reads its old spill area (A1 was =SEQUENCE(3), becomes =SUM(A2:A3)+1 or =SEQUENCE(1,A2+1)) sees that area empty instead of the old values |
| 2026-10-14 | Recalculation: when two arrays of one recalculation want the same empty cells, the formulas that read the one laid out second (at its anchor or over the cells it would have spilled into) read #SPILL! and empty cells instead of its values |
| 2026-10-14 | Border keytips: each Alt, H, B letter applies the preset Excel's Borders menu gives it (H,B,O bottom, H,B,B bottom double, H,B,N no border, H,B,A all borders and the rest); they all drew a bottom border before. H,B,M opens Format Cells on the Border tab |
| 2026-10-13 | Formula-entry Command/Ctrl-click inserts another reference with the locale's argument separator; Shift-click extends from a stable, sheet-aware anchor. Pointer tests cover repeated clicks, reversed ranges, ordinary replacement, typed separators, Spanish syntax, sheet switches and keyboard continuation. Readiness estimates unchanged. |
| 2026-10-13 | formulas.evaluate (gridcraft-cli eval, MCP evaluate_formula) refuses what entering the formula in a cell refuses, with the reason (=SUM(1;2): "expected , or )"), instead of #NAME? for any formula that doesn't parse |
| 2026-10-13 | Colour menus: Fill Color, Font Color and the Format Cells pickers end with Recent Colors (the last ten custom colours) and More Colors… (hue/saturation area, RGB, hex box, preview, OK/Cancel) (#928) |
| 2026-10-13 | Multi-level category axes: a category range two or more columns wide beside a column of values (year beside month, Excel's multiLvlStrRef) draws its innermost labels across the plot and the outer levels in rows under them with group separators (columns beside the labels in bar charts), instead of flattening the two columns into twice as many categories; saving writes the reference back as multiLvlStrRef with Excel's level caches, so the axis survives a round trip |
| 2026-10-13 | Charts: a huge trendline forecast no longer collapses the chart: on a category axis it adds at most four times the data in empty slots (at least 32), the line is sampled over the plot only, and forecasts read from XLSX or set by command are clamped, NaN and infinity becoming 0 (#1148) |
| 2026-10-13 | XLSX export writes a picture used on several sheets once, as one xl/media part every drawing points to (it wrote a copy per drawing: a 16-sheet workbook with one 112 KB logo grew from 0.4 to 1.9 MB) (#985) |
| 2026-10-13 | XLSX: [Content_Types].xml, _rels/.rels, the workbook rels and xl/workbook.xml are the first zip entries (document properties last), so libmagic and PHP finfo detect the file type even with large properties (#1090) |
| 2026-10-13 | Conditional formatting: a rule gathers range statistics only when it reads them (top/bottom, above average, duplicates, scales, bars, icons) and borrows them instead of copying them per cell, so the per-frame lookup of an expression or cell-value rule no longer visits its whole range (#1098, part 1) |
| 2026-10-12 | Next/previous sheet navigation stops at the first/last visible worksheet instead of activating a hidden boundary sheet; the current selection is retained |
| 2026-10-21 | Macro engine (macros.md): typed, declarative macros saved in the workbook (a JSON field; hidden names in xlsx); declared inputs checked with messages that name the cells; tokens (Input.col(2), Row, Output, Name:Total, {{…}} in formulas); one undo step with full rollback; a footprint dry run with ask, fail, overwrite, shift down or shift right; a policy that keeps macros away from files and the app, with approval for macros in opened files; Repeat, If and Stop steps; a debugger; a relative recorder; macro.* commands beside the unchanged Automate scripts |
| 2026-10-12 | Security: the --control server requires an auth token (random, kept in a 0600 file or chosen with GRIDCRAFT_CONTROL_TOKEN) on each connection's first line and closes bad connections (#777) |
| 2026-10-12 | Rows auto-fit oversized fonts: opening a file and whole-row/column formatting grow non-custom rows to their tallest font (#833) |
| 2026-10-12 | Number formats: parsing a format code is linear in its length (long runs of [, , or / no longer take quadratic time), and an unclosed [ is a literal when splitting sections as well as when tokenizing (#810) |
| 2026-10-12 | Number formats: a fraction denominator with 65,536 zeros no longer crashes; format codes are capped at 255 characters like Excel (longer codes display as General, TEXT gives #VALUE!) (#807) |
| 2026-10-12 | Security: cell hyperlinks open only http, https and mailto, after a confirmation; other schemes (file:, smb:, UNC, custom handlers) are refused (#777, part 1) |
| 2026-10-12 | Deleting several Ctrl-selected rows or columns removes them all in one undo step (#758) |
| 2026-10-12 | XLSX chart sheets are kept on open and save: the sheet, its drawing and chart (with style and colours) are written back unchanged in their place among the worksheets, and left out when the sheet they plot is deleted or renamed or a worksheet took their name (#727) |
| 2026-10-12 | CSV and tab-separated export is capped at 512 MiB: a sheet whose used range would expand to more (two cells far apart, such as A1 and XFD1048576, are 16 GiB of commas) is refused with the rows, columns and limit, before anything is allocated or written (#528) |
| 2026-10-12 | PDF writer hardening: text width cannot overflow, all-zero dash arrays and negative or NaN stroke widths are sanitised, non-finite sizes and positions draw nothing (#812) |
| 2026-10-12 | PDF export writes the document title and author as UTF-16BE when they are not ASCII, so viewers show accents, currency signs and non-Latin text correctly (#813) |
| 2026-10-12 | TEXT() over a range and chart labels parse each number format code once instead of once per value (#806) |
| 2026-10-12 | SUBTOTAL(109) over hidden rows recalculates after Row Height, AutoFit Row Height and Ungroup reveal rows (found by the command-sequence fuzz) |
| 2026-10-12 | Page Layout view: drag the margin edges on the rulers to set the page margins (resize cursor, live preview, value tooltip, one undo step, Esc cancels) (#792) |
| 2026-10-12 | Forecast Sheet gets Forecast Start: begin the forecast inside the history to compare it with the actuals (#785) |
| 2026-10-12 | Ink strokes save as unfilled DrawingML paths and reopen as editable ink with their points, colour and width; icons in #551 remain a follow-up |
| 2026-10-12 | The selection outline stays visible when extended to the last row (Ctrl+Shift+Down): its sides are cut to the viewport instead of stroking a 20-million-point rectangle (#687) |
| 2026-10-12 | File › Print selects a system printer, copies, duplex and grayscale, submits PDF jobs through craft-print on a worker and shows spooler errors; browser printing and PDF export remain available |
| 2026-10-11 | UI building blocks: theme tokens with a WCAG contrast test over both themes (icons and reference colours follow dark mode); ribbon scroll arrows and a large split button (Formulas › AutoSum opens its menu); the formula bar grows from one to five lines, then scrolls; a code editor widget with Python and LaTeX colouring |
| 2026-10-11 | Command-sequence fuzzing: random command sequences checked against undo/redo, XLSX round-trip and full recalculation; fixes for the table, legacy-array, spill, AutoSum, Watch Window and sheet-copy bugs it found |
| 2026-10-11 | Password-protected workbooks open: GridCraft asks for the password and decrypts Agile and Standard encryption (#11) |
| 2026-10-11 | Text boxes keep their formatting: run size, bold, italic, typeface, text colour and outline, alignment, vertical anchor and "no outline" (#377) |
| 2026-10-11 | Desktop printing opens the print PDF in the system viewer; Save As offers CSV, web page and PDF; macOS File › Properties opens File › Info (#370, #343) |
| 2026-10-11 | Windows: DirectX 12 shaders compile with FXC, so a missing or stray dxcompiler.dll no longer stops the app at start (#339, #354) |
| 2026-10-11 | Merged cells draw their whole outline: right and bottom edges come from the last column's and last row's cells (#376) |
| 2026-10-11 | Shrink to fit draws too-wide text and numbers in a smaller font inside the cell or merged area (#375) |
| 2026-10-11 | Shift+Space and Ctrl+Space select the row / column without starting an edit; Control+Space on Mac (#338) |
| 2026-10-11 | Workbooks reopen at their saved scroll position (topLeftCell, also with frozen panes) and save the current one back (#378) |
| 2026-10-11 | Protect Sheet passwords use Excel-compatible hashes and round-trip in XLSX sheetProtection (imported passwords verify instead of being dropped) |
| 2026-10-11 | Review › Protect Workbook opens a dialog with an optional password (Excel-compatible hash, kept in XLSX workbookProtection); unprotecting verifies it (#345) |
| 2026-10-11 | Formula bar, name box and dialogs fall back to the cell font: Hebrew (and any script cells can show) no longer turns into boxes there (#349) |
| 2026-10-11 | Headers and footers: first-page and odd/even variants are read, kept, printed and edited in Page Layout view; Insert › Header & Footer edits the header in place (#344) |
| 2026-10-11 | Legacy Excel 97-2003 .xls (BIFF8) import with formulas, number formats, merges, sizes and names (#121) |
| 2026-10-11 | XLSX pass-through: custom XML, external links, connections, query tables, printer settings, form/ActiveX controls and OLE objects are kept on save (#330, #324) |
| 2026-10-11 | Data › Forecast › Forecast Sheet: a new sheet with the history, FORECAST.ETS forecast, confidence bounds, statistics and a chart (#322) |
| 2026-10-11 | Startup no longer panics on a system font egui can't parse: fonts are validated and skipped (#226) |
| 2026-10-11 | Ctrl+drag on the fill handle swaps copying and extending a series (#264) |
| 2026-10-11 | Odd-period bond functions ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD: Financial 55 / 55 (#275) |
| 2026-10-11 | PERCENTOF and EUROCONVERT worksheet functions (#279) |
| 2026-10-11 | BAHTTEXT: amounts in Thai words with Baht and Satang (#291) |
| 2026-10-11 | TRIMRANGE: ranges and arrays without blank outer rows and columns (#296) |
| 2026-10-11 | Selected charts, pictures and shapes can be deleted from the keyboard (#213) |
| 2026-10-11 | Ribbon translated into German (266 labels; de, de-DE, de-AT, de-CH locale tags resolve to German) |
| 2026-10-11 | View › Interface size: a saved 75–200 % scale for the whole window (#230) |
| 2026-10-11 | View › Formula Bar and Zoom 100% reachable from the CLI and MCP (#289) |
| 2026-10-11 | Freeze panes by dragging the freeze handles on the header edges (#195) |
| 2026-10-11 | XLSX: threaded comments (replies, resolved, timestamps) and note visibility survive a save (#300) |
| 2026-10-11 | Cell checkboxes: Insert › Checkbox on the ribbon, Excel's Delete and value rules, XLSX round trip as Excel cell controls (#196) |
| 2026-10-11 | Review › Allow Edit Ranges with Excel-compatible password hashes, kept in XLSX (#307) |
| 2026-10-11 | PivotTable calculated fields (pivot.calculatedField), evaluated on sums like Excel, with XLSX round-trip (#304) |
| 2026-10-11 | PivotCharts (insert.pivotChart): charts bound to a PivotTable's report, following refreshes and layout changes (#311) |
| 2026-10-11 | FORECAST.ETS, FORECAST.ETS.CONFINT, FORECAST.ETS.SEASONALITY, FORECAST.ETS.STAT: AAA exponential smoothing forecasts (#314) |
| 2026-10-11 | File tab Backstage view (Home, New, Open, Info, Save As, Print preview, Export, Options) and file.options (#174) |
| 2026-10-10 | Ribbon translated into Japanese, Chinese, Korean, Brazilian Portuguese and Russian with system-language default (#31, #104, #82); CJK/Thai/Hebrew font fallback (#38); clear messages for encrypted and .xls files (#17); smooth line charts (#62). Progress docs restructured; full re-measure (this page). Initial ribbon key tips (#43), in-place text box editing (#84), copy as HTML table (#36). ODS and XLSB data import (#100, #101); recalc linear in the number of range formulas (#66); RISC-V Linux build; Flatpak repository on Pages; web cell-commit trap fixed |
| 2026-10-09 | Community fixes: spill range operator A1#, sheet-scoped names, protection refuses locked-cell edits, Insert/Delete Cells adjust references, DATE(1900,2,29), SUMIF sizing, ROUND at 15 digits, _xlpm. LAMBDA parameters in XLSX, vertical scrollbar, system appearance, border previews; v0.4.0 |
| 2026-10-08 | v0.2.0 and v0.3.0 releases; Flatpak, AppImage zsync, branded DMG; desktop log file; DirectX 12 default on Windows |
| 2026-10-07 | About window with contributor and model credits; macOS release runner |
| 2026-10-06 | M0–M13 first pass: engine, 478 functions, XLSX/CSV, egui UI, charts, PivotTables with XLSX round-trip, PDF and printing, what-if, spelling, Draw, task panes, MCP, CLI, web build, release packaging |
| 2026-10-05 | Repository created |
Revision history
| Date | Change | Summary |
|---|---|---|
| 2026-11-02 | minor | What-if and analysis: Solver Sensitivity report for Simplex LP and GRG Nonlinear (no score change) |
| 2026-11-02 | minor | Progress log: one selection and eight resize handles for every floating object |
| 2026-11-01 | minor | Chart data tables are available from Chart Design › Add Chart Element and Format Chart Area. Tables follow live source values and number formats, keep blank cells blank, offer legend keys and border settings, and survive XLSX save/reopen; the shared renderer includes them in print and PDF. Readiness estimates unchanged. |
| 2026-11-01 | trivial | Workbook views: selected window settings stay together, tab ratios are bounded, and regressions cover isolated settings and sheet edits; readiness estimates unchanged (#3057) |
| 2026-10-31 | minor | File-page text fields keep the view open when Esc cancels an edit (#3035) |
| 2026-10-31 | minor | Progress log: Recently Used and Insert Function categories |
| 2026-10-31 | minor | Progress log: Function Library |
| 2026-10-25 | minor | Progress log: AutoSum over a selected row, and a selection's empty last row and column |
| 2026-10-24 | minor | Macro interface on the Automate tab; progress log row |
| 2026-10-24 | minor | Macro engine and macro.* commands; catalog 275 / 291 → 276 / 292 (View › Macros › Record Macro); progress log row |
| 2026-10-23 | minor | Progress log: accounting negatives in number text |
| 2026-10-23 | minor | Progress log: INDEX with one index on a 2-D reference is #REF! |
| 2026-10-22 | trivial | Progress log: formula hardening (#2163, #2162) |
| 2026-10-22 | minor | Progress log: Arrange All; two windows on one workbook without copying it |
| 2026-10-22 | minor | Progress log: a native window per workbook window |
| 2026-10-22 | minor | Progress log: New Window shares the workbook; window ids for scripts and MCP |
| 2026-10-22 | minor | Progress log: drafts stay in their workbook, Switch Windows, macOS Quit asks to save |
| 2026-10-21 | minor | Page Setup paper sizes: JIS B4/B5/B6 (ISO by name), Japanese postcards and envelopes, A6; PDF page size follows, XLSX round-trips |
| 2026-10-20 | minor | Dutch (nl) listed under other shipped languages; progress log row |
| 2026-10-19 | minor | Progress log: long flat operator chains (#916) |
| 2026-10-19 | trivial | Progress log: desktop theme portal read timeout |
| 2026-10-16 | minor | Progress log: undo steps share picture and macro bytes |
| 2026-10-16 | minor | Progress log: floating pictures' textures bounded and kept per workbook |
| 2026-10-16 | trivial | Progress log: web preferences kept between visits (#1562) |
| 2026-10-16 | minor | Progress log: interface fonts held once instead of twice |
| 2026-10-14 | minor | Progress log: .xls import reads cell formatting |
| 2026-10-14 | minor | Progress log: lookups compare numbers exactly |
| 2026-10-14 | minor | Progress log: Analysis ToolPak value arguments reject multi-cell references |
| 2026-10-14 | minor | XLSX dynamic-array cm metadata kept on save; progress log row |
| 2026-10-14 | minor | Progress log: spill anchor reading its old spill area |
| 2026-10-14 | minor | Progress log: formulas reading an array that loses a spill conflict |
| 2026-10-13 | trivial | Progress log: More Colors… and Recent Colors in the colour menus (#928) |
| 2026-10-13 | minor | Multi-level category axes (read, drawn, written); progress log row |
| 2026-10-13 | trivial | Progress log: shared pictures written once on XLSX export (#985) |
| 2026-10-13 | minor | Progress log: conditional-format lookups no longer scan the range for rules without statistics (#1098) |
| 2026-10-12 | minor | Progress log: hidden-sheet navigation at workbook boundaries |
| 2026-10-12 | minor | The control server requires an auth token and closes bad connections (#777); progress log row |
| 2026-10-12 | minor | Rows auto-fit oversized fonts on open and whole-row/column formatting (#833); progress log row |
| 2026-10-12 | minor | Progress log: multi-area row/column delete (#758) |
| 2026-10-12 | trivial | Progress log: XLSX chart sheets kept on save (#727) |
| 2026-10-12 | trivial | Progress log: CSV export size cap (#528) |
| 2026-10-12 | minor | Progress log: margins dragged on the Page Layout rulers (#792) |
| 2026-10-12 | minor | Ink preservation across XLSX save/reopen (ink portion of #551) |
| 2026-10-12 | minor | Desktop File > Print now discovers printers and submits PDF jobs through pinned craft-print with printer choice, copies, duplex and grayscale; browser printing and PDF export remain available. Remaining print parity includes page ranges and driver-specific tray/options UI; physical printer fidelity needs hardware validation. |
| 2026-10-11 | minor | UI building blocks; progress log row |
| 2026-10-11 | minor | Password-encrypted workbooks open (#11); progress log row |
| 2026-10-11 | minor | Forecast Sheet (#322); progress log row |
| 2026-10-11 | minor | Worksheet functions 505 / 523 (ODD* bond functions); progress log row |
| 2026-10-11 | minor | Worksheet functions 503 / 523 (PERCENTOF, EUROCONVERT); progress log row |
| 2026-10-11 | minor | Worksheet functions 502 / 523 (BAHTTEXT); progress log row |
| 2026-10-11 | minor | Worksheet functions 502 / 523 (TRIMRANGE); progress log row |
| 2026-10-11 | minor | Selected objects can be deleted from the keyboard (#213) |
| 2026-10-11 | minor | Catalog 258 → 260 / 290: View › Formula Bar and Zoom 100% (#289) |
| 2026-10-11 | minor | Progress log: XLSX threaded comments round trip (#300) |
| 2026-10-11 | minor | Catalog 258 → 259 / 290: Allow Edit Ranges (#307) |
| 2026-10-11 | minor | Worksheet functions 505 / 523 (FORECAST.ETS family); progress log row |
| 2026-10-11 | minor | Czech (cs) listed under other shipped languages: ribbon only, ~12% |
| 2026-10-10 | minor | Readiness-by-audience table with hours to ~95% per audience; full number unchanged (additive weighted sum) |
| 2026-10-10 | minor | Added Mainstream practitioner (~50%) and Essentials user (~63%); languages updated for the 10-10 merges (ribbon in ja, zh, ko, pt-BR, ru); localization 5%→10%; full number re-checked (51.6, unchanged) |
| 2026-10-10 | minor | Checked against the alpha gate (six core workflows pass): stays alpha |
| 2026-10-10 | major | Re-measured against Excel for Mac 16.113.4: stage alpha, breadth ~75%, ready ~50%, ~160–240 h to beta, ~700–1,100 h to full parity; progress docs restructured; detail moved to docs/ |
| 2026-10-07 | major | First estimates: catalog 89%, functions ~93%, depth ~65%, ~35 h to alpha, ~215 h to full parity |