Skip to content
Merged
Show file tree
Hide file tree
Changes from 126 commits
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
b33cde3
docs: design safe rich clipboard ingestion
seonghobae Aug 5, 2026
c33d642
docs: plan safe rich clipboard implementation
seonghobae Aug 5, 2026
c9ab5f8
test(clipboard): define safe rich paste contract
seonghobae Aug 5, 2026
16272b5
feat(clipboard): implement bounded rich HTML sanitizer
seonghobae Aug 5, 2026
6e0115b
feat(clipboard): add sanitizer to shared editor kit
seonghobae Aug 5, 2026
f3f0d67
test(clipboard): cover shared kit configuration
seonghobae Aug 5, 2026
c71acb0
feat(clipboard): expose editor paste policy props
seonghobae Aug 5, 2026
d06701a
feat(clipboard): wire standalone paste policy
seonghobae Aug 5, 2026
54736e2
feat(clipboard): wire collaborative paste policy
seonghobae Aug 5, 2026
7d8d1de
test(clipboard): cover standalone editor integration
seonghobae Aug 5, 2026
23b486d
test(clipboard): cover collaborative editor integration
seonghobae Aug 5, 2026
1a6b0eb
test(clipboard): use inferred extension contract
seonghobae Aug 5, 2026
e52c39a
feat(clipboard): export safe rich paste API
seonghobae Aug 5, 2026
2faf969
docs(clipboard): add operator security guide
seonghobae Aug 5, 2026
ffb85f2
docs(doctoring): record safe rich clipboard boundary
seonghobae Aug 5, 2026
4168586
docs: add Inkspan architecture and trust boundaries
seonghobae Aug 5, 2026
34baf71
docs(changelog): record safe rich clipboard slice
seonghobae Aug 5, 2026
26cd91f
fix(clipboard): type paste transform input
seonghobae Aug 5, 2026
9d30ecb
test(clipboard): preserve untrusted configuration identity
seonghobae Aug 5, 2026
80a5233
test(clipboard): use deterministic accessor spy
seonghobae Aug 5, 2026
dc85544
test(clipboard): defer standalone config validation to paste
seonghobae Aug 5, 2026
cc4b05d
test(clipboard): defer collaborative config validation
seonghobae Aug 5, 2026
a1c952e
fix(clipboard): validate preserved host config at paste
seonghobae Aug 5, 2026
2c67c41
fix(clipboard): preserve host config until paste validation
seonghobae Aug 5, 2026
9f188f2
test(clipboard): cover hidden-style and transform-order regressions
seonghobae Aug 5, 2026
f948fdd
fix(clipboard): harden Office hiding and final transform order
seonghobae Aug 5, 2026
c34a5bb
test(clipboard): assert removed elements through parsed output
seonghobae Aug 5, 2026
e2998b9
test(clipboard): inspect unwrapped elements structurally
seonghobae Aug 5, 2026
bae6033
test(docs): require clipboard assurance boundaries
seonghobae Aug 5, 2026
0772cf1
docs(clipboard): define paste and browser assurance boundaries
seonghobae Aug 5, 2026
aa23f03
docs(doctoring): record clipboard residual assurance risk
seonghobae Aug 5, 2026
a387a09
docs(changelog): record clipboard assurance hardening
seonghobae Aug 5, 2026
41c91b3
test(ci): require immutable exact-head verification
seonghobae Aug 5, 2026
e2fff37
ci: verify immutable exact pull-request heads
seonghobae Aug 5, 2026
7e48536
test(docs): require reconciled clipboard design records
seonghobae Aug 5, 2026
94df928
test: normalize clipboard documentation contracts
seonghobae Aug 5, 2026
db038d2
docs(clipboard): reconcile reviewed design and assurance limits
seonghobae Aug 5, 2026
94ed221
docs(clipboard): reconcile implementation plan after review
seonghobae Aug 5, 2026
610318d
test: cover clipboard fail-closed branches
seonghobae Aug 5, 2026
c3615e5
test(clipboard): cover absent ambient DOM branch
seonghobae Aug 5, 2026
e15104b
test(clipboard): cover CSS-escaped hidden declarations
seonghobae Aug 5, 2026
8991804
test(clipboard): cover CSS escape decoding boundaries
seonghobae Aug 5, 2026
5fe4915
fix(clipboard): decode bounded CSS escapes for hidden content
seonghobae Aug 5, 2026
8a704b6
test(docs): require CSS escape assurance evidence
seonghobae Aug 5, 2026
0be036e
docs(clipboard): document bounded CSS escape decoding
seonghobae Aug 5, 2026
b7aa88b
docs(doctoring): record CSS escape hidden-content defense
seonghobae Aug 5, 2026
cc8797b
test(docs): bind CSS escape decision to doctoring addendum
seonghobae Aug 5, 2026
d01dceb
docs: record CSS-escaped Office hidden handling
seonghobae Aug 5, 2026
3096782
test: close residual clipboard branch coverage
seonghobae Aug 5, 2026
dac8fef
test(clipboard): cover EOF-terminated CSS comments
seonghobae Aug 5, 2026
e6d51c9
fix(clipboard): consume EOF-terminated CSS comments
seonghobae Aug 5, 2026
e12fec9
docs(clipboard): record EOF CSS comment boundary
seonghobae Aug 5, 2026
ae38958
docs(clipboard): document EOF comment handling
seonghobae Aug 5, 2026
fd3b5ae
docs(changelog): record EOF CSS comment hardening
seonghobae Aug 5, 2026
c116170
test(clipboard): reject title metadata subtrees
seonghobae Aug 5, 2026
d9fcc0f
fix(clipboard): drop title metadata subtrees
seonghobae Aug 5, 2026
eebf18a
test(clipboard): expose closed disclosure text leakage
seonghobae Aug 5, 2026
e84261e
fix(clipboard): exclude closed interactive content
seonghobae Aug 5, 2026
2e52ec5
docs(clipboard): define closed interactive content boundary
seonghobae Aug 5, 2026
f0b0e49
docs(doctoring): record closed interactive clipboard boundary
seonghobae Aug 5, 2026
111925b
docs(changelog): record closed interactive sanitizer hardening
seonghobae Aug 5, 2026
ba97291
test(docs): bind closed interactive clipboard policy
seonghobae Aug 5, 2026
6e6d48f
test: reject native-widget fallback text
seonghobae Aug 5, 2026
01683cc
fix: drop native-widget fallback subtrees
seonghobae Aug 5, 2026
2269d36
docs: record fallback-content boundary
seonghobae Aug 5, 2026
6ab2272
docs: explain fallback-content sanitization
seonghobae Aug 5, 2026
aa7a556
docs: record fallback-content change
seonghobae Aug 5, 2026
75e96eb
test: bind fallback-content documentation
seonghobae Aug 5, 2026
a48d81e
test(clipboard): expose hidden datalist fallback text
seonghobae Aug 5, 2026
ec5d602
fix(clipboard): drop hidden datalist suggestion content
seonghobae Aug 5, 2026
5a17ec2
docs(clipboard): record hidden datalist boundary
seonghobae Aug 5, 2026
80e073c
docs(clipboard): document hidden datalist suggestions
seonghobae Aug 5, 2026
491e97e
test(docs): require datalist visibility evidence
seonghobae Aug 5, 2026
83429c3
docs(changelog): record datalist visibility boundary
seonghobae Aug 5, 2026
8335871
docs(clipboard): correct interactive record date metadata
seonghobae Aug 5, 2026
d356f08
docs(clipboard): correct native fallback decision date
seonghobae Aug 5, 2026
602bcd2
docs(clipboard): synchronize hidden boundaries and memory claims
seonghobae Aug 5, 2026
f8c24f6
docs(clipboard): correct review defect count
seonghobae Aug 5, 2026
46e744e
test(clipboard): prove representative Word capacity
seonghobae Aug 5, 2026
04657df
docs(types): clarify clipboard policy lifecycle
seonghobae Aug 5, 2026
6dadce2
test(clipboard): require one safe-link policy decision
seonghobae Aug 5, 2026
00d163e
refactor(clipboard): reuse safe-link classification
seonghobae Aug 5, 2026
77ea951
test(clipboard): reject visibility-collapse content
seonghobae Aug 6, 2026
503ba7f
fix(clipboard): drop visibility-collapse subtrees
seonghobae Aug 6, 2026
7a7efd1
docs(clipboard): record visibility-collapse boundary
seonghobae Aug 6, 2026
95dc3eb
test(docs): bind visibility-collapse decision
seonghobae Aug 6, 2026
3e369cb
test(clipboard): expose content-visibility hidden gap
seonghobae Aug 6, 2026
28df0b9
fix(clipboard): drop content-visibility hidden subtrees
seonghobae Aug 6, 2026
b830f49
test(docs): bind content-visibility hidden policy
seonghobae Aug 6, 2026
f5af554
docs(clipboard): define content-visibility hidden boundary
seonghobae Aug 6, 2026
b82405f
docs(doctoring): record content-visibility hidden decision
seonghobae Aug 6, 2026
20238fb
docs(architecture): preserve integrated modular contract
seonghobae Aug 6, 2026
baeaa89
docs(changelog): reconcile architecture and clipboard evidence
seonghobae Aug 6, 2026
ca7b417
test(ci): preserve exact-head evidence contract
seonghobae Aug 6, 2026
54d8a68
docs(ci): preserve exact-head evidence record
seonghobae Aug 6, 2026
2d47306
docs(changelog): isolate pending clipboard notes from integrated history
seonghobae Aug 6, 2026
50dcde8
Merge 2d47306043581a18db7e6ba0847e8368a0e34982 into ca49a3249403be88b…
seonghobae Aug 6, 2026
d69575e
test(clipboard): expose hidden popover content
seonghobae Aug 6, 2026
ee14bdb
fix(clipboard): drop hidden popover subtrees
seonghobae Aug 6, 2026
0af1410
test(clipboard): cover invalid popover default
seonghobae Aug 6, 2026
36e0e5a
docs(clipboard): record popover hidden-content policy
seonghobae Aug 6, 2026
2d38ccb
docs(clipboard): explain popover privacy boundary
seonghobae Aug 6, 2026
639eaf0
docs(changelog): record popover hidden-content fix
seonghobae Aug 6, 2026
7f0fa36
test(docs): bind popover policy evidence
seonghobae Aug 6, 2026
486846a
test(security): expose DOM capability reflection leakage
seonghobae Aug 6, 2026
e438765
fix(security): redact DOM capability reflection failures
seonghobae Aug 6, 2026
73585e5
docs(security): record DOM reflection redaction decision
seonghobae Aug 6, 2026
1e27f14
docs(changelog): record DOM capability reflection repair
seonghobae Aug 6, 2026
5c84b73
docs(security): document DOM capability failure boundary
seonghobae Aug 6, 2026
0c63934
test(docs): bind DOM reflection security evidence
seonghobae Aug 6, 2026
2e1d634
test(clipboard): exercise actual ProseMirror paste pipeline
seonghobae Aug 7, 2026
88bdd07
fix(clipboard): install sanitizer in ProseMirror paste pipeline
seonghobae Aug 7, 2026
ce95e56
fix(clipboard): use registered TipTap v2 adapter
seonghobae Aug 7, 2026
018b55e
fix(clipboard): export registered SafeClipboard adapter
seonghobae Aug 7, 2026
8070ed0
test(clipboard): verify collaborative ProseMirror paste path
seonghobae Aug 7, 2026
9ed36e6
test(clipboard): cover TipTap v2 adapter and transform order
seonghobae Aug 7, 2026
9ba9c60
test(clipboard): bind plugin transform context
seonghobae Aug 7, 2026
88d5ebd
test(clipboard): use real ProseMirror transform ordering
seonghobae Aug 7, 2026
dc4c8d7
test(clipboard): cover preserved nested config branch
seonghobae Aug 7, 2026
a646a99
test(docs): require TipTap v2 paste adapter doctoring
seonghobae Aug 7, 2026
ea74226
docs(clipboard): record TipTap v2 paste adapter root cause
seonghobae Aug 7, 2026
f43848e
test(api): prove registered SafeClipboard exports
seonghobae Aug 7, 2026
257c494
docs(changelog): record TipTap v2 paste adapter repair
seonghobae Aug 7, 2026
f0416d0
test(docs): bind clipboard adapter changelog evidence
seonghobae Aug 7, 2026
338c095
chore(clipboard): reconcile protected release gate
seonghobae Aug 9, 2026
d5ab65d
Merge branch 'main' into feat/safe-rich-clipboard
opencode-agent[bot] Aug 9, 2026
6cb0321
test(clipboard): classify DOM factory invocation failures
seonghobae Aug 9, 2026
2a095ed
fix(clipboard): preserve DOM capability failure classification
seonghobae Aug 9, 2026
0dd5944
test(clipboard): cover nested config through ProseMirror plugin
seonghobae Aug 9, 2026
c6fa1f4
docs(clipboard): bound visibility claims to inline declarations
seonghobae Aug 9, 2026
7868195
docs(clipboard): synchronize hidden-content boundaries
seonghobae Aug 9, 2026
260935f
Merge branch 'main' into feat/safe-rich-clipboard
opencode-agent[bot] Aug 9, 2026
9f66368
test(clipboard): align DOM factory failure contract
seonghobae Aug 9, 2026
0e1e76d
test(clipboard): cover fail-closed sanitizer branches
seonghobae Aug 9, 2026
fbf8b03
Merge branch 'main' into feat/safe-rich-clipboard
opencode-agent[bot] Aug 9, 2026
71a5456
Merge branch 'main' into feat/safe-rich-clipboard
opencode-agent[bot] Aug 9, 2026
8f5ad15
fix(clipboard): reconcile transition exports from current main
seonghobae Aug 9, 2026
dd7007a
Merge branch 'main' into feat/safe-rich-clipboard
opencode-agent[bot] Aug 9, 2026
d57d300
test(clipboard): distinguish inert-document creation failures
seonghobae Aug 9, 2026
64b4616
Merge branch 'main' into feat/safe-rich-clipboard
opencode-agent[bot] Aug 9, 2026
57f3581
test(clipboard): align inert-document failure classification
seonghobae Aug 9, 2026
559f3d5
test(docs): bind inert-document failure classification
seonghobae Aug 9, 2026
d6e6e16
docs(clipboard): classify inert-document setup as DOM capability
seonghobae Aug 9, 2026
38caec2
docs(clipboard): align DOM capability error guidance
seonghobae Aug 9, 2026
289c8fd
Merge branch 'main' into feat/safe-rich-clipboard
opencode-agent[bot] Aug 9, 2026
a530a44
test(docs): bind DOM capability contract to current semantics
seonghobae Aug 9, 2026
73b3148
test(docs): ignore prose capitalization in DOM capability contract
seonghobae Aug 9, 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
52 changes: 51 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Historical release entries from **0.1.0 through 0.5.27** are preserved verbatim

### Security
- Evidence and callback outcomes are validated fail-closed without evaluating accessors; hostile reflection failures become bounded redacted errors
- The public autosave boundary traverses candidate document JSON iteratively before scheduling, rejecting mutable nested nodes, accessors, symbols, non-finite numbers, unsupported prototypes, aliases, cycles, sparse arrays, excessive nesting, and values beyond the active envelope resource ceiling
- The public autosave boundary traverses candidate document JSON iteratively before scheduling, rejecting mutable nested nodes, accessors, symbols, non-finite numbers, unsupported prototypes, aliases, cycles, sparse arrays, excessive depth, and values beyond the active envelope resource ceiling
- Partially frozen look-alike evidence cannot enter the host callback and mutate after its strong revision was selected
- The queue includes no timer, network client, provider SDK, credential, tenant identifier, persistence adapter, React, TipTap, ProseMirror, or Yjs runtime dependency
- Revision tags remain tenant-confidential equality validators rather than authorization, signatures, tenant membership, or proof of durable persistence
Expand All @@ -99,3 +99,53 @@ Historical release entries from **0.1.0 through 0.5.27** are preserved verbatim
### Documentation
- Added the autosave architecture and doctoring record with APA 7th references to RFC 9110, RFC 8785, Herlihy and Wing (1990), and ISO/IEC 25010:2023
- Added an operator guide covering correct durable-base `If-Match` usage, local versus durable ownership, SSR/worker compatibility, observability minimization, and CWL/naruon modular integration boundaries

## Pending 0.6.0 — Safe rich clipboard ingestion

### Added
- Added a default `SafeClipboard` TipTap extension and `sanitizeRichClipboardHtml()` API that reconstruct browser-provided `text/html` through a strict semantic allowlist before ProseMirror parsing
- Added a registered TipTap v2.27.2 ProseMirror plugin adapter and public plugin key so SafeClipboard participates in the actual `transformPastedHTML` editor-property chain before parsing
- Added `clipboard` byte/node/depth limits and a live `onClipboardError` observer to standalone and provider-neutral Yjs editor surfaces
- Added operator guidance, design, implementation-plan, and APA 7th doctoring records for the clipboard trust boundary

### Changed
- Rich HTML pasted from Word, Google Docs, email, and web pages keeps supported structure and narrowly mapped bold/italic/underline/strike semantics while discarding arbitrary source styling and proprietary metadata
- Standalone and collaborative editors use one shared clipboard policy through `buildExtensions()`
- The runtime integration now uses the locked TipTap v2.27.2 `addProseMirrorPlugins` contract instead of relying on a manually invoked direct extension field that the installed v2 ExtensionManager does not register
- Nested clipboard policy objects use accessor-safe paste-time configuration validation at the exact rich-paste boundary
- Because default rich-HTML paste behavior changes, publication targets **0.6.0** only after a separate verified release pull request

### Security
- Active, embedded, form, metadata, media, SVG/MathML, template, resource-bearing, hidden, and HTML-image subtrees are removed before insertion
- Exact `content-visibility: hidden` subtrees are removed from bounded raw style declarations, including case, whitespace, terminal `!important`, CSS-comment, and CSS-escaped forms, while `visible`, `auto`, `hiddenly`, and prefixed property names remain visible
- Closed `details` elements preserve only their first rendered summary, closed `dialog` subtrees are removed, and open variants are unwrapped through the ordinary sanitizer
- Every subtree bearing a `popover` attribute is removed because static clipboard HTML cannot prove the source element's separate runtime showing state; empty, `auto`, `manual`, `hint`, and invalid-value forms are covered
- Native `progress` and `meter` widget subtrees and obsolete `noframes` and `noembed` fallback subtrees are removed
- Hidden `datalist` suggestion and down-level fallback subtrees are removed
- Raw `mso-hide` declarations are parsed with exact case-insensitive property/value matching, closed and EOF-terminated CSS-comment removal, optional terminal `!important`, and false-positive guards
- CSS-escaped property and keyword forms of `mso-hide: all` are decoded for exact comparison, while invalid or look-alike declarations remain visible
- SafeClipboard is the final ordinary TipTap paste transform through a low-priority ProseMirror plugin; a host that deliberately installs an even later transform remains outside the supported safety contract
- Unsafe and credential-bearing links are unwrapped while visible text remains; approved links retain only exact `href` and fixed `noopener noreferrer nofollow`
- IDs, classes, styles, event handlers, `data-*`, arbitrary ARIA, `contenteditable`, remote resources, local-file references, and Office/Google attributes never reach the output fragment
- UTF-8 bytes, traversed nodes, source depth, and configuration reflection are bounded and fail closed with static redacted errors
- Hostile direct-API `Document` accessors, proxies, and revoked proxies now fail closed as the stable `dom_unavailable` error before parsing, without exposing private capability exceptions

### Performance
- Accepted clipboard traversal is iterative and linear in the bounded source tree; defaults are 1 MiB, 10,000 nodes, and 64 levels
- The feature adds no runtime dependency and performs no network, storage, clipboard-permission, model, provider, credential, or database operation

### Tests
- Added realistic Word-like and Google-Docs-like fixtures, Office conditional comments, semantic conversion, structural, malformed, active-content, hidden-data, unsafe-link, resource-bound, hostile-configuration, DOM-unavailable, callback-failure, and error-redaction cases
- Added test-first regressions for closed interactive content, hidden popover state, native-widget fallback content, hidden `datalist` suggestions, `visibility: collapse`, and `content-visibility: hidden`
- Added a test-first direct-API regression proving hostile `createElement` and `implementation` property reads cannot leak arbitrary exception text
- Added RED integration commit `2e1d634bd819686b298256f9bac161e4f6e90067` and CI run `31172315841`, then real standalone, Yjs, competing-transform, and public-export tests against the complete ProseMirror paste pipeline
- Added standalone and Yjs integration tests, a 3,000-paragraph capacity fixture, final-transform ordering evidence, and repository-wide 100% production statement, branch, function, and line coverage gates
- Current jsdom results are not cross-engine browser evidence; version-pinned Chromium, Firefox, and WebKit differential fixtures remain a publication gate for 0.6.0

### Documentation
- Documented preserved and removed clipboard content, Base64Image handoff, SSR behavior, error codes, modular ownership, performance bounds, rollback, and buyer integration
- Documented `content-visibility: hidden` against CSS Containment Module Level 2, including exact raw-declaration matching, false-positive controls, test-first evidence, rollback, and the cross-engine assurance boundary
- Documented hidden popover content against the WHATWG runtime visibility-state model, including invalid-value behavior, deterministic loss boundary, test-first evidence, rollback, and cross-engine limitations
- Documented closed interactive, native-widget fallback, hidden suggestion-source, CSS escape, Office hidden-content, and final-transform composition decisions against primary specifications and official documentation
- Added an APA 7th doctoring record for DOM capability reflection redaction grounded in ECMAScript 2026 proxy abrupt-completion semantics, the WHATWG DOM capability surface, and OWASP generic-error guidance
- Added APA 7th doctoring for the TipTap v2.27.2 ProseMirror paste adapter, including locked-source authority, test-first root-cause evidence, priority ordering, residual host boundary, and rollback
Loading
Loading