Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
166 commits
Select commit Hold shift + click to select a range
3f3afc3
test(toolbar): fail closed after image upload lifecycle changes
seonghobae Aug 10, 2026
6da5eab
fix(toolbar): stop stale image upload continuations
seonghobae Aug 10, 2026
faf7c2f
test(spreadsheet): establish XLS/XLSX body import RED
seonghobae Aug 13, 2026
46fc0a5
chore(ci): preserve installed dependency build files
seonghobae Aug 13, 2026
1571a25
chore(ci): stage exact spreadsheet parser for local TDD
seonghobae Aug 13, 2026
7a0d1cf
feat(spreadsheet): convert visible worksheet text
seonghobae Aug 13, 2026
d8462dc
test(spreadsheet): assert complete imported worksheet rows
seonghobae Aug 13, 2026
3b053a8
test(spreadsheet): cover stable import error contract
seonghobae Aug 13, 2026
9e70d93
test(spreadsheet): cover worksheet fidelity boundaries
seonghobae Aug 13, 2026
1b059db
fix(spreadsheet): preserve worksheet table fidelity
seonghobae Aug 13, 2026
fa81b40
test(spreadsheet): cover resource limit boundaries
seonghobae Aug 13, 2026
7c36809
fix(spreadsheet): preflight conversion resource limits
seonghobae Aug 13, 2026
b2eef9b
test(spreadsheet): bound visible worksheet count
seonghobae Aug 14, 2026
89a1795
fix(spreadsheet): bound visible worksheet materialization
seonghobae Aug 14, 2026
3443bb6
test(spreadsheet): expose aggregate import limits
seonghobae Aug 14, 2026
0b1cb3d
fix(spreadsheet): preflight aggregate import limits
seonghobae Aug 14, 2026
4787124
test(spreadsheet): preflight impossible row counts
seonghobae Aug 14, 2026
11b6407
fix(spreadsheet): preflight worksheet row counts
seonghobae Aug 14, 2026
db2de30
test(spreadsheet): bound worksheet heading text
seonghobae Aug 14, 2026
2bf4efe
fix(spreadsheet): include headings in text budget
seonghobae Aug 14, 2026
e28bb2d
test(spreadsheet): require bounded binary source preflight
seonghobae Aug 14, 2026
bb8ac96
test(spreadsheet): make source size preflight observable
seonghobae Aug 14, 2026
d29c689
feat(spreadsheet): bound binary source envelope
seonghobae Aug 14, 2026
24099b5
test(spreadsheet): reject non-byte binary sources
seonghobae Aug 14, 2026
ba4934f
test(spreadsheet): use real oversized byte source
seonghobae Aug 14, 2026
e53f885
fix(spreadsheet): validate binary byte sources
seonghobae Aug 14, 2026
c955594
test(spreadsheet): bypass byte-length accessors
seonghobae Aug 14, 2026
4c8f458
fix(spreadsheet): bypass byte-length accessors
seonghobae Aug 14, 2026
793402b
test(spreadsheet): reject runtime metadata coercion
seonghobae Aug 15, 2026
b5cee21
fix(spreadsheet): validate runtime metadata primitives
seonghobae Aug 15, 2026
5cb7754
test(spreadsheet): reject malformed runtime containers
seonghobae Aug 15, 2026
07e0364
fix(spreadsheet): validate runtime container shapes
seonghobae Aug 15, 2026
8182f94
test(spreadsheet): reject primitive workbook containers
seonghobae Aug 15, 2026
a76c505
fix(spreadsheet): validate workbook container
seonghobae Aug 15, 2026
4325927
test(spreadsheet): reject nullish worksheet entries
seonghobae Aug 15, 2026
77f7a92
fix(spreadsheet): validate worksheet container
seonghobae Aug 15, 2026
73a8315
test(spreadsheet): bound worksheet heading metadata
seonghobae Aug 15, 2026
c00990b
fix(spreadsheet): bound worksheet heading metadata
seonghobae Aug 15, 2026
373f6d6
fix(spreadsheet): remove redundant text preflight branch
seonghobae Aug 15, 2026
507807f
test(spreadsheet): require framework-neutral package surface
seonghobae Aug 15, 2026
bbb7480
test(spreadsheet): fix package-surface fixture path
seonghobae Aug 15, 2026
597dda8
feat(spreadsheet): publish bounded package surface
seonghobae Aug 15, 2026
6e821d3
docs(package): discover spreadsheet subpath
seonghobae Aug 15, 2026
6adf43d
ci(spreadsheet): verify official SheetJS parser provenance
seonghobae Aug 15, 2026
6e76761
test(reliability): prove toolbar leaks hostile image failures
seonghobae Aug 16, 2026
84cb2b1
fix(reliability): redact hostile toolbar image failures
seonghobae Aug 16, 2026
6117702
fix(ci): document spreadsheet package export
seonghobae Aug 16, 2026
920a4d3
test(spreadsheet): reject accessor-backed workbook metadata
seonghobae Aug 16, 2026
ecfc1fc
test(spreadsheet): redact metadata reflection failures
seonghobae Aug 16, 2026
42d2ae9
test(spreadsheet): cover missing metadata properties
seonghobae Aug 16, 2026
db0c637
fix(spreadsheet): preflight workbook metadata descriptors
seonghobae Aug 16, 2026
a22485c
test(spreadsheet): exercise public package barrel
seonghobae Aug 16, 2026
98ee151
test(toolbar): reject unsafe links before editor commands
seonghobae Aug 16, 2026
2f15737
test(spreadsheet): reject hostile collection access
seonghobae Aug 16, 2026
ceb79a7
test(spreadsheet): preserve safe proxied array data
seonghobae Aug 16, 2026
cd9b267
fix(spreadsheet): snapshot collection data without getters
seonghobae Aug 16, 2026
0693ba3
fix(toolbar): enforce safe-link policy before commands
seonghobae Aug 16, 2026
041e726
test(reliability): contain toolbar image observer failures
seonghobae Aug 16, 2026
d448a9d
fix(reliability): contain toolbar image observer failures
seonghobae Aug 16, 2026
519a04f
test(spreadsheet): bound workbook worksheet descriptors
seonghobae Aug 16, 2026
ad0b338
fix(spreadsheet): bound total worksheet descriptors
seonghobae Aug 16, 2026
c96fbe1
test(spreadsheet): normalize revoked array containers
seonghobae Aug 16, 2026
bfd8394
fix(spreadsheet): normalize revoked array containers
seonghobae Aug 16, 2026
28c4671
test(spreadsheet): establish SheetJS adapter boundary
seonghobae Aug 16, 2026
7676b2d
docs(spreadsheet): converge parser provenance and ADR ownership
seonghobae Aug 16, 2026
7d47e02
feat(spreadsheet): implement bounded SheetJS adapter
seonghobae Aug 16, 2026
4d5f2c2
test(spreadsheet): cover parser trust boundaries and row preflight
seonghobae Aug 16, 2026
9e30a15
test(spreadsheet): type parser failure fixtures explicitly
seonghobae Aug 16, 2026
970d208
fix(spreadsheet): bound SheetJS row parsing
seonghobae Aug 16, 2026
66252d2
test(spreadsheet): require aggregate parser row budgeting
seonghobae Aug 16, 2026
4e9ce87
fix(spreadsheet): enforce aggregate parser row budget
seonghobae Aug 16, 2026
cb4d4a9
test(spreadsheet): align adapter contract with aggregate parser budge…
seonghobae Aug 16, 2026
5fdcdb3
test(spreadsheet): bound parser output before cell inspection
seonghobae Aug 16, 2026
19f4a92
fix(spreadsheet): bound materialized parser output
seonghobae Aug 16, 2026
9fa103c
test(spreadsheet): require real SheetJS workbook parsing
seonghobae Aug 16, 2026
7b1f218
test(spreadsheet): isolate real parser runtime boundary
seonghobae Aug 16, 2026
f55b436
test(spreadsheet): persist hidden worksheet metadata
seonghobae Aug 16, 2026
5641f31
feat(spreadsheet): add pinned SheetJS runtime adapter
seonghobae Aug 16, 2026
095458e
feat(spreadsheet): export local SheetJS runtime
seonghobae Aug 16, 2026
7892ae8
chore: sync spreadsheet branch with current protected main
seonghobae Aug 17, 2026
ffa5488
ci(spreadsheet): expose generated dependency blobs without moving refs
seonghobae Aug 17, 2026
99dcbb8
fix(spreadsheet): commit exact SheetJS dependency graph
seonghobae Aug 17, 2026
4744d83
chore(spreadsheet): remove temporary workspace generator
seonghobae Aug 17, 2026
d81824f
fix(spreadsheet): verify package-owned lazy parser chunk
seonghobae Aug 17, 2026
b8d67ba
test(spreadsheet): define local file import boundary
seonghobae Aug 17, 2026
3609619
feat(spreadsheet): add bounded local file import bridge
seonghobae Aug 17, 2026
bc9dbf9
test(spreadsheet): cover hostile local file identities
seonghobae Aug 17, 2026
ba36b83
fix(spreadsheet): bind local bytes to declared file size
seonghobae Aug 17, 2026
76700fe
test(toolbar): define accessible spreadsheet insertion
seonghobae Aug 17, 2026
302ae5d
feat(toolbar): insert local XLS and XLSX worksheets
seonghobae Aug 17, 2026
9f1c8b7
test(toolbar): account for spreadsheet control
seonghobae Aug 17, 2026
9117a98
test(spreadsheet): normalize real SheetJS array fixture
seonghobae Aug 17, 2026
dcf9f6f
fix(editor): make spreadsheet status precise and non-conflicting
seonghobae Aug 17, 2026
fec40f4
test(editor): align spreadsheet status assertions with live-region co…
seonghobae Aug 17, 2026
4daf83b
test(spreadsheet): enforce direct parser source-byte ceiling
seonghobae Aug 17, 2026
1099831
fix(spreadsheet): bound the public byte-array parser entry
seonghobae Aug 17, 2026
ef26cf6
test(spreadsheet): assert atomic insertion at editor boundary
seonghobae Aug 17, 2026
ea216ca
test(spreadsheet): close toolbar import coverage gaps
seonghobae Aug 17, 2026
101371b
test(spreadsheet): verify real BIFF8 XLS import
seonghobae Aug 17, 2026
547526f
test(spreadsheet): cover real inert workbook values
seonghobae Aug 17, 2026
bebb5ba
test(spreadsheet): expose host failure callback
seonghobae Aug 17, 2026
90a01be
feat(spreadsheet): expose host import failure callback
seonghobae Aug 17, 2026
91116de
feat(spreadsheet): forward host import failure callback
seonghobae Aug 17, 2026
5838cc0
feat(spreadsheet): connect public import error path
seonghobae Aug 17, 2026
9a828a5
test(spreadsheet): preserve BIFF8 sheet visibility fixture
seonghobae Aug 17, 2026
26af04e
chore: synchronize toolbar reliability lane with protected main
seonghobae Aug 17, 2026
5f98788
test(spreadsheet): fail closed across async host boundaries
seonghobae Aug 17, 2026
f32b4d7
fix(toolbar): converge async import trust boundaries
seonghobae Aug 17, 2026
51267d3
merge: stack spreadsheet import on toolbar reliability
seonghobae Aug 17, 2026
89b5b77
fix(spreadsheet): bind visibility to parsed sheet index
seonghobae Aug 17, 2026
a4ed7e5
test(spreadsheet): pin workbook visibility metadata authority
seonghobae Aug 17, 2026
3ce9826
test(spreadsheet): scope visibility metadata regression to BIFF8
seonghobae Aug 17, 2026
7729cdb
fix(spreadsheet): preserve BIFF8 workbook visibility metadata
seonghobae Aug 17, 2026
ddd52fa
test(spreadsheet): require preflight before parser load
seonghobae Aug 17, 2026
371f2ea
fix(spreadsheet): preflight bytes before parser load
seonghobae Aug 17, 2026
fb052c8
test(spreadsheet): cover empty BIFF8 discovery
seonghobae Aug 17, 2026
c88bc4f
test(spreadsheet): isolate BIFF8 visibility metadata
seonghobae Aug 17, 2026
d8ac925
test(spreadsheet): trace real BIFF8 visibility through adapter
seonghobae Aug 17, 2026
df6c950
test(spreadsheet): localize BIFF8 visibility boundary
seonghobae Aug 17, 2026
8d5c124
test(spreadsheet): compare BIFF8 browser byte representations
seonghobae Aug 17, 2026
dff699b
test(spreadsheet): isolate copied-byte adapter behavior
seonghobae Aug 17, 2026
1f56dc2
test(spreadsheet): require isolated parser-loader preflight seam
seonghobae Aug 17, 2026
05627ee
fix(spreadsheet): isolate parser load behind binary preflight
seonghobae Aug 17, 2026
ab2577b
fix(spreadsheet): preserve pristine BIFF8 visibility metadata
seonghobae Aug 17, 2026
0db8513
test(spreadsheet): bind BIFF8 discovery to pristine visibility pass
seonghobae Aug 17, 2026
dce85ca
test(spreadsheet): snapshot BIFF8 visibility before body reads
seonghobae Aug 17, 2026
069e735
fix(spreadsheet): snapshot BIFF8 visibility before body parsing
seonghobae Aug 17, 2026
895dbf3
test(spreadsheet): require repeatable BIFF8 source parsing
seonghobae Aug 17, 2026
e868187
test(spreadsheet): isolate BIFF8 visibility across workbook imports
seonghobae Aug 17, 2026
773862d
fix(spreadsheet): isolate BIFF8 parser source bytes
seonghobae Aug 17, 2026
b2a38b2
test(spreadsheet): isolate BIFF8 visibility parser input
seonghobae Aug 17, 2026
7fad29e
fix(spreadsheet): separate BIFF8 visibility parser source
seonghobae Aug 17, 2026
44ddb09
test(spreadsheet): require one-snapshot BIFF8 parsing
seonghobae Aug 17, 2026
8a34afd
fix(spreadsheet): parse BIFF8 from one bounded snapshot
seonghobae Aug 17, 2026
e8a66cb
fix(spreadsheet): bind BIFF8 visibility to raw workbook records
seonghobae Aug 17, 2026
3942e03
test(spreadsheet): distrust parser BIFF8 visibility metadata
seonghobae Aug 17, 2026
1deac43
fix(spreadsheet): parse BIFF8 CFB bytes as buffer input
seonghobae Aug 17, 2026
e0a53ac
fix(spreadsheet): normalize documented CFB byte arrays
seonghobae Aug 17, 2026
849391f
fix(spreadsheet): accept cross-realm CFB byte views
seonghobae Aug 17, 2026
c9bd5ba
fix(spreadsheet): ignore blank-only parser ranges
seonghobae Aug 17, 2026
1e98158
test(spreadsheet): cover blank BIFF8 parser range
seonghobae Aug 17, 2026
ba1fc4e
test(spreadsheet): harden BIFF8 runtime validation coverage
seonghobae Aug 17, 2026
c3ed931
test(spreadsheet): avoid accessor subclass in BIFF8 validation
seonghobae Aug 17, 2026
2273a6d
test(spreadsheet): reject revoked parser sheet names
seonghobae Aug 17, 2026
c4ff522
fix(spreadsheet): normalize hostile sheet-name arrays
seonghobae Aug 17, 2026
e02080e
test(spreadsheet): cover selective worksheet identity checks
seonghobae Aug 17, 2026
7ae2073
test(spreadsheet): keep selective validation assertions explicit
seonghobae Aug 17, 2026
00a2965
fix(spreadsheet): insert genuine XLS/XLSX files into the document body
cursoragent Aug 17, 2026
de27e43
test(spreadsheet): copy workbook bytes before constructing File
cursoragent Aug 17, 2026
aa5b97d
test(spreadsheet): fail closed on hostile source brands
seonghobae Aug 17, 2026
39d869a
fix(spreadsheet): redact hostile File and ArrayBuffer brand traps
cursoragent Aug 17, 2026
eafd7d4
test(spreadsheet): cover hostile ArrayBuffer length access
seonghobae Aug 17, 2026
eab2dbc
fix(spreadsheet): redact hostile ArrayBuffer length accessors
cursoragent Aug 17, 2026
addd3a6
test(spreadsheet): reject non-buffer body before length access
seonghobae Aug 17, 2026
9d55ec5
fix(spreadsheet): reject non-ArrayBuffer bodies before length access
cursoragent Aug 17, 2026
2dbbc7f
test(release): enforce canonical four-file inventory
seonghobae Aug 17, 2026
d8c26ac
test(release): cover canonical inventory documents
seonghobae Aug 17, 2026
d6cc52f
docs(release): align canonical inventory with the four-file contract
cursoragent Aug 17, 2026
3ca35dd
test(docs): detect stale Markdown package maturity
seonghobae Aug 17, 2026
ca45df7
docs: align Markdown package maturity with protected main
seonghobae Aug 17, 2026
63a424a
fix(docs): restore #156 ownership of markdown maturity
seonghobae Aug 17, 2026
5a013ac
fix(tests): keep markdown maturity contract in #156
seonghobae Aug 17, 2026
0fd42aa
chore(spreadsheet): relinquish release-contract ownership
seonghobae Aug 18, 2026
cd251dc
chore(spreadsheet): drop release-operability ownership
seonghobae Aug 18, 2026
83e9727
chore(spreadsheet): drop release-test-strategy ownership
seonghobae Aug 18, 2026
fce8fe7
chore(spreadsheet): relinquish release consistency contract
seonghobae Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Historical release entries from **0.1.0 through 0.5.27** are preserved verbatim

## [Unreleased]

### Added

- Active PR / Proposed: local XLS/XLSX worksheet insertion into the current document. A toolbar control reads a user-selected `.xls` or `.xlsx` file in memory, projects only visible displayed cell text into a heading and table, and announces the imported worksheet/row/cell counts. Formulas, macros, hyperlinks, and hidden sheets receive no editor authority. This is not protected-main behavior until the branch merges.

## [0.6.0] — 2026-08-10

### Release
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ runtime.
| Text-position selector | `@contextualwisdomlab/cwl-editor/text-position-selector` | React-free deterministic W3C `TextPositionSelector` projection core |
| Autosave | `@contextualwisdomlab/cwl-editor/autosave` | Provider-neutral bounded single-flight persistence coordination |
| Headless Markdown | `@contextualwisdomlab/cwl-editor/markdown` | React-free deterministic Markdown/HTML/email/plain-text conversion |
| Spreadsheet conversion | `@contextualwisdomlab/cwl-editor/spreadsheet` | Active PR: bounded local XLS/XLSX worksheet-to-document conversion used by the editor toolbar |
| Styles | `@contextualwisdomlab/cwl-editor/styles.css` | Editor layout and theming |
| Full fonts | `@contextualwisdomlab/cwl-editor/fonts.css` | KR/EN/JP/SC/TC/VI offline font bundle |
| Latin fonts | `@contextualwisdomlab/cwl-editor/fonts-latin.css` | Smaller Latin/Vietnamese-only bundle |
Expand Down
6 changes: 6 additions & 0 deletions docs/CONTRACTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ Model-assisted authoring is separate from deterministic conversion and validatio

The host owns model/provider selection, credentials, external-data-use approval, redaction, prompt retention, model logging, tenancy, authorization, human approval, and audit. No model may authorize a save, bypass deterministic validation, or redefine a revision/durable-validator contract.

## Local spreadsheet body-import contract

Active PR / Proposed under ADR 0032. The public `@contextualwisdomlab/cwl-editor/spreadsheet` subpath and the editor toolbar accept local `.xls`/`.xlsx` bytes, project visible displayed cell text into one TipTap insertion batch, and reject hidden sheets, formulas, macros, and hyperlinks as executable authority. Source size is bounded before the file body is read. Genuine `File` values are read through `arrayBuffer()` when present, otherwise `FileReader` or `Response`. Failures are payload-redacted. This contract is not protected-main authority.

Hosts retain transport, authorization, persistence, retention, and any later sharing of the inserted document. Worksheet names remain authoring labels and are not PII-masked in this lane.

## Deterministic Office conversion contract

Office rendering accepts versioned bounded JSON and produces supported DOCX/XLSX/PPTX artifacts without model, network, macro, or Desktop Office dependency. Inputs must satisfy XML 1.0, size/depth/container/cycle, spreadsheet, worksheet-name, freeze-pane, supported-structure, and formula-injection rules before publication.
Expand Down
1 change: 1 addition & 0 deletions docs/DOCUMENTATION_FITNESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Document fitness and implementation maturity are independent. A `present_current
| DOCX bounded paragraph alignment | ADR 0024, Office schema/renderer/tests, Office guidance and doctoring | `present_current` | `implemented_on_protected_main` | `paragraph` and `rich_paragraph` preserve explicit left/center/right/justify alignment while omission retains inherited/default behavior. |
| DOCX bounded heading alignment | ADR 0025, Office schema/renderer/tests, Office guidance and doctoring | `present_current` | `implemented_on_protected_main` | `heading` preserves the same exact left/center/right/justify contract through the shared paragraph-alignment authority while omission retains heading-style/default behavior. |
| DOCX bounded external hyperlinks | ADR 0026, Office schema/renderer/tests, Office guidance and doctoring | `present_current` | `implemented_on_protected_main` | Optional rich-run hyperlinks preserve exact accepted external HTTP(S) targets and existing run emphasis through deterministic relationship-backed OOXML without network, credential, local-file, tenant, persistence, or destination-trust authority. |
| Bounded local spreadsheet body import | Proposed ADR 0032, spreadsheet subpath, toolbar insertion and known-workbook editor tests | `present_current` | `implemented_on_active_pr` | Local XLS/XLSX files insert visible displayed cells as editable headings/tables without upload, formula execution, or protected-main authority. |
| THREAT_MODEL | `docs/THREAT_MODEL.md` | `present_current` | Covers current trust boundaries and explicitly proposed extensions | Clipboard, evidence, Office, SSR/form, Yjs, model, host-authority and supply-chain threats are reconstructable. |
| TEST_STRATEGY | `docs/TEST_STRATEGY.md` | `present_current` | Protected deterministic/browser/Office evidence plus feature-specific test contracts | Test authority, exact source-head evidence and claim limits are explicit rather than inferred from CI badges. |
| OPERABILITY | `docs/OPERABILITY.md` | `present_current` | Current product responsibilities plus protected browser/release recovery boundaries | Conflict, collaboration, conversion, registry partial-publication recovery and rollback ownership are explicit. |
Expand Down
2 changes: 1 addition & 1 deletion docs/PRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,4 @@ Shareable acquisition evidence excludes production tenant content and credential

Protected `main` is the sole implemented baseline. Open PRs may describe Proposed or Active work but are not shipped contracts until protected integration. Canonical documentation must state when a requirement is target architecture rather than current implementation.

SafeClipboard, real Chromium/Firefox/WebKit release assurance, lifecycle observation, the root security disclosure lifecycle, toolbar shortcut accessibility metadata, SSR/native-form serialization, revision-scoped selection evidence, W3C text-position selector evidence, document-transition evidence, and envelope identity migration routing are implemented on protected `main`.
SafeClipboard, real Chromium/Firefox/WebKit release assurance, lifecycle observation, the root security disclosure lifecycle, toolbar shortcut accessibility metadata, SSR/native-form serialization, revision-scoped selection evidence, W3C text-position selector evidence, document-transition evidence, and envelope identity migration routing are implemented on protected `main`. Local XLS/XLSX worksheet insertion into the document body is `implemented_on_active_pr` under Proposed ADR 0032 and is not a shipped claim.
1 change: 1 addition & 0 deletions docs/TEST_STRATEGY.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ At minimum, maintain regressions for:
- autosave stale validators, conflict/failure recovery, ambiguous transport outcomes, duplicate/no-op lifecycle transitions, callback exceptions, queue bounds, flush/close behavior, and durable-validator coherence;
- selection/revision races and document movement during asynchronous hashing;
- Office formula prefixes, invalid XML characters, malicious strings, path/publication races, invalid worksheet names, invalid freeze panes, cyclic input, pathological nesting, excessive container size, and partial write failure;
- local XLS/XLSX body import from a known small workbook File through the real toolbar/editor path, including asserted heading/cell text, hidden-sheet exclusion, formula/link non-execution, FileReader fallback when `arrayBuffer` is absent, and payload-redacted failures;
- package/release stale draft assets, unexpected or non-regular local entries, exact three-file inventory violations, incomplete remote uploads, GitHub-vs-local digest mismatch, stale exact-head evidence, mutable provenance inputs, and isolated packed-consumer behavior.

## Concurrency and failure testing
Expand Down
4 changes: 4 additions & 0 deletions docs/THREAT_MODEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ Untrusted clipboard HTML can attempt script execution, external resource fetches

URLs or image-like content can exfiltrate document context, induce unexpected network access, or smuggle executable/active payloads. Inkspan validates only supported local semantics and does not grant network authority. Hosts remain responsible for downstream CSP, fetch policy, proxy/egress controls, content serving, and tenant authorization.

### Local spreadsheet body import

Untrusted local XLS/XLSX bytes can carry macros, formulas, hyperlinks, hidden sheets, and hostile object graphs. Active-PR import (ADR 0032) must parse only after ZIP/OLE preflight, insert only visible displayed/cached cell text, and keep parser exceptions, file names, formulas, and hidden values out of ordinary status text. Missing `File.arrayBuffer` is not a reason to reject a genuine local workbook when `FileReader` or `Response` can read the same Blob. The parser still has no network, credential, persistence, or model authority.

### Spreadsheet formula injection

XLSX cell values beginning with formula-significant prefixes can become executable spreadsheet formulas when opened by a user. Deterministic Office rendering must preserve the documented formula-injection neutralization boundary and never silently convert untrusted strings into formulas. No macro, network, or Desktop Office execution is part of the renderer contract.
Expand Down
17 changes: 11 additions & 6 deletions docs/TRACEABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ This record maps durable Inkspan product decisions to authoritative standards, p
| Editor integration | Public behavior must exercise the actual TipTap/ProseMirror integration path, not an inert extension field or test-only hook | official TipTap and ProseMirror documentation for the locked dependency line | integration tests and package consumers | Inkspan does not claim compatibility with untested major-version integration semantics |
| Collaboration | Inkspan provides provider-neutral editor/Yjs bindings; host owns provider lifecycle, room authorization, awareness privacy, persistence and audit | official Yjs/provider documentation plus Inkspan public contract | collaboration tests and architecture ownership matrix | No network-provider or tenant-authorization authority is implied |
| Secure development | Security controls are developed test-first, with exact-head scanning/review/package evidence and root-cause regression | NIST SP 800-218 SSDF 1.1 | CI/security/SAST/package/provenance gates, doctoring and regression history | Repository evidence is not a claim of complete SSDF organizational conformance |
| Local spreadsheet body import | Visible XLS/XLSX worksheet text is inserted locally as inert headings/tables after ZIP/OLE preflight, BIFF8 BoundSheet8 visibility recovery, and File/FileReader/Response body reads | ECMA-376; [MS-XLS]; SheetJS CE; WAI-ARIA 1.2 status/live regions | Proposed ADR 0032, active-PR spreadsheet runtime/editor insertion tests and `./spreadsheet` package surface | `implemented_on_active_pr`; not protected-main authority; no upload, formula execution, macro, network, or destination-trust claim |
| Office rendering | JSON→DOCX/XLSX/PPTX is deterministic, bounded, network-free, macro-free, injection-aware and package-inspected | Office Open XML specifications and relevant Python package contracts | Office renderer tests, Python coverage/docstring/package gates | Format fidelity is limited to explicitly tested supported constructs |
| DOCX informative PNG figures | Informative figures accept only bounded inline PNG data, explicit alt text, bounded dimensions/bytes and deterministic WordprocessingML output | Office Open XML drawing semantics; python-docx public picture APIs | protected-main #121 renderer/schema/tests, ADR 0022 and PNG doctoring | No remote/file/SVG/JPEG fetch, decorative-image claim, arbitrary drawing authority, or image-based model inference is implied |
| DOCX bounded rich-text runs | `rich_paragraph` preserves ordered bold/italic/underline run emphasis through a strict bounded JSON contract | Office Open XML run semantics; python-docx run API | protected-main #124 renderer/schema/tests, ADR 0023 and rich-run doctoring | No arbitrary Word styles, font/color/size, hyperlink, field-code, tracked-change, raw-OOXML or source-format parsing authority is implied |
Expand All @@ -46,17 +47,19 @@ Fielding, R., Nottingham, M., & Reschke, J. (Eds.). (2022). *HTTP Semantics* (RF

MacFarlane, J. (2024, January 28). *CommonMark specification* (Version 0.31.2). CommonMark. https://spec.commonmark.org/0.31.2/

Microsoft. (n.d.-a). *Browsers*. Playwright documentation. Retrieved August 10, 2026, from https://playwright.dev/docs/browsers
Microsoft. (n.d.-a). *[MS-XLS]: Excel Binary File Format (.xls) Structure*. Microsoft Learn. Retrieved August 17, 2026, from https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls

Microsoft. (n.d.-b). *Hyperlink class (DocumentFormat.OpenXml.Wordprocessing)*. Microsoft Learn. Retrieved August 10, 2026, from https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.hyperlink
Microsoft. (n.d.-b). *Browsers*. Playwright documentation. Retrieved August 10, 2026, from https://playwright.dev/docs/browsers

Microsoft. (n.d.-c). *HyperlinkRelationship class (DocumentFormat.OpenXml.Packaging)*. Microsoft Learn. Retrieved August 10, 2026, from https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.packaging.hyperlinkrelationship
Microsoft. (n.d.-c). *Hyperlink class (DocumentFormat.OpenXml.Wordprocessing)*. Microsoft Learn. Retrieved August 10, 2026, from https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.hyperlink

Microsoft. (n.d.-d). *Projects*. Playwright documentation. Retrieved August 10, 2026, from https://playwright.dev/docs/test-projects
Microsoft. (n.d.-d). *HyperlinkRelationship class (DocumentFormat.OpenXml.Packaging)*. Microsoft Learn. Retrieved August 10, 2026, from https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.packaging.hyperlinkrelationship

Microsoft. (n.d.-e). *Release notes: Version 1.62*. Playwright. Retrieved August 10, 2026, from https://playwright.dev/docs/release-notes
Microsoft. (n.d.-e). *Projects*. Playwright documentation. Retrieved August 10, 2026, from https://playwright.dev/docs/test-projects

Microsoft. (n.d.-f). *Working with paragraphs*. Microsoft Learn. Retrieved August 10, 2026, from https://learn.microsoft.com/en-us/office/open-xml/word/working-with-paragraphs
Microsoft. (n.d.-f). *Release notes: Version 1.62*. Playwright. Retrieved August 10, 2026, from https://playwright.dev/docs/release-notes

Microsoft. (n.d.-g). *Working with paragraphs*. Microsoft Learn. Retrieved August 10, 2026, from https://learn.microsoft.com/en-us/office/open-xml/word/working-with-paragraphs

Node.js contributors. (2026). *Modules: Packages*. Node.js documentation. https://nodejs.org/api/packages.html

Expand All @@ -68,6 +71,8 @@ python-docx. (n.d.-b). *Working with text*. Retrieved August 10, 2026, from http

Rundgren, A., Jordan, B., & Erdtman, S. (2020). *JSON Canonicalization Scheme (JCS)* (RFC 8785). RFC Editor. https://doi.org/10.17487/RFC8785

SheetJS. (n.d.). *SheetJS CE*. Retrieved August 17, 2026, from https://docs.sheetjs.com/

Souppaya, M., Scarfone, K., & Dodson, D. (2022). *Secure Software Development Framework (SSDF) Version 1.1: Recommendations for Mitigating the Risk of Software Vulnerabilities* (NIST SP 800-218). National Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-218

Web Hypertext Application Technology Working Group. (2026). *HTML Standard: Parsing HTML documents* (Living Standard). Retrieved August 10, 2026, from https://html.spec.whatwg.org/multipage/parsing.html
Expand Down
2 changes: 1 addition & 1 deletion docs/TRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@ Queued, cancelled, skipped-required, absent, stale-head, predecessor-head, statu

Protected `main` is the sole shipped implementation baseline. SafeClipboard, cross-engine browser assurance, the security disclosure lifecycle, autosave lifecycle observation, toolbar shortcut accessibility metadata, accessible editor placeholder semantics, SSR/native-form serialization, revision-scoped selection evidence, W3C text-position selector evidence, the React-free text-position-selector subpath, document-transition evidence, envelope identity routing, framework-neutral deterministic Markdown conversion, CSS paged-media print output, DOCX informative PNG figures, bounded rich-text runs, bounded paragraph alignment, bounded heading alignment, and the OIDC-backed unified stable registry release train are `implemented_on_protected_main`.

The bounded DOCX rich-run external hyperlink contract in #137 is `implemented_on_active_pr` under Proposed ADR 0026. Open branches may extend the protected boundary, but no active-PR capability becomes shipped merely because its design, tests, or documentation are complete.
The bounded DOCX rich-run external hyperlink contract in #137 is `implemented_on_active_pr` under Proposed ADR 0026. Local XLS/XLSX worksheet body import in #318 is `implemented_on_active_pr` under Proposed ADR 0032. Open branches may extend the protected boundary, but no active-PR capability becomes shipped merely because its design, tests, or documentation are complete.
2 changes: 2 additions & 0 deletions docs/accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ Disabled table, image, undo, and redo controls are skipped by directional naviga

Toggle controls expose `aria-pressed`; one-shot command buttons do not claim a pressed state. The toolbar declares horizontal orientation and ships visible `:focus-visible` styling, including a forced-colors fallback.

The **Insert XLS/XLSX spreadsheet** control is a one-shot command. It opens a hidden local file picker, disables itself while the selected workbook is imported, and reports progress plus imported worksheet/row/cell counts through the toolbar's polite `aria-live` status region. Failures announce only `Spreadsheet import failed.` so assistive technology is told the next action — choose another supported file — without hearing file names, worksheet names, or cell text. This control is Active PR / Proposed under ADR 0032 and is not protected-main behavior.

After the image file passes the existing local conversion, type, size, and decode policy, the toolbar asks for alternative-text intent before creating the image node. A non-empty response becomes the image alternative text; an explicitly submitted empty response marks the image decorative with `alt=""`; canceling leaves the document unchanged. Conversion failures continue through `onImageError` and do not open the alternative-text prompt. The separate **Alt** control remains available for later corrections when an image is selected.

Shortcuts that the editor already implements are also exposed programmatically with `aria-keyshortcuts` so assistive technology can discover the same commands that appear in the button titles. Inkspan publishes `Control+B Meta+B` for bold, `Control+I Meta+I` for italic, `Control+K Meta+K` for link editing, `Control+Z Meta+Z` for undo, and `Control+Shift+Z Meta+Shift+Z Control+Y Meta+Y` for redo. The redo alternatives reflect Tiptap's configured history and collaboration behavior: both `Ctrl/Cmd+Shift+Z` and `Ctrl/Cmd+Y` invoke redo. `aria-keyshortcuts` describes shortcuts that Inkspan already implements; it does not create keyboard behavior, replace the visible button label, or authorize hosts to intercept those combinations. The explicit values remain `Control` and `Meta` rather than a presentation-only `Ctrl/Cmd` abbreviation because WAI-ARIA defines those modifier tokens and permits a space-separated list of alternatives.
Expand Down
Loading
Loading