Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
452 commits
Select commit Hold shift + click to select a range
04e19ef
fix(project): name 5 MiB limit accurately
seonghobae Sep 5, 2026
73d6a80
docs(project): state 5 MiB limit precisely
seonghobae Sep 5, 2026
1d2e086
docs(traceability): record project size unit repair
seonghobae Sep 5, 2026
86207ea
test(project): require v2 playback preference migration
seonghobae Sep 5, 2026
be4ce61
feat(project): migrate durable playback preference to v2
seonghobae Sep 5, 2026
4aa18fa
test(project): add golden v2 playback preference fixture
seonghobae Sep 5, 2026
73dc9a7
test(project): verify golden v2 playback preference fixture
seonghobae Sep 5, 2026
9518d84
docs(project): describe v2 playback preference migration
seonghobae Sep 5, 2026
ae97f88
docs(traceability): record v2 playback preference migration
seonghobae Sep 5, 2026
e95b1db
refactor(project): keep historical core source in place
seonghobae Sep 5, 2026
5dc4d7b
docs(traceability): record minimal v2 module boundary
seonghobae Sep 5, 2026
770942f
test(ci): require v2 project-format Windows evidence triggers
seonghobae Sep 5, 2026
72434d1
fix(ci): cover v2 project-format Windows evidence
seonghobae Sep 5, 2026
e4913d7
docs(traceability): record v2 Windows evidence repair
seonghobae Sep 5, 2026
ed5dd9a
test(project): require typed v2 IPC preference admission
seonghobae Sep 5, 2026
7711b4f
fix(project): admit typed v2 IPC preference documents
seonghobae Sep 5, 2026
21e7519
docs(traceability): record typed v2 IPC admission
seonghobae Sep 5, 2026
4f076ce
fix(project): expose typed v2 IPC admission
seonghobae Sep 5, 2026
5320607
docs(traceability): record public v2 IPC surface repair
seonghobae Sep 5, 2026
ecc2904
test(project): require selected-source IPC bridge
seonghobae Sep 5, 2026
30bfa59
feat(project): define renderer v2 document boundary
seonghobae Sep 5, 2026
64613fb
feat(project): bridge v2 document through TypeScript IPC
seonghobae Sep 5, 2026
7f9d118
feat(project): carry v2 document through native save and load
seonghobae Sep 5, 2026
327c83f
fix(project): preserve score removal project scope
seonghobae Sep 5, 2026
8149d43
docs(project): trace v2 IPC bridge boundary
seonghobae Sep 5, 2026
1a20bf5
docs(project): align format with v2 IPC bridge
seonghobae Sep 5, 2026
3db1096
test(project): reject prototype-bearing persistence records
seonghobae Sep 5, 2026
7cc4869
fix(project): require plain renderer persistence records
seonghobae Sep 5, 2026
4c2eaa8
docs(project): trace plain-record IPC admission hardening
seonghobae Sep 5, 2026
3f4ce38
test(project): cover prototype admission edge cases
seonghobae Sep 5, 2026
d1d4d0e
docs(project): record prototype edge coverage
seonghobae Sep 5, 2026
a71439d
test(project): reject trapped project record access
seonghobae Sep 5, 2026
bc8e144
fix(project): fail closed on trapped record access
seonghobae Sep 5, 2026
eba9669
docs(project): trace trapped renderer record hardening
seonghobae Sep 5, 2026
bc7e6c5
test(project): cover nested accessor rejection
seonghobae Sep 5, 2026
1777705
docs(project): record nested accessor edge coverage
seonghobae Sep 5, 2026
3191f38
test(project): require durable app-owned audio source reference
seonghobae Sep 5, 2026
7e315da
feat(project): add versioned app-owned source reference
seonghobae Sep 5, 2026
90ae48e
fix(project): export source reference contract
seonghobae Sep 5, 2026
6acd761
test(project): require source reference across renderer bridge
seonghobae Sep 5, 2026
f54be00
feat(project): validate renderer source reference contract
seonghobae Sep 5, 2026
04b4a93
fix(project): keep optional source admission trap-safe
seonghobae Sep 5, 2026
c1cdcd0
test(project): keep source-reference admission passive
seonghobae Sep 5, 2026
5203c28
docs(project): document version 3 source reference boundary
seonghobae Sep 5, 2026
76e203e
docs(traceability): record v3 source-reference decision
seonghobae Sep 5, 2026
818b9b5
docs(changelog): record project format v3 source reference
seonghobae Sep 5, 2026
ace91a2
fix(project): align historical migration tests with v3 envelope
seonghobae Sep 5, 2026
c4980be
docs(traceability): record v3 predecessor-test RCA
seonghobae Sep 5, 2026
a0bb091
docs(architecture): align project persistence with v3
seonghobae Sep 5, 2026
bb40053
docs(architecture): date v3 persistence boundary
seonghobae Sep 5, 2026
d0eb7a6
docs(traceability): mark v2 preference as historical
seonghobae Sep 5, 2026
28588c1
docs(traceability): align v2 IPC history with v3
seonghobae Sep 5, 2026
8383b3a
docs(project): align bridge comments with v3
seonghobae Sep 5, 2026
9e9d9ce
docs(traceability): align shared-song contract with v3
seonghobae Sep 5, 2026
7653c80
docs(traceability): ground v3 source reference in SSDF and CWE
seonghobae Sep 5, 2026
39fb181
test(project): require durable source content identity
seonghobae Sep 5, 2026
ac5a080
test(project): constrain source digest evidence
seonghobae Sep 5, 2026
c2117f2
fix(project): require SHA-256 source identity evidence
seonghobae Sep 5, 2026
16e5478
test(project): require source digest across renderer bridge
seonghobae Sep 5, 2026
7e853c5
fix(project): enforce source digest in renderer admission
seonghobae Sep 5, 2026
a684ab5
docs(project): trace SHA-256 source identity decision
seonghobae Sep 5, 2026
5ec9465
docs(project): make v3 source identity code-current
seonghobae Sep 5, 2026
2f5634b
docs(changelog): record v3 source content identity
seonghobae Sep 5, 2026
0e9e823
test(project): keep source digest admission passive
seonghobae Sep 5, 2026
45037f9
test(security): bound Security Notes section evidence
seonghobae Sep 5, 2026
907f3a7
fix(security): stop Security Notes evidence at peer headings
seonghobae Sep 5, 2026
00418cb
docs(project): use required Security Notes heading
seonghobae Sep 5, 2026
70c2313
docs(project): document passive admission helpers
seonghobae Sep 5, 2026
0837570
test(security): keep policy regression lint-clean
seonghobae Sep 5, 2026
65e422c
test(security): stop nested notes at parent section
seonghobae Sep 5, 2026
d1ba145
fix(security): stop Security Notes at parent headings
seonghobae Sep 5, 2026
3883f34
style(security): keep verifier imports canonical
seonghobae Sep 5, 2026
08e5531
docs(traceability): record bounded Security Notes evidence
seonghobae Sep 5, 2026
3eabb08
test(project): preserve unrelated rollback artifact
seonghobae Sep 5, 2026
a93626e
fix(project): preserve mismatched rollback artifacts
seonghobae Sep 5, 2026
9816fe4
test(audio): preserve approved native intake errors
seonghobae Sep 5, 2026
04e813e
fix(audio): preserve safe native intake diagnostics
seonghobae Sep 5, 2026
9852265
test(audio): bind native intake diagnostics to resource owner
seonghobae Sep 5, 2026
dbeee9c
merge: adopt protected develop in resource admission lane
seonghobae Sep 5, 2026
804a286
test(audio): reject growth while materializing admitted source
seonghobae Sep 5, 2026
0beee45
fix(audio): bound admitted source materialization
seonghobae Sep 5, 2026
a2b1bd9
fix(audio): materialize selected source into project storage
seonghobae Sep 5, 2026
0ee15f0
docs(audio): trace app-owned source materialization
seonghobae Sep 5, 2026
323a7fa
fix(audio): export bounded source materialization port
seonghobae Sep 5, 2026
dcb3b25
docs(audio): record native port export repair
seonghobae Sep 5, 2026
131d6d7
test(audio): expose bounded-copy destination error
seonghobae Sep 5, 2026
ac4adfd
fix(audio): distinguish bounded-copy destination failure
seonghobae Sep 5, 2026
e2257d9
docs(audio): record bounded-copy diagnostics repair
seonghobae Sep 5, 2026
dc41379
test(audio): require native content identity receipt
seonghobae Sep 5, 2026
566cd1f
fix(audio): emit streaming content identity receipt
seonghobae Sep 5, 2026
f955661
docs(audio): trace native content identity receipt
seonghobae Sep 5, 2026
373824c
test(core): require reusable SHA-256 reader boundary
seonghobae Sep 5, 2026
d1ba406
fix(core): expose reusable SHA-256 reader boundary
seonghobae Sep 5, 2026
8a4f50c
docs(core): record reusable SHA-256 consolidation port
seonghobae Sep 5, 2026
fdfdd70
test(audio): require publication-bound source identity
seonghobae Sep 5, 2026
a1c85cb
fix(audio): verify published source identity
seonghobae Sep 5, 2026
20e7faa
fix(audio): expose publication receipt verifier
seonghobae Sep 5, 2026
505d214
docs(audio): trace publication receipt verification
seonghobae Sep 5, 2026
6a0692e
test(audio): bound publication verification to receipt size
seonghobae Sep 5, 2026
c65a9fd
fix(audio): stop publication verification at expected bytes
seonghobae Sep 5, 2026
92f436a
docs(audio): bound publication verification read evidence
seonghobae Sep 5, 2026
dedaab7
test(audio): reject invalid publication receipt lengths
seonghobae Sep 5, 2026
ed9fe7e
test(audio): require publication-bound materializer receipt
seonghobae Sep 6, 2026
bdf8f87
fix(audio): bind published source to native receipt
seonghobae Sep 6, 2026
539bd57
docs(audio): align publication identity traceability
seonghobae Sep 6, 2026
51734ce
test(audio): align native oversize policy expectation
seonghobae Sep 6, 2026
dd78dee
test(audio): keep zero-byte guard on decode port
seonghobae Sep 6, 2026
6ef0096
test(audio): patch canonical decode boundary
seonghobae Sep 6, 2026
e5726df
test(audio): preserve unrelated separation test wording
seonghobae Sep 6, 2026
46ca91a
docs(security): align local-audio publication authority
seonghobae Sep 6, 2026
45b1f72
test(audio): require no-clobber source publication
seonghobae Sep 6, 2026
eb972e9
fix(audio): publish local source without clobber race
seonghobae Sep 6, 2026
55b0da5
docs(audio): record no-clobber publication decision
seonghobae Sep 6, 2026
bad908c
test(audio): require path-free publication identity handoff
seonghobae Sep 6, 2026
87bdeea
fix(audio): expose path-free publication identity
seonghobae Sep 6, 2026
344a9a3
fix(audio): export publication identity handoff
seonghobae Sep 6, 2026
681675d
docs(audio): record path-free publication identity boundary
seonghobae Sep 6, 2026
645457e
test(audio): require native publication identity retention
seonghobae Sep 6, 2026
f89996b
test(audio): keep Tauri retention as next production slice
seonghobae Sep 6, 2026
03f14fc
test(project): reject oversized source references
seonghobae Sep 6, 2026
a74d05d
test(project): bound renderer source identity bytes
seonghobae Sep 6, 2026
c956044
fix(project): bound durable source identity bytes
seonghobae Sep 6, 2026
83127b5
fix(project): align renderer source identity ceiling
seonghobae Sep 6, 2026
cbfa967
test(audio): require native retention of publication identity
seonghobae Sep 6, 2026
d8c57ce
test(audio): keep native-retention RED off canonical head
seonghobae Sep 6, 2026
106ae75
test(audio): require native retention of publication identity
seonghobae Sep 6, 2026
e4e2ba7
fix(audio): retain verified publication identity natively
seonghobae Sep 6, 2026
9a13d2b
docs(audio): record native publication identity retention
seonghobae Sep 6, 2026
06092be
fix(ci): format audio decode regressions
seonghobae Sep 6, 2026
839f5a0
fix(ci): format audio metadata regression
seonghobae Sep 6, 2026
841e1c9
chore(test): normalize decode docstring wrap
seonghobae Sep 6, 2026
37ea9a5
test(project): reject renderer-authored source identity
seonghobae Sep 6, 2026
01c09cf
fix(project): reject renderer-authored source identity
seonghobae Sep 6, 2026
4ea8c2a
test(project): block renderer source identity before IPC
seonghobae Sep 6, 2026
0268568
fix(project): block renderer source identity before IPC
seonghobae Sep 6, 2026
a747cd6
test(project): align bridge with native source authority
seonghobae Sep 6, 2026
7b2ade1
fix(persistence): consolidate desktop core crate root
seonghobae Sep 6, 2026
ce81744
fix(persistence): integrate project format into canonical core root
seonghobae Sep 6, 2026
548c46e
refactor(persistence): remove duplicate desktop core wrapper
seonghobae Sep 6, 2026
2a27d30
fix(persistence): reconcile Resource Admission stack
seonghobae Sep 6, 2026
8893a92
fix(persistence): adopt Resource Admission ancestry
seonghobae Sep 6, 2026
649e335
docs(core): explain canonical compatibility alias
seonghobae Sep 6, 2026
3a96be6
test(project): require typed resource-admission persistence handoff
seonghobae Sep 6, 2026
c2d3541
fix(project): add typed resource-admission persistence ACL
seonghobae Sep 6, 2026
b0355a9
fix(project): export resource-admission persistence ACL
seonghobae Sep 6, 2026
6eea76f
test(project): fail closed on browser save preview
seonghobae Sep 6, 2026
cb7f4fd
fix(project): fail closed on browser save preview
seonghobae Sep 6, 2026
e29f0de
docs(project): align IPC traceability with native source authority
seonghobae Sep 6, 2026
cd3c67d
test(project): require native source-reference save adapter
seonghobae Sep 6, 2026
ffdac30
fix(project): inject retained native source identity on save
seonghobae Sep 6, 2026
570894b
test(project): require explicit project-id save selector
seonghobae Sep 6, 2026
979ac4d
fix(project): forward explicit project-id save selector
seonghobae Sep 6, 2026
28d94d0
test(project): require mounted local save project identity
seonghobae Sep 6, 2026
06afcbe
fix(project): preserve analyzed local project save authority
seonghobae Sep 6, 2026
4869ee8
docs(project): record native source-reference save handoff
seonghobae Sep 6, 2026
8f44188
docs(project): correct bridge RED provenance
seonghobae Sep 6, 2026
f1d307d
test(project): require restart audio byte re-admission
seonghobae Sep 6, 2026
823cd4a
fix(project): re-admit persisted audio bytes on restart
seonghobae Sep 6, 2026
54390ce
fix(project): export restart audio re-admission
seonghobae Sep 6, 2026
3389786
refactor(project): keep restart identity verification minimal
seonghobae Sep 6, 2026
20ded47
test(project): cover malformed restart source evidence
seonghobae Sep 6, 2026
cbfc23f
test(project): distinguish malformed restart identity cases
seonghobae Sep 6, 2026
8b84312
docs(project): trace restart source re-admission boundary
seonghobae Sep 6, 2026
dbe4959
docs(project): complete restart Security Notes contract
seonghobae Sep 6, 2026
e115811
test(project): prove malformed restart evidence is not read
seonghobae Sep 6, 2026
66ed5ec
test(project): require safe app-owned source reopen authority
seonghobae Sep 6, 2026
f36996f
fix(project): bind restart re-admission to native opener
seonghobae Sep 6, 2026
c7e112f
feat(project): export native reopen ACL
seonghobae Sep 6, 2026
b80dea3
test(project): exercise restart ACL through native opener
seonghobae Sep 6, 2026
b975843
test(project): cover project-root restart binding
seonghobae Sep 6, 2026
909d54f
style(project): format restart opener coverage
seonghobae Sep 6, 2026
6801d95
docs(project): trace native restart opener boundary
seonghobae Sep 6, 2026
ece508c
test(project): require non-provisioning restart root lookup
seonghobae Sep 6, 2026
f7e8685
fix(project): add non-provisioning restart root resolver
seonghobae Sep 6, 2026
b2fb798
test(project): bind restart lookup to read-side resolver
seonghobae Sep 6, 2026
9cd4681
test(project): require production restart source re-admission
seonghobae Sep 6, 2026
0f20b07
fix(project): restore verified source authority on reopen
seonghobae Sep 6, 2026
ddeff8b
style(project): rustfmt restart root resolver
seonghobae Sep 6, 2026
3e21973
docs(project): trace production restart re-admission
seonghobae Sep 6, 2026
382f029
docs(project): document restart directory guards
seonghobae Sep 6, 2026
1c8bc3d
test(project): reject linked app-local reopen base
seonghobae Sep 6, 2026
a839b5b
fix(project): bind reopen to a real app-local base
seonghobae Sep 6, 2026
9a924ba
docs(project): trace app-local reopen authority
seonghobae Sep 6, 2026
232db73
test(project): cover Windows app-local reparse base
seonghobae Sep 6, 2026
90f60a7
test(project): require fresh source bytes at analysis dispatch
seonghobae Sep 6, 2026
ae1f568
fix(project): revalidate app-owned audio before dispatch
seonghobae Sep 6, 2026
b84ed0e
fix(project): revalidate source before analysis dispatch
seonghobae Sep 6, 2026
f5730fd
test(project): format dispatch revalidation contract
seonghobae Sep 6, 2026
c6351fc
docs(traceability): record analysis dispatch revalidation
seonghobae Sep 6, 2026
9dc5336
test(audio): require content-bound decode snapshot
seonghobae Sep 6, 2026
93d2c99
fix(audio): bind decoder to admitted content snapshot
seonghobae Sep 6, 2026
65baf71
test(audio): require scoped native admission evidence
seonghobae Sep 6, 2026
e0bec86
fix(audio): consume scoped native admission evidence
seonghobae Sep 6, 2026
404586a
test(audio): require per-process decode evidence handoff
seonghobae Sep 6, 2026
a0809cd
fix(audio): scope native evidence to analysis child
seonghobae Sep 6, 2026
cbaaf86
test(audio): forbid duplicate CLI path decode
seonghobae Sep 6, 2026
a1136c5
fix(audio): skip duplicate path probe for admitted source
seonghobae Sep 6, 2026
e1b5092
test(audio): pin scoped child evidence contract
seonghobae Sep 6, 2026
88beb62
style(audio): wrap admitted snapshot construction
seonghobae Sep 6, 2026
e11f73c
docs(audio): trace content-bound decoder handoff
seonghobae Sep 6, 2026
19c2112
test(audio): bind cache workspace to source identity
seonghobae Sep 6, 2026
063164e
fix(audio): scope analysis workspaces by source digest
seonghobae Sep 6, 2026
e67f9b2
docs(audio): bind cache provenance to source digest
seonghobae Sep 6, 2026
716438d
test(audio): reject uncached Demucs remote lookup
seonghobae Sep 6, 2026
61b629b
fix(audio): fail closed before Demucs model download
seonghobae Sep 6, 2026
8ccdf20
test(audio): preserve mocked Demucs unit boundary
seonghobae Sep 6, 2026
b91d120
docs(audio): trace local-only Demucs model admission
seonghobae Sep 6, 2026
fb9571b
test(audio): reject tampered cached Demucs checkpoint
seonghobae Sep 6, 2026
d043218
fix(audio): verify cached Demucs checkpoint checksum
seonghobae Sep 6, 2026
e2b8721
docs(audio): trace Demucs cache integrity admission
seonghobae Sep 6, 2026
58f30d4
docs(audio): block commercial Demucs weight packaging
seonghobae Sep 6, 2026
9fd9b56
test(separation): require immutable local Demucs snapshot
seonghobae Sep 6, 2026
3662de1
fix(separation): bind Demucs load to verified local snapshot
seonghobae Sep 6, 2026
7ac4bc1
test(separation): bound local Demucs snapshot size
seonghobae Sep 6, 2026
c21c6c4
fix(separation): bound Demucs checkpoint snapshot
seonghobae Sep 6, 2026
cce5638
docs(traceability): record bounded Demucs snapshot
seonghobae Sep 6, 2026
6cdea97
docs(changelog): record bounded local model load
seonghobae Sep 6, 2026
f4ef3dc
test(mir): reject Demucs checkpoint growth after preflight
seonghobae Sep 6, 2026
0d0c6c3
fix(mir): bind Demucs snapshot to admitted descriptor size
seonghobae Sep 6, 2026
f9758eb
docs(traceability): bind Demucs snapshot to descriptor size
seonghobae Sep 6, 2026
c7d22c0
docs(changelog): record exact Demucs snapshot size binding
seonghobae Sep 6, 2026
bd18d28
test(audio): use one separator import boundary
seonghobae Sep 6, 2026
e8aa3db
test(separation): use one Demucs separator import boundary
seonghobae Sep 6, 2026
9ceeb2f
test(project): preserve reopen source authority on resave
seonghobae Sep 6, 2026
9a9151d
fix(project): retain reopen persistence identity
seonghobae Sep 6, 2026
d76d90b
docs(project): trace reopen save authority
seonghobae Sep 6, 2026
767b87e
docs(changelog): record reopen resave authority
seonghobae Sep 6, 2026
5789562
test(mir): expose PyTorch weights-only model incompatibility
seonghobae Sep 6, 2026
d395c60
fix(mir): bound PyTorch weights-only model load failure
seonghobae Sep 6, 2026
4838ee8
docs(trace): record PyTorch weights-only model boundary
seonghobae Sep 6, 2026
e4c606b
docs(changelog): record bounded Demucs weights-only failure
seonghobae Sep 6, 2026
3ae3646
test(separation): reject unsafe torch load override
seonghobae Sep 6, 2026
0d9fb9f
fix(separation): fail closed on unsafe torch load override
seonghobae Sep 6, 2026
28c73a3
docs(traceability): record torch environment downgrade guard
seonghobae Sep 6, 2026
dc59326
docs(changelog): record torch environment downgrade guard
seonghobae Sep 6, 2026
4d0b16b
test(separation): reject torch backend autoload
seonghobae Sep 6, 2026
000fdb5
fix(separation): fail closed on torch backend autoload
seonghobae Sep 6, 2026
3fc5a87
docs(traceability): bind pytorch runtime environment
seonghobae Sep 6, 2026
4676650
docs(changelog): record torch backend autoload guard
seonghobae Sep 6, 2026
f5db38a
docs(security): structure cross-platform plan notes
seonghobae Sep 6, 2026
707d680
docs(security): structure harness plan notes
seonghobae Sep 6, 2026
87d6cd7
docs(security): structure supply-chain plan notes
seonghobae Sep 6, 2026
87690cd
docs(security): record analysis dispatch threats
seonghobae Sep 6, 2026
eee919d
docs(traceability): align v2 preference security notes
seonghobae Sep 6, 2026
21fb89b
docs(traceability): align v3 source security contract
seonghobae Sep 6, 2026
9388e8c
docs(traceability): align project IPC security notes
seonghobae Sep 6, 2026
349d67d
docs(architecture): align local audio authority flow
seonghobae Sep 6, 2026
8feb0c3
test(project): bind dispatch opener closure
seonghobae Sep 6, 2026
dbc3dd7
test(project): accept generic restart adapter signature
seonghobae Sep 6, 2026
8a94753
fix(desktop): remove stale rehearsal parser import
seonghobae Sep 6, 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
67 changes: 67 additions & 0 deletions .github/workflows/project-persistence-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: project-persistence-windows

on:
pull_request:
branches:
- develop
- main
paths:
- "apps/desktop/core/Cargo.toml"
- "apps/desktop/core/src/lib.rs"
- "apps/desktop/core/src/crate_root.rs"
- "apps/desktop/core/src/project_format.rs"
- "apps/desktop/core/tests/project_persistence*.rs"
- "apps/desktop/core/tests/project_format*.rs"
- "apps/desktop/core/testdata/project-*.json"
- "apps/desktop/src-tauri/Cargo.toml"
- "apps/desktop/src-tauri/Cargo.lock"
- "apps/desktop/src-tauri/src/main.rs"
- "apps/desktop/src-tauri/src/project_persistence.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.rs"
- ".github/workflows/project-persistence-windows.yml"
push:
branches:
- develop
- main
paths:
- "apps/desktop/core/Cargo.toml"
- "apps/desktop/core/src/lib.rs"
- "apps/desktop/core/src/crate_root.rs"
- "apps/desktop/core/src/project_format.rs"
- "apps/desktop/core/tests/project_persistence*.rs"
- "apps/desktop/core/tests/project_format*.rs"
- "apps/desktop/core/testdata/project-*.json"
- "apps/desktop/src-tauri/Cargo.toml"
- "apps/desktop/src-tauri/Cargo.lock"
- "apps/desktop/src-tauri/src/main.rs"
- "apps/desktop/src-tauri/src/project_persistence.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.rs"
- ".github/workflows/project-persistence-windows.yml"

permissions:
contents: read

env:
GIT_CONFIG_COUNT: "1"
GIT_CONFIG_KEY_0: init.defaultBranch
GIT_CONFIG_VALUE_0: develop

jobs:
windows-recovery-cleanup:
name: test / project-persistence / windows
runs-on: windows-2025
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install Rust 1.97.1
run: rustup toolchain install 1.97.1 --profile minimal
- name: Prepare compile-only frontendDist fixture
shell: pwsh
run: |
New-Item -ItemType Directory -Force apps/desktop/dist | Out-Null
Set-Content -Path apps/desktop/dist/index.html -Value '<!doctype html><title>BandScope test fixture</title>' -NoNewline
- name: Run Windows recovery-cleanup regression
run: cargo +1.97.1 test --manifest-path apps/desktop/src-tauri/Cargo.toml --no-default-features --tests
5 changes: 3 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ARCHITECTURE.md

Last updated: 2026-03-11
Last updated: 2026-09-06

## Brand source

Expand Down Expand Up @@ -111,8 +111,9 @@ Last updated: 2026-03-11
- Shared contracts live in `packages/shared-types` so the UI can evolve without importing Python internals.
- Shared contracts should ultimately model section, role, cue, confidence, and export artifacts explicitly enough that desktop UI and analysis outputs do not invent their own parallel schemas.
- The current shared-types baseline includes a rehearsal-domain fixture that exercises section, role, cue, confidence, provenance, and export-summary fields in the desktop shell before the full analysis pipeline lands.
- Current Project Persistence writes a strict `projectFormatVersion: 3` envelope around the validated rehearsal song, closed Active Player preference, and optional path-free app-owned audio `sourceReference`; legacy raw-song, v1, and v2 inputs remain readable through ordered migration. Resource Admission materializes the admitted local source as the fixed app-owned `source.<extension>` artifact, verifies publication byte identity, and retains a path-free native identity. Project Persistence injects that identity into Save and re-admits the exact size and SHA-256 on restart; production analysis revalidates the retained identity and decodes a verified private byte snapshot. Source/derived/decision/handoff expansion, autosave/recovery UX, and fresh Active Player audible authority remain follow-up work under #962/#961 rather than parallel stores.
- Local analysis orchestration uses typed Tauri IPC commands and a Python subprocess over stdin/stdout rather than a loopback HTTP listener.
- Local audio intake bootstraps a project by validating a user-selected file in Rust, creating app-owned temp/cache/project roots, and referencing the original source file rather than copying it in this phase.
- Local audio intake validates an OS-selected source in Rust, enforces the canonical resource policy, publishes a no-clobber app-owned `source.<extension>` copy under the minted project aggregate, verifies the published bytes, and exposes only bounded bootstrap/path-free identity evidence to downstream Project Persistence and analysis consumers.
- Those bootstrap roots should resolve from app-owned Tauri data/cache paths instead of the shared system temp namespace.
- Product and UX decisions should prefer rehearsal-first simplicity while still maintaining high analytical accuracy.
- Security decisions should prefer allowlisted narrow capabilities over generic convenience APIs.
Expand Down
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Name tonight's first playable range on the ready rehearsal map and tell the player to check that span on their instrument before the section.
- Display the analyzed song tempo (BPM) as a badge in the rehearsal workspace.
- 각 합주 역할(Role)별 개인 연습 진행도를 0~100% 범위로 기록 및 시각화할 수 있는 연습 진척도(`practiceProgress`) 트래커 기능 추가. UI 컨트롤(슬라이더 및 +/- 버튼)과 한/영 다국어 지원 포함.
- Evolve local project writes to `projectFormatVersion: 3`: retain deterministic legacy/v1/v2 migration, persist the closed Active Player source preference, and optionally store a path-free app-owned audio `sourceReference` with bounded byte evidence and canonical SHA-256 content identity for process-restart re-admission.

### Changed

Expand All @@ -15,7 +16,27 @@

### Fixed

- Preserve a reopened v3 project's native source selector and stored playback-source preference across an Open Project → Save Project round trip, so resaving cannot silently drop `sourceReference` or reset a non-default stem intent to Full mix.
- Enforce one canonical local-audio resource policy across native local-file/YouTube bootstrap intake, the desktop bridge, Python request preflight, temporal decoding, and stem separation so oversized, overlong, malformed, wrong-rate, or non-finite input fails before bootstrap storage or expensive analysis/model work.
- Preflight source-container duration, sample rate, and channel count from the already-open audio handle before temporal, stem, or bass-transcription decoders resample, downmix, or truncate it; successful metadata probes rewind the handle and malformed probes fail closed.
- Bound the admitted canonical decoded mono buffer to 317,520,000 bytes as well as the existing 39,690,000-sample ceiling, so decoder dtype expansion cannot stay within the sample count while exceeding the explicit in-memory audio budget.
- Fail closed on malformed known YouTube duration metadata before `download=True`; Boolean, non-numeric, non-finite, zero, negative, and non-canonical numeric-subtype duration evidence can no longer authorize a media download through Python numeric coercion or subclass semantics.
- Align YouTube download admission with that same 100 MiB encoded-byte ceiling: abort in-flight with yt-dlp `max_filesize` and a progress hook, reject announced oversize before `download=True`, delete owned `.part` / `.ytdl` / `-Frag*` siblings from that import directory on abort, reject a completed path that resolves outside the current import cache before post-download validation, cleanup, or success, and delete owned post-download artifacts that still exceed the policy. A 60 MiB import that the old 50 MB check rejected is now accepted; a file one byte over 100 MiB is not.
- Bound native stored-score PDF reads to the 25 MiB product limit before heap allocation and revalidate PDF magic on the same opened descriptor, preventing an attached score that later grows from bypassing the local resource boundary.
- Treat every zero-element NumPy layout as empty chord input, including shapes whose first dimension is non-zero, before feature extraction.
- Upgraded the local score PDF parser to `pdfjs-dist` 6.2.108, pinned Undici 7.29.0 across the workspace, and constrained PDF loading to copied in-memory bytes with a same-origin bundled worker and npm-generated lock provenance.
- Stage and sync new project saves before non-clobbering publication, and enforce the existing 5 MiB project limit during the file read itself so a selected project cannot grow past a metadata preflight into an unbounded load allocation.
- Reject directly selected project symlinks before reading so a chosen `.bscope` path cannot silently redirect the loader to different file content.
- Reject a symlinked/reparse-point save parent before staging so a selected project path cannot redirect new project publication into a different directory.
- Fail closed when a selected `.bscope` path changes file identity between preflight and handle acquisition; Windows opens reparse points without following them and compares native volume serial plus file-index identity across the acquisition boundary.
- Refuse last-component symlink following during Linux/macOS project handle acquisition and make that acquisition non-blocking so a preflight-to-open path swap cannot redirect the loader or stall it on a special file.
- Preserve first-save crash safety on filesystems without hard-link support by publishing the fully synced staging file with an OS-native atomic no-replace rename, so a crash cannot leave an empty reserved final path.
- Reject a stale existing-project replacement when the selected target changes file identity while replacement bytes are staged; native exchange/backup publication restores the competing target instead of clobbering it.
- Recover an interrupted existing-project replacement from a bounded, same-directory identity journal when the target is selected again, while leaving mismatched files untouched.
- Keep renderer project admission passive and path-free: custom prototypes, enumeration/descriptor traps, accessors, runtime playback authorities, unknown fields, invalid app-owned source references, unsafe byte-size values, and missing/non-canonical SHA-256 source identity fail closed before persistence IPC.
- Keep local Demucs loading offline and bounded by resolving a private snapshot copied from the verified cache descriptor through `LocalRepo`; reject missing, modified, empty, non-regular, over-128-MiB, or descriptor-size-racing checkpoint state before model deserialization so mutable cache replacement, post-preflight growth/shrink, and oversized local artifacts cannot alter or exhaust one analysis load.
- Bound PyTorch 2.6+ weights-only checkpoint incompatibility at the admitted local-model boundary instead of leaking serialized class details or silently enabling legacy pickle loading; incompatible technical cache state now returns the existing local-model-unavailable diagnostic and remains a Distribution serialization/provenance decision.
- Reject PyTorch runtime-environment widening at the local Demucs boundary: `TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD` cannot turn the upstream implicit checkpoint load back into unrestricted pickle deserialization, and `TORCH_DEVICE_BACKEND_AUTOLOAD=1` cannot auto-import out-of-tree backend extensions before model admission.

## [0.1.3] - 2026-04-29

Expand Down Expand Up @@ -75,4 +96,4 @@

- `ChordsFeature` (코드 분석) 화면에서 각 파트(Role)의 `transpositionPlan`(이조/조옮김 계획)을 표시하는 기능을 추가했습니다.
- `RangesFeature` (음역대 분석) 화면에서 겹침 경고(Overlap warning) 외에 해당 파트의 채보(Transcription) 가능 노드 수를 요약하여 보여주는 기능을 추가했습니다.
- 신규 UI 요소에 대한 단위 테스트를 추가했습니다 (`apps/desktop/src/features/chords/index.test.tsx`, `apps/desktop/src/features/ranges/index.test.tsx`).
- 신규 UI 요소에 대한 단위 테스트를 추가했습니다 (`apps/desktop/src/features/chords/index.test.tsx`, `apps/desktop/src/features/ranges/index.test.tsx`).
2 changes: 1 addition & 1 deletion apps/desktop/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ publish = false

[lib]
name = "bandscope_desktop_core"
path = "src/lib.rs"
path = "src/root.rs"

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage)'] }
Expand Down
Loading