Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
683 commits
Select commit Hold shift + click to select a range
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
67b1ebc
test(security): format Security Notes policy regressions
seonghobae Sep 6, 2026
f9553f0
test(ci): fix security notes import order
seonghobae Sep 6, 2026
542791a
test(ci): make Security Notes imports Ruff-canonical
seonghobae Sep 6, 2026
bab276e
test(ci): match Ruff import-block spacing
seonghobae Sep 6, 2026
2d2e5a9
style(ci): terminate temporal analyzer source canonically
seonghobae Sep 6, 2026
50837f1
style(ci): terminate transcription source canonically
seonghobae Sep 6, 2026
46478c4
style(ci): apply Ruff layout to Security Notes test
seonghobae Sep 6, 2026
f408b5a
test(project): red for durable local-audio publication
seonghobae Sep 14, 2026
b758deb
fix(project): add durable no-replace source publication
seonghobae Sep 14, 2026
834b45f
fix(project): route local audio through durable publication
seonghobae Sep 14, 2026
920bacf
test(project): bind local audio to durable publication owner
seonghobae Sep 14, 2026
66bb6fb
docs(project): record durable local-audio publication boundary
seonghobae Sep 14, 2026
740e052
test(project): preserve source stage on publication rejection
seonghobae Sep 14, 2026
64ebca3
fix(project): preserve rejected audio publication stage
seonghobae Sep 14, 2026
85dfbed
style(project): restore source newline
seonghobae Sep 14, 2026
af3bf76
test(cache): bind final results to admitted audio identity
seonghobae Sep 14, 2026
676b8d9
test(cache): scope RED to admitted identity
seonghobae Sep 14, 2026
5802980
feat(cache): add admitted final-result cache boundary
seonghobae Sep 14, 2026
72e7c7a
feat(cache): verify scoped admitted identity
seonghobae Sep 14, 2026
49d2c70
fix(cache): bind final results to admitted source identity
seonghobae Sep 14, 2026
c45ffdd
test(cache): cover final-result admission edge cases
seonghobae Sep 14, 2026
b80e383
docs(cache): document final-result invariants
seonghobae Sep 14, 2026
21b2f3e
test(cache): reject incomplete persisted rehearsal roles
seonghobae Sep 14, 2026
32e355f
fix(cache): validate complete persisted rehearsal roles
seonghobae Sep 14, 2026
dc30ae1
test(cache): cover complete role admission edges
seonghobae Sep 14, 2026
93757a1
test(cache): expose shared-contract admission gaps
seonghobae Sep 14, 2026
9638481
fix(cache): enforce shared rehearsal contract on reuse
seonghobae Sep 14, 2026
6c39f6a
test(cache): require durable final-result publication
seonghobae Sep 14, 2026
57c305a
fix(cache): durably publish final rehearsal results
seonghobae Sep 14, 2026
14db687
fix(cache): route final-result writes through durable publisher
seonghobae Sep 14, 2026
2cfc06b
test(cache): bind durability failure to production caller
seonghobae Sep 14, 2026
abc4cf1
test(cache): cover platform durability branches
seonghobae Sep 14, 2026
901a50a
fix(cache): make durability adapter strict-check clean
seonghobae Sep 14, 2026
8d9c432
test(cache): cover unavailable Windows durability binding
seonghobae Sep 14, 2026
290e320
docs(cache): trace final-result durability decision
seonghobae Sep 14, 2026
0d7c35f
test(cache): reject unknown persisted rehearsal fields
seonghobae Sep 14, 2026
4376924
fix(cache): enforce shared contract key strictness
seonghobae Sep 14, 2026
0b0ab2a
test(cache): cover nested unknown-key boundaries
seonghobae Sep 14, 2026
1b43360
test(cache): require feature-cache integrity and durable ordering
seonghobae Sep 14, 2026
4530cd5
fix(cache): bind and durably publish reusable stem arrays
seonghobae Sep 14, 2026
cfcc237
docs(traceability): record feature-cache integrity boundary
seonghobae Sep 14, 2026
e8b2b59
test(cache): bound feature-cache admission
seonghobae Sep 14, 2026
9f7cb56
fix(cache): bound reusable feature admission
seonghobae Sep 14, 2026
f44e0d9
test(cache): reject oversized declared stem arrays
seonghobae Sep 14, 2026
eebc093
fix(cache): preflight NPZ array declarations
seonghobae Sep 14, 2026
1fa9dd3
docs(cache): trace bounded feature admission
seonghobae Sep 14, 2026
efcffad
test(cache): require MIR generation identity
seonghobae Sep 14, 2026
33ebea0
feat(mir): expose canonical separation generation identity
seonghobae Sep 14, 2026
3b1c237
fix(cache): bind reuse to MIR generation
seonghobae Sep 14, 2026
f17051f
test(mir): cover separation generation identity
seonghobae Sep 14, 2026
a035d32
docs(mir): bind cache reuse to scientific generation
seonghobae Sep 14, 2026
8cee952
test(cache): assert MIR generation binding
seonghobae Sep 14, 2026
316cf44
style(mir): format nested generation test helper
seonghobae Sep 14, 2026
83d7dc3
docs(security): complete final-result cache threat notes
seonghobae Sep 16, 2026
315cb55
docs(security): complete feature-cache threat notes
seonghobae Sep 16, 2026
efec25d
test(cache): clarify Windows MoveFileExW mocks
seonghobae Sep 16, 2026
55e4046
test(cache): remove unused pytest import
seonghobae Sep 16, 2026
31136a1
fix(cache): use one ctypes import style
seonghobae Sep 16, 2026
50372d3
test(security): reject fenced Security Notes headings
seonghobae Sep 16, 2026
9c1cb6c
fix(security): ignore fenced headings in notes policy
seonghobae Sep 16, 2026
efd4ec0
test(security): reject indented code headings
seonghobae Sep 16, 2026
4cbd76d
fix(security): honor Markdown heading indentation
seonghobae Sep 16, 2026
78b4757
test(security): preserve CommonMark closing hashes
seonghobae Sep 16, 2026
452a786
fix(security): parse ATX closing hashes exactly
seonghobae Sep 16, 2026
764b889
test(security): reject Security Notes hidden in HTML comments
seonghobae Sep 16, 2026
905d5eb
fix(security): ignore raw HTML comment headings in policy parser
seonghobae Sep 16, 2026
d2e3e72
test(security): reject Security Notes hidden in raw HTML blocks
seonghobae Sep 16, 2026
d0be236
fix(security): exclude CommonMark raw HTML blocks from heading policy
seonghobae Sep 16, 2026
31e257c
chore(security): keep raw HTML parser lint-clean
seonghobae Sep 16, 2026
0987542
test(security): reject example-only Security Notes evidence
seonghobae Sep 16, 2026
b388722
fix(security): admit only rendered Security Notes evidence
seonghobae Sep 16, 2026
f106b07
repair(project): release generic Security Notes ownership
seonghobae Sep 16, 2026
83a0e59
repair(project): remove duplicate governance regression owner
seonghobae Sep 16, 2026
79e7588
repair(project): remove transferred governance RED
seonghobae Sep 16, 2026
347653a
repair(project): format persistence Ruff regressions
seonghobae Sep 17, 2026
7a2a801
repair(project): sort cache publication imports
seonghobae Sep 17, 2026
0f9e01c
fix(project): apply Ruff canonical cache import ordering
seonghobae Sep 18, 2026
fc8271b
style(project): preserve canonical EOF formatting
seonghobae Sep 18, 2026
ef4e0a4
test(project): require deterministic migration receipts
seonghobae Sep 18, 2026
e833187
feat(project): emit deterministic migration receipts
seonghobae Sep 18, 2026
abf6611
feat(project): export migration receipt contract
seonghobae Sep 18, 2026
74d5bcc
test(project): prove migration receipt idempotency
seonghobae Sep 18, 2026
f00ea01
docs(project): trace migration receipt contract
seonghobae Sep 18, 2026
852236e
docs(project): make migration and source lifecycle code-current
seonghobae Sep 18, 2026
2c46d0c
test(project): require validated migration copy preparation
seonghobae Sep 18, 2026
a137fd9
feat(project): prepare validated migration copy
seonghobae Sep 18, 2026
04ab3cc
feat(project): export validated migration preparation
seonghobae Sep 18, 2026
01dccee
docs(project): trace validated migration copy preparation
seonghobae Sep 18, 2026
eaba6e3
docs(project): align format lifecycle with prepared migrations
seonghobae Sep 18, 2026
5ff8027
test(project): require sealed migration plan accessors
seonghobae Sep 18, 2026
fd2e4f2
fix(project): seal validated migration candidate
seonghobae Sep 18, 2026
0369f04
docs(project): record sealed migration plan invariant
seonghobae Sep 18, 2026
f1f374a
test(project): require read-bound predecessor identity
seonghobae Sep 18, 2026
cc0755b
fix(project): bind bounded reads to opened file identity
seonghobae Sep 18, 2026
4324e61
docs(project): trace read-bound migration predecessor identity
seonghobae Sep 18, 2026
eeb2b71
test(project): require exact migration predecessor digest binding
seonghobae Sep 18, 2026
53ab331
fix(project): verify migration predecessor bytes through receipt
seonghobae Sep 18, 2026
26cf9e6
test(project): require exact migration output digest binding
seonghobae Sep 18, 2026
7b4c6e5
fix(project): bind migration candidate bytes to receipt output
seonghobae Sep 18, 2026
847c31d
test(project): require digest-bound migration publication CAS
seonghobae Sep 18, 2026
a46be0d
fix(project): enforce digest-bound migration publication CAS
seonghobae Sep 18, 2026
6104b95
docs(project): trace digest-bound migration publication
seonghobae Sep 18, 2026
c406080
test(project): require migrate-on-load publication
seonghobae Sep 18, 2026
d50b9e3
fix(project): orchestrate receipt-bound migrate-on-load
seonghobae Sep 18, 2026
ee906cf
test(project): exercise migrate-on-load owner
seonghobae Sep 18, 2026
e610db4
fix(project): route load through migration service
seonghobae Sep 18, 2026
28daa66
style(project): format migrate-on-load service
seonghobae Sep 18, 2026
9a4554e
test(project): track migrate-on-load route
seonghobae Sep 18, 2026
bd318f9
test(project): preserve migration data permissions
seonghobae Sep 18, 2026
e79aa8a
docs(project): trace migrate-on-load publication
seonghobae Sep 18, 2026
4008dab
test(project): require native persistence CI coverage
seonghobae Sep 18, 2026
cc80424
ci(project): track persistence application owners
seonghobae Sep 18, 2026
e0566c3
ci(project): add macOS persistence evidence lane
seonghobae Sep 18, 2026
ddfad47
docs(project): trace native persistence CI gate
seonghobae Sep 18, 2026
1726e9b
test(project): bind native CI traceability refresh
seonghobae Sep 18, 2026
488b89d
ci(project): refresh Windows lane on traceability changes
seonghobae Sep 18, 2026
ad9087a
ci(project): refresh macOS lane on traceability changes
seonghobae Sep 18, 2026
60e0623
docs(project): bind exact-head native CI evidence
seonghobae Sep 18, 2026
488b2de
test(project): require Windows workflow successor identity
seonghobae Sep 18, 2026
c6045d8
ci(project): register Windows persistence successor
seonghobae Sep 18, 2026
61f7d56
ci(project): retire stale Windows workflow identity
seonghobae Sep 18, 2026
05ed6c1
docs(project): record Windows native workflow successor
seonghobae Sep 18, 2026
62ac8f8
test(project): flush staged source with Windows write authority
seonghobae Sep 18, 2026
fddd996
docs(project): trace Windows durability fixture RED and repair
seonghobae Sep 18, 2026
927c4aa
test(project): require content-bound published recovery
seonghobae Sep 18, 2026
4452580
fix(project): bind recovery journal to migration receipt
seonghobae Sep 18, 2026
bc892e3
test(project): exercise versioned recovery journal
seonghobae Sep 18, 2026
aedf857
docs(project): trace receipt-bound crash recovery
seonghobae Sep 18, 2026
b1edaf3
test(project): mirror native published recovery layout
seonghobae Sep 18, 2026
d8edb4a
test(project): adapt rollback fixture to journal v2
seonghobae Sep 18, 2026
0f8f335
docs(project): trace recovery-journal hosted repair
seonghobae Sep 18, 2026
5c1a26e
refactor(project): remove obsolete v1 serializer ownership
seonghobae Sep 18, 2026
6156d35
fix(project): keep legacy v1 parser warning-clean
seonghobae Sep 18, 2026
7f55bfc
docs(project): trace compatibility warning root fix
seonghobae Sep 18, 2026
69d54d4
test(persistence): compile native owner once
seonghobae Sep 18, 2026
582ec08
ci(persistence): track single-compile case inputs
seonghobae Sep 18, 2026
92136ba
test(persistence): repair shared harness import
seonghobae Sep 18, 2026
2b0d5d9
test(persistence): exercise production source publisher
seonghobae Sep 18, 2026
1622a3a
docs(persistence): trace single-compile native harness
seonghobae Sep 18, 2026
1ec378f
test(persistence): scope unix-only imports
seonghobae Sep 18, 2026
966cb6e
test(persistence): scope unix permission owner
seonghobae Sep 18, 2026
522ef90
test(persistence): scope macOS-only alias case
seonghobae Sep 18, 2026
b947e55
fix(persistence): scope platform and test-only readers
seonghobae Sep 18, 2026
c38b7e6
docs(persistence): trace final warning owners
seonghobae Sep 18, 2026
29e52d8
test(persistence): require native warning gate
seonghobae Sep 18, 2026
a2d8c74
fix(persistence): add core warning gate feature
seonghobae Sep 18, 2026
e0ead7d
fix(persistence): deny core warnings in native gate
seonghobae Sep 18, 2026
61aca5c
fix(persistence): wire native warning gate feature
seonghobae Sep 18, 2026
a3861a0
fix(persistence): deny warnings in native harness
seonghobae Sep 18, 2026
9b2b854
test(persistence): scope warning gate to owner harness
seonghobae Sep 18, 2026
14e54bc
test(persistence): track warning gate owner root
seonghobae Sep 18, 2026
2f1d4c7
ci(persistence): enforce owned warnings on Windows
seonghobae Sep 18, 2026
bb832ae
ci(persistence): enforce owned warnings on macOS
seonghobae Sep 18, 2026
15d0305
docs(persistence): trace compile-time warning gate
seonghobae Sep 18, 2026
269db5b
fix(persistence): restore source readmission exports
seonghobae Sep 19, 2026
5de22a6
docs(persistence): trace warning-gate export regression
seonghobae Sep 19, 2026
eebe2ee
test(project): require durable Windows replacement rollback
seonghobae Sep 19, 2026
5455fc8
fix(project): flush Windows replacement metadata before success
seonghobae Sep 19, 2026
336836a
test(project): assert Windows rollback artifacts are retired
seonghobae Sep 19, 2026
40847ed
docs(project): trace Windows replacement durability boundary
seonghobae Sep 19, 2026
b4214ad
fix(project): preserve raced target during Windows rollback
seonghobae Sep 19, 2026
a00654a
docs(project): trace raced-target rollback authority
seonghobae Sep 19, 2026
4b617a5
test(project): reject recovery journal parent traversal
seonghobae Sep 19, 2026
49bc47c
test(project): activate hostile recovery-name regression
seonghobae Sep 19, 2026
e364474
fix(project): confine recovery journal names to one component
seonghobae Sep 19, 2026
2f8454c
docs(project): trace recovery journal path boundary
seonghobae Sep 19, 2026
898b3c2
docs(project): anchor journal confinement to CWE-22
seonghobae Sep 19, 2026
4cda80b
test(project): expose successful-cleanup boundary for race regression
seonghobae Sep 19, 2026
d3daecf
test(project): RED preserve raced displaced path on successful cleanup
seonghobae Sep 19, 2026
83a40b2
fix(project): bind successful cleanup to durable journal identities
seonghobae Sep 19, 2026
1d53792
test(project): cover target swap before successful cleanup
seonghobae Sep 19, 2026
48fbd91
docs(traceability): record successful-cleanup authority repair
seonghobae Sep 19, 2026
18b381b
test(project): prove private modes under permissive umask
seonghobae Sep 19, 2026
cac722e
fix(project): keep Unix persistence artifacts owner-private
seonghobae Sep 19, 2026
3cde95f
docs(project): trace private persistence artifacts
seonghobae Sep 19, 2026
23fdaec
test(project): preserve deliberate Unix sharing mode
seonghobae Sep 19, 2026
85c0879
test(project): reject stale hard-link stage after sync failure
seonghobae Sep 19, 2026
c0ec7d2
fix(project): retire first-save hard-link alias before durability check
seonghobae Sep 19, 2026
06ff23a
test(project): prove first-save alias cleanup ordering
seonghobae Sep 19, 2026
bbb11de
test(project): reject linked project-root ancestors
seonghobae Sep 19, 2026
f9e9fe0
fix(project): bind existing roots to safe ancestor chain
seonghobae Sep 19, 2026
0a4d7bf
docs(project): record root-chain authority boundary
seonghobae Sep 19, 2026
bdd3cee
test(project): preserve real project-root authority
seonghobae Sep 19, 2026
9e998d8
test(project): reject parent-swap false success
seonghobae Sep 19, 2026
88c68a3
test(project): register parent-swap authority regression
seonghobae Sep 19, 2026
ac5e5c5
test(project): keep parent-swap regression warning-clean on Windows
seonghobae Sep 19, 2026
f99eee8
fix(project): bind first-save publication to staged identity
seonghobae Sep 19, 2026
8a7d3e9
fix(project): keep persistence engine path stable under integration i…
seonghobae Sep 19, 2026
66515cd
test(project): drive recovery cases through public owner state machine
seonghobae Sep 19, 2026
c6aa06b
test(project): build hostile journal fixtures through durable public …
seonghobae Sep 19, 2026
951ef26
test(project): exercise rollback identity through recovery entrypoint
seonghobae Sep 19, 2026
c8eaa89
test(project): preserve foreign stage on first-save parent swap
seonghobae Sep 19, 2026
7e87a41
fix(project): keep first-save test seams out of production
seonghobae Sep 19, 2026
e3b5040
test(project): prove private journal through production replacement
seonghobae Sep 19, 2026
c16f69a
ci(project): track persistence engine owner on macOS
seonghobae Sep 19, 2026
1bd9637
ci(project): track persistence engine owner on Windows
seonghobae Sep 19, 2026
cbb62d3
test(project): gate native CI on persistence engine changes
seonghobae Sep 19, 2026
e112ba4
fix(project): isolate superseded first-save writer to tests
seonghobae Sep 19, 2026
42d4664
fix(project): use one first-save publication seam
seonghobae Sep 19, 2026
51310c8
ci(project): deny owned Tauri warnings in persistence gate
seonghobae Sep 19, 2026
2b2326c
fix(project): restore complete Tauri entrypoint
seonghobae Sep 19, 2026
90aa59b
ci(project): test exact persistence source head
seonghobae Sep 19, 2026
fab6d10
test(project): preserve ambiguous rollback evidence
seonghobae Sep 19, 2026
33aa68d
fix(project): fail closed on ambiguous rollback recovery
seonghobae Sep 19, 2026
c573b2b
revert: keep proven rollback cleanup semantics
seonghobae Sep 19, 2026
bd88318
revert: avoid unsupported rollback guard
seonghobae Sep 19, 2026
8ba3d99
test(project): add out-of-process first-save interruption
seonghobae Sep 19, 2026
ca7e682
test(project): include process-kill recovery case
seonghobae Sep 19, 2026
834e561
test(project): reject linked roots during provisioning
seonghobae Sep 19, 2026
6e235a4
ci(project): cover project-root authority regression
seonghobae Sep 19, 2026
93da927
ci(project): cover project-root authority regression on Windows
seonghobae Sep 19, 2026
f566951
fix(project): provision roots without following links
seonghobae Sep 19, 2026
066a274
fix(project): bind new roots to safe provisioning
seonghobae Sep 19, 2026
79eee50
test(project): cover ordinary safe root provisioning
seonghobae Sep 19, 2026
7949820
docs(project): trace project-root provisioning authority
seonghobae Sep 19, 2026
e1f06cd
docs(project): add provisioning Security Notes
seonghobae Sep 19, 2026
f8ba050
test(project): consolidate root authority into warning-gated harness
seonghobae Sep 19, 2026
f45df9e
test(project): reproduce linked cache temp scores authority
seonghobae Sep 19, 2026
acd29ba
fix(project): bind cache temp scores to owned directory authority
seonghobae Sep 19, 2026
4b17802
fix(project): apply owned authority to cache temp scores
seonghobae Sep 19, 2026
c6d8c5e
fix(project): restore queued progress contract
seonghobae Sep 19, 2026
d913537
docs(project): extend workspace authority traceability
seonghobae Sep 19, 2026
fcfb00a
test(project): require private app-owned directory modes
seonghobae Sep 19, 2026
73b2fbb
fix(project): create Unix app-owned directories privately
seonghobae Sep 19, 2026
5691785
docs(project): trace private app-owned directory creation
seonghobae Sep 19, 2026
9639876
test(audio): require private local source staging
seonghobae Sep 19, 2026
35548ea
test(audio): bind materializer to private stage owner
seonghobae Sep 19, 2026
d2ede94
fix(audio): create local source stages owner-private
seonghobae Sep 19, 2026
a984dd5
fix(audio): use private source staging boundary
seonghobae Sep 19, 2026
cf73bb2
docs(audio): trace private local source staging
seonghobae Sep 19, 2026
d75c3c8
fix(audio): keep private stage helper warning-clean
seonghobae Sep 19, 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
83 changes: 83 additions & 0 deletions .github/workflows/project-persistence-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: project-persistence-macos

on:
pull_request:
branches:
- develop
- main
paths:
- "apps/desktop/core/Cargo.toml"
- "apps/desktop/core/src/root.rs"
- "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_load.rs"
- "apps/desktop/src-tauri/src/project_persistence.rs"
- "apps/desktop/src-tauri/src/project_persistence_engine.rs"
- "apps/desktop/src-tauri/src/project_root.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.case"
- "apps/desktop/src-tauri/tests/project_root_existing_authority.rs"
- "docs/traceability/project-persistence-native-ci.md"
- ".github/workflows/project-persistence-macos.yml"
- "services/analysis-engine/tests/test_project_persistence_workflow_policy.py"
push:
branches:
- develop
- main
paths:
- "apps/desktop/core/Cargo.toml"
- "apps/desktop/core/src/root.rs"
- "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_load.rs"
- "apps/desktop/src-tauri/src/project_persistence.rs"
- "apps/desktop/src-tauri/src/project_persistence_engine.rs"
- "apps/desktop/src-tauri/src/project_root.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.case"
- "apps/desktop/src-tauri/tests/project_root_existing_authority.rs"
- "docs/traceability/project-persistence-native-ci.md"
- ".github/workflows/project-persistence-macos.yml"
- "services/analysis-engine/tests/test_project_persistence_workflow_policy.py"

permissions:
contents: read

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

jobs:
macos-recovery-cleanup:
name: test / project-persistence / macos
runs-on: macos-15
permissions:
contents: read
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Install Rust 1.97.1
run: rustup toolchain install 1.97.1 --profile minimal
- name: Prepare compile-only frontendDist fixture
run: |
mkdir -p apps/desktop/dist
printf '%s' '<!doctype html><title>BandScope test fixture</title>' > apps/desktop/dist/index.html
- name: Run macOS recovery-cleanup regression
run: cargo +1.97.1 test --manifest-path apps/desktop/src-tauri/Cargo.toml --no-default-features --features persistence_warning_gate --tests
84 changes: 84 additions & 0 deletions .github/workflows/project-persistence-windows-native.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: project-persistence-windows-native

on:
pull_request:
branches:
- develop
- main
paths:
- "apps/desktop/core/Cargo.toml"
- "apps/desktop/core/src/root.rs"
- "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_load.rs"
- "apps/desktop/src-tauri/src/project_persistence.rs"
- "apps/desktop/src-tauri/src/project_persistence_engine.rs"
- "apps/desktop/src-tauri/src/project_root.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.case"
- "apps/desktop/src-tauri/tests/project_root_existing_authority.rs"
- "docs/traceability/project-persistence-native-ci.md"
- ".github/workflows/project-persistence-windows-native.yml"
- "services/analysis-engine/tests/test_project_persistence_workflow_policy.py"
push:
branches:
- develop
- main
paths:
- "apps/desktop/core/Cargo.toml"
- "apps/desktop/core/src/root.rs"
- "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_load.rs"
- "apps/desktop/src-tauri/src/project_persistence.rs"
- "apps/desktop/src-tauri/src/project_persistence_engine.rs"
- "apps/desktop/src-tauri/src/project_root.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.rs"
- "apps/desktop/src-tauri/tests/project_persistence*.case"
- "apps/desktop/src-tauri/tests/project_root_existing_authority.rs"
- "docs/traceability/project-persistence-native-ci.md"
- ".github/workflows/project-persistence-windows-native.yml"
- "services/analysis-engine/tests/test_project_persistence_workflow_policy.py"

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
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- 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 --features persistence_warning_gate --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`).
6 changes: 5 additions & 1 deletion apps/desktop/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ publish = false

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

[features]
default = []
persistence_warning_gate = []

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