| new file mode 100644 |
| index 0000000..6bfb9aa |
| --- /dev/null |
| +++ b/docs/superpowers/plans/2026-09-07-workbook-import-fidelity.md |
| @@ -0,0 +1,35 @@ |
| +# Workbook import completeness: review draft |
| + |
| +Status: LLM-only implementation contract, unapproved; no production implementation. Baseline origin/main 4aea8f47153b907e6d8903df174a0b10d502922a. Branch test/xlsx-workbook-fidelity, Sheets discussion 23. Depends on workbook-tabs discussion 18, whose design remains unapproved and whose source branch currently adds no tab implementation. Do not merge the red regression candidate or deploy it. |
| + |
| +## Exact evidence and ownership |
| + |
| +POST /sheets/import accepts upload bytes and creates a hidden workbook through createFillingSheet. runImport opens its first tab, calls xlsx.Import, then markFilled clears FillingSince. Import selects GetSheetList()[0]; later worksheets are never read. GET /sheets/{sheetID}/export.xlsx opens SheetSummary.TabID and calls xlsx.Export; that writer creates a new one-worksheet file with its default name. Whole-workbook export belongs to discussion18, not this follow-up. |
| + |
| +Three tiny synthetic XLSX fixtures contain Summary and Inputs, with distinct numbers at A1. One has no formulas; two place a cached cross-tab formula at B1 on either the first or second worksheet. They were generated with the repository's pinned excelize, including its normal workbook metadata/styles. The real runImport lifecycle and real authenticated HTTP export demonstrate: |
| + |
| +- Literal two-worksheet import returns success with one stored tab; HTTP export returns one worksheet. |
| +- First-worksheet cross-tab formula fails at B1 and leaves the workbook hidden/deleted, which is the correct existing unsupported-feature behavior. |
| +- The later-worksheet formula is never parsed; import reports success and publishes the partial workbook. |
| + |
| +This is a documented first-worksheet limitation today, not a claim that current UI promises all worksheets: the settled spec explicitly defers later worksheets until a second tab is reachable. That trigger is the readiness dependency this draft addresses. Importing all worksheets into an unreachable UI is not an authorized shortcut. The current formula engine keys references by row/column only and has no worksheet grammar; tabs alone cannot make cross-tab formulas work. |
| + |
| +## Bounded adjacent implementation after review and reachable tabs |
| + |
| +1. Add a workbook-level import entry point in xlsx, leaving the existing single-tab converter as an explicit compatibility helper. Open the XLSX archive once using the existing decompression bounds. Enumerate every worksheet in workbook order, including empty worksheets, before any visible publication. Preserve names exactly through the reviewed tab-name validator/sealer; do not invent fallback or lossy rename behavior. |
| +2. Reuse discussion18's reviewed tab-count and workbook-cell limits when finalized. Keep the existing per-tab cell cap and compressed-upload/decompression limits. Count the whole workbook before writing, so one oversized later worksheet cannot produce success for an earlier one. Do not silently truncate or introduce a different cap in this draft. |
| +3. Keep one hidden workbook and its creator grant throughout filling. Create/seal tab metadata under an ordinary scoped transaction, then release it before opening any cell Handle: cell import uses the existing one-connection store path and cannot run inside an outer writer transaction. Import one tab handle at a time and release it before the next. Store every cell, formula, format and size through the existing sealed methods, never in a plaintext staging file. |
| +4. Parse formulas through the existing calc path on every worksheet. Unsupported cross-tab syntax is a workbook failure; never flatten its cached value, drop the cell/tab, rewrite the reference to the current tab or publish a partial workbook. Cross-tab evaluation requires a separate reviewed grammar/reference/dependency design. This slice does not implement it. |
| +5. Preserve runImport's hide-until-complete contract. On any tab-name, cell, formula, context, size or storage failure, keep the workbook hidden and use existing discard/error redaction. Clear FillingSince only after every worksheet completes and the workbook is still live. Check caller cancellation between worksheets and while processing bounded cell batches; publication must not race a cancelled/discarded import into visibility. |
| +6. Keep errors to existing codes and cell coordinates. No source worksheet names, formula text, cell values or uploaded file names in errors/progress/logs. Reuse existing import failure wording. Any UI statement about import scope is a separate reviewed copy dependency before shipping; no UI language is included here. |
| +7. Require the reviewed whole-workbook exporter from discussion18 for round-trip acceptance. Compare input/output worksheet count, exact names/order, distinct contents, formula text for supported same-tab formulas, formats and sizes. Re-import the exported file through the workbook importer and compare all tabs, not just snapshots of the first tab. |
| + |
| +## Scope corrections and review questions |
| + |
| +Current .xlsm upload handling accepts the extension and ignores macros; there is no verified general external-link/macro refusal policy to preserve. Discussion18's shorthand about existing unsupported-feature refusal must not be treated as evidence of one. This draft does not change that policy or claim broad Excel fidelity. |
| + |
| +No tab deletion, cross-tab formula implementation, formula rewriting, row/column identity redesign, new UI, new Estilo component, or changes to frozen reconciliation/tabs candidates. This import design needs independent Fable approval before implementation. Ask the reviewer to assess all-or-hidden failure behavior, empty worksheets, bounds before publication, compatible wrapper ownership, and formula rejection across later worksheets. Full release remains gated on reviewed tabs, exporter and importer together; a tab strip alone is not migration readiness. |
| + |
| +## Verification candidate |
| + |
| +internal/sheets/workbook_import_readiness_test.go exercises actual runImport and the authenticated export route with fixtures in internal/testdata/workbook-regressions. Current expected red cases are one retained tab/worksheet and later unsupported-formula publication; the first-tab refusal control is green and checks the failure coordinate. No implementation is hidden behind these tests. Root owns the Fable allocation and all integrations/deployments. |