Skip to content
Draft
Show file tree
Hide file tree
Changes from 233 commits
Commits
Show all changes
340 commits
Select commit Hold shift + click to select a range
3ac09a6
test(audio): preserve structured resource rejection contract
seonghobae Sep 1, 2026
336195a
fix(audio): preserve resource rejection provenance
seonghobae Sep 1, 2026
7862ad2
test(audio): fail closed on parser ValueError leakage
seonghobae Sep 1, 2026
1f33cde
fix(audio): contain metadata parser ValueError details
seonghobae Sep 1, 2026
2ca91e0
test(audio): require one canonical PCM decode port
seonghobae Sep 2, 2026
5cc67e1
test(audio): keep decode-port RED compatible with frozen policy
seonghobae Sep 2, 2026
4b3009c
fix(audio): own one bounded PCM decode port
seonghobae Sep 2, 2026
c2e6509
fix(audio): route MIR consumers through owned decode port
seonghobae Sep 2, 2026
3a76907
test(audio): follow the owned decode-port preflight seam
seonghobae Sep 2, 2026
c5cc94f
fix(audio): document decode-port regressions
seonghobae Sep 3, 2026
609de8d
Merge protected develop into Resource Admission owner
seonghobae Sep 3, 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
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
ebc5055
test(audio): require durable publication commit
seonghobae Sep 7, 2026
d794555
fix(audio): add platform publication durability barrier
seonghobae Sep 7, 2026
4e2bccc
test(audio): compile publication durability tests
seonghobae Sep 7, 2026
94086ed
fix(audio): durably commit local source publication
seonghobae Sep 7, 2026
e3f6151
docs(audio): record crash-durable source publication
seonghobae Sep 7, 2026
00f720c
docs(audio): doctor publication durability boundary
seonghobae Sep 7, 2026
60816b1
test(audio): preserve existing publication on commit failure
seonghobae Sep 7, 2026
6011294
fix(audio): preserve existing source on publication collision
seonghobae Sep 7, 2026
53747bd
test(audio): bind decoded memory ceiling to canonical float32
seonghobae Sep 7, 2026
379d4a1
fix(audio): cap canonical decoded buffer at float32 footprint
seonghobae Sep 7, 2026
6b16e3c
docs(audio): doctor resource policy v2 memory contract
seonghobae Sep 7, 2026
e96b6f0
test(audio): require canonical float32 decoded PCM
seonghobae Sep 7, 2026
b24a6ff
fix(audio): enforce canonical float32 decoded PCM
seonghobae Sep 7, 2026
3ee3f64
docs(audio): record canonical PCM dtype policy
seonghobae Sep 7, 2026
623294d
docs(audio): doctor canonical float32 admission
seonghobae Sep 7, 2026
6a329fe
style(audio): restore transcription EOF formatting
seonghobae Sep 7, 2026
44a9087
style(audio): restore temporal EOF formatting
seonghobae Sep 7, 2026
31a7b79
style(audio): restore separator EOF formatting
seonghobae Sep 7, 2026
8adcec8
test(audio): align resource policy version regression
seonghobae Sep 7, 2026
f294100
test(audio): bind metadata errors to policy version
seonghobae Sep 7, 2026
370a3d5
test(runtime): require native analysis cancellation
seonghobae Sep 7, 2026
0238c67
fix(runtime): add typed analysis cancellation error
seonghobae Sep 7, 2026
7aa8055
fix(runtime): expose cancelled job error contract
seonghobae Sep 7, 2026
4b85582
fix(runtime): cancel active analysis children
seonghobae Sep 7, 2026
c4e2f30
docs(runtime): record native cancellation boundary
seonghobae Sep 7, 2026
0a54d60
docs(runtime): record analysis cancellation behavior
seonghobae Sep 7, 2026
12cc6bd
test(runtime): bind cancellation error wire value
seonghobae Sep 7, 2026
36c5605
fix(runtime): declare cancellation command permission
seonghobae Sep 7, 2026
a90a7ea
fix(runtime): grant analysis cancellation capability
seonghobae Sep 7, 2026
b746f60
fix(runtime): add generated cancellation permission contract
seonghobae Sep 7, 2026
9e5d1d5
test(runtime): bind cancellation command capability
seonghobae Sep 7, 2026
2dac5b6
docs(audio): bind cancellation to Tauri runtime authority
seonghobae Sep 7, 2026
2f254ac
docs(security): bind analysis cancellation IPC authority
seonghobae Sep 7, 2026
1756759
docs(architecture): record Tauri command authority boundary
seonghobae Sep 7, 2026
d3f6b53
test(tauri): require cancellation permission in generated schemas
seonghobae Sep 7, 2026
a4c1d71
fix(tauri): refresh generated cancellation capability snapshot
seonghobae Sep 7, 2026
ae4d4d3
fix(tauri): regenerate cancellation permission schema
seonghobae Sep 7, 2026
3bfe659
fix(tauri): restore complete generated desktop schema
seonghobae Sep 7, 2026
a9a7e27
test(tauri): fail on tracked generated schema drift
seonghobae Sep 7, 2026
ea97fc0
fix(tauri): avoid build-mutated schema worktree assertion
seonghobae Sep 7, 2026
5e0180e
docs(architecture): align resource admission and cancellation truth
seonghobae Sep 7, 2026
2d21b6e
docs(architecture): sync local-first resource boundary
seonghobae Sep 7, 2026
1161252
docs(doctoring): trace process-tree containment constraints
seonghobae Sep 7, 2026
6b416c0
test(audio): enforce encoded size at decode boundary
seonghobae Sep 7, 2026
6afb2d8
fix(audio): enforce encoded bytes in decode port
seonghobae Sep 7, 2026
959891e
test(audio): reject non-mono decoder output before normalization
seonghobae Sep 7, 2026
65c9b6a
fix(audio): fail closed on non-mono decoder shapes
seonghobae Sep 7, 2026
ec6c41e
style(audio): restore canonical Python file terminator
seonghobae Sep 7, 2026
b34be05
test(audio): require renderer cancellation bridge
seonghobae Sep 7, 2026
aa07f08
fix(audio): expose cancellation through renderer bridge
seonghobae Sep 7, 2026
4fed274
test(audio): cover cancellation bridge races
seonghobae Sep 7, 2026
d3a50f2
test(audio): expose terminal cancellation race
seonghobae Sep 7, 2026
7991631
test(audio): pin cancellation acceptance lock
seonghobae Sep 7, 2026
2fba61c
fix(audio): serialize terminal cancellation
seonghobae Sep 7, 2026
fced227
docs(audio): record cancellation ordering invariant
seonghobae Sep 7, 2026
23445c1
test(audio): expose queued cancellation cleanup race
seonghobae Sep 7, 2026
4956aac
fix(audio): serialize queued cancellation cleanup
seonghobae Sep 7, 2026
c8a4869
fix(score): restore project score root call
seonghobae Sep 7, 2026
f402f54
docs: establish product technical gap baseline
seonghobae Sep 7, 2026
3dd62bb
test(tauri): gate cancellation on runtime authority
seonghobae Sep 7, 2026
aa1c938
test(tauri): match generic cancellation finalizer
seonghobae Sep 7, 2026
db1a18f
test(tauri): parse generated cancellation schemas
seonghobae Sep 7, 2026
a8bd64a
test(tauri): validate cancellation schema structure
seonghobae Sep 7, 2026
8f0d89e
style(tauri): format schema contract helper
seonghobae Sep 7, 2026
b0384cb
test(audio): reject post-admission decode growth
seonghobae Sep 7, 2026
c0b9c2f
fix(audio): bound decoder reads to admitted bytes
seonghobae Sep 7, 2026
f995307
test(audio): cover bounded readinto EOF semantics
seonghobae Sep 7, 2026
7152b92
test(audio): cover bounded seek branches
seonghobae Sep 7, 2026
7413f92
docs(audio): doctor bounded decode authority
seonghobae Sep 7, 2026
a7282aa
test(audio): reject invalid publication identity JSON
seonghobae Sep 7, 2026
43b889e
fix(audio): validate publication identity deserialization
seonghobae Sep 7, 2026
1789da7
docs(product): refresh audio admission gap baseline
seonghobae Sep 7, 2026
593d44e
test(audio): expose pre-normalization decoder budget gap
seonghobae Sep 7, 2026
f606236
fix(audio): reject over-budget decoder buffers before normalization
seonghobae Sep 7, 2026
2299b21
docs(product): record decoder pre-normalization resource guard
seonghobae Sep 7, 2026
c040eed
docs(audio): distinguish decoder allocation from canonical artifact b…
seonghobae Sep 7, 2026
24465db
docs(changelog): clarify decoder allocation admission
seonghobae Sep 7, 2026
dcfa90b
test(audio): cap finiteness validation temporary memory
seonghobae Sep 7, 2026
a98165a
fix(audio): bound finiteness scan temporary memory
seonghobae Sep 7, 2026
bfeefe8
docs(audio): record bounded finiteness validation memory
seonghobae Sep 7, 2026
f7f5be0
docs(audio): trace bounded finiteness scan memory
seonghobae Sep 7, 2026
6c559ca
docs(audio): record bounded finiteness scan fix
seonghobae Sep 7, 2026
9b5d1e9
test(audio): assert finiteness rejection provenance
seonghobae Sep 7, 2026
8a4d6f0
test(audio): freeze decoder dtype and resampler contract
seonghobae Sep 7, 2026
2d98bfb
fix(audio): pin canonical decode dtype and resampler
seonghobae Sep 7, 2026
bcb533f
test(audio): align decode-port contract with pinned resampler
seonghobae Sep 7, 2026
3761c75
fix(audio): satisfy reproducibility regression lint
seonghobae Sep 7, 2026
e24d7ce
fix(audio): apply pinned Ruff formatter output
seonghobae Sep 7, 2026
5e303e0
docs(audio): pin canonical decoder reproducibility evidence
seonghobae Sep 7, 2026
815841d
docs(changelog): record canonical decoder pin
seonghobae Sep 7, 2026
c60fb7c
docs(audio): narrow decoder reproducibility claim
seonghobae Sep 7, 2026
fb000fb
docs(changelog): narrow decoder reproducibility claim
seonghobae Sep 7, 2026
da43fea
test(audio): reject decoder views retaining oversized backing memory
seonghobae Sep 7, 2026
e2d39f9
fix(audio): reject decoder views with hidden backing memory
seonghobae Sep 7, 2026
f80b962
docs(audio): record hidden decoder backing-memory admission gap
seonghobae Sep 7, 2026
ab94470
test(audio): require owned PCM for decoder views
seonghobae Sep 7, 2026
1a35277
fix(audio): detach decoder views into owned PCM
seonghobae Sep 7, 2026
44fbdcf
docs(audio): distinguish retained artifact memory from decoder peak RSS
seonghobae Sep 7, 2026
eab2c68
docs(audio): record owned canonicalization of decoder views
seonghobae Sep 7, 2026
8fc4da8
docs(audio): doctor decoder view ownership boundary
seonghobae Sep 7, 2026
574e86d
test(audio): reject malformed decoder dtypes
seonghobae Sep 7, 2026
8f7e1a5
fix(audio): fail closed on malformed decoder dtypes
seonghobae Sep 7, 2026
45b1727
docs(audio): record decoder dtype admission boundary
seonghobae Sep 7, 2026
bc8aa65
test(audio): prove dtype rejection precedes PCM allocation
seonghobae Sep 7, 2026
25ff54f
test(audio): reject canonicalization budget expansion
seonghobae Sep 7, 2026
2216a1d
fix(audio): budget canonical PCM before allocation
seonghobae Sep 7, 2026
43ce16f
docs(audio): record canonicalization budget boundary
seonghobae Sep 7, 2026
0510b57
test(audio): resolve duplicate resource-policy import
seonghobae Sep 7, 2026
0467043
test(audio): pin allocation rejection provenance
seonghobae Sep 7, 2026
4861e78
test(audio): reject canonical allocation exhaustion
seonghobae Sep 7, 2026
c19f60b
fix(audio): normalize canonical allocation exhaustion
seonghobae Sep 7, 2026
664efd0
docs(audio): record allocator-failure claim boundary
seonghobae Sep 7, 2026
ba53156
docs(audio): record canonical allocation exhaustion
seonghobae Sep 7, 2026
fb94f21
test(audio): distinguish pre-canonical allocation failure
seonghobae Sep 7, 2026
cacc982
fix(audio): scope allocator budget mapping to canonical copy
seonghobae Sep 7, 2026
69adec3
docs(audio): distinguish canonical allocation exhaustion
seonghobae Sep 7, 2026
95d9cc7
test(audio): pin allocator exception provenance
seonghobae Sep 7, 2026
cd3e0d5
test(audio): reject empty YouTube artifact with correct reason
seonghobae Sep 7, 2026
f925e23
fix(audio): preserve YouTube admission failure reason
seonghobae Sep 7, 2026
eed3f8e
fix(audio): lease YouTube artifact ownership per video
seonghobae Sep 7, 2026
d04d1c1
test(audio): create malformed YouTube output under active lease
seonghobae Sep 7, 2026
ef95475
test(audio): isolate same-ID YouTube cache ownership
seonghobae Sep 7, 2026
ab7a4c1
fix(audio): bind YouTube cleanup to leased video identity
seonghobae Sep 7, 2026
8facfa0
test(audio): reject noncanonical YouTube completed filename
seonghobae Sep 7, 2026
c4c2c9e
fix(audio): require canonical YouTube completed artifact name
seonghobae Sep 7, 2026
ef5b223
docs(audio): bind YouTube completion to canonical filename
seonghobae Sep 7, 2026
f23ba9f
test(audio): preserve nontransient same-ID cache files
seonghobae Sep 7, 2026
3dc1bb4
test(audio): bound transient sibling sweep
seonghobae Sep 7, 2026
b82bfdf
fix(audio): restrict YouTube abort cleanup authority
seonghobae Sep 7, 2026
d2b72b9
test(audio): preserve yt-dlp part-fragment cleanup
seonghobae Sep 7, 2026
09bb020
fix(audio): normalize yt-dlp part-fragment cleanup stems
seonghobae Sep 7, 2026
be97c73
test(audio): preserve YouTube IDs containing fragment tokens
seonghobae Sep 8, 2026
98366b6
fix(audio): preserve fragment tokens in YouTube video IDs
seonghobae Sep 8, 2026
0e11700
style(audio): restore youtube module terminator
seonghobae Sep 8, 2026
3c39fa7
docs(audio): record YouTube fragment identity boundary
seonghobae Sep 8, 2026
7664e34
docs(audio): record fragment identity cleanup fix
seonghobae Sep 8, 2026
c09ec58
test(audio): constrain yt-dlp fragment cleanup to ASCII indices
seonghobae Sep 8, 2026
668d726
fix(audio): match yt-dlp ASCII fragment indices exactly
seonghobae Sep 8, 2026
ab569ca
docs(audio): narrow yt-dlp fragment cleanup authority
seonghobae Sep 8, 2026
740c357
docs(audio): trace yt-dlp fragment index grammar
seonghobae Sep 8, 2026
21458ae
docs(audio): record ASCII fragment cleanup contract
seonghobae Sep 8, 2026
f551694
test(audio): reject fragment lookalikes ending in part
seonghobae Sep 8, 2026
7a0387f
fix(audio): reject fragment suffix lookalikes before part cleanup
seonghobae Sep 8, 2026
af94694
test(audio): require Unix analysis process-group containment
seonghobae Sep 8, 2026
4e0aa5d
fix(audio): contain analysis descendants on Unix
seonghobae Sep 8, 2026
3ece757
docs(audio): record Unix cancellation containment
seonghobae Sep 8, 2026
e6f5d36
docs(audio): trace Unix process-group cancellation
seonghobae Sep 8, 2026
55764a1
docs(audio): log Unix descendant cancellation
seonghobae Sep 8, 2026
a07be5c
docs(architecture): record Unix analysis containment
seonghobae Sep 8, 2026
143f04b
docs(security): narrow Unix cancellation claim
seonghobae Sep 8, 2026
65c94f7
test(audio): expose YouTube descendant timeout leak
seonghobae Sep 8, 2026
81a4890
fix(audio): contain YouTube import descendants on Unix
seonghobae Sep 8, 2026
9c36cf0
test(audio): verify YouTube containment in shell gate
seonghobae Sep 8, 2026
e8b887c
docs(audio): record YouTube descendant containment gap repair
seonghobae Sep 8, 2026
5f7692f
docs(audio): record YouTube subprocess containment
seonghobae Sep 8, 2026
066d891
docs(architecture): include YouTube process containment
seonghobae Sep 8, 2026
76ca2c0
docs(security): include YouTube descendant containment
seonghobae Sep 8, 2026
91b64cf
docs(doctoring): trace YouTube process containment
seonghobae Sep 8, 2026
04e4d5c
test(process): require shared containment owner
seonghobae Sep 8, 2026
25dd7a5
refactor(process): share containment primitives
seonghobae Sep 8, 2026
e772af6
docs(process): record shared containment owner
seonghobae Sep 8, 2026
e395dc4
docs(gap): mark containment ownership consolidated
seonghobae Sep 8, 2026
650d93f
docs(changelog): record containment consolidation
seonghobae Sep 8, 2026
ce96055
docs(architecture): point process containment to shared owner
seonghobae Sep 8, 2026
6619840
docs(security): consolidate subprocess containment owner
seonghobae Sep 8, 2026
5771e9b
test(process): align containment platform guards
seonghobae Sep 8, 2026
bb14420
fix(process): align containment platform guards
seonghobae Sep 8, 2026
3b2df5d
test(process): scope core containment regression
seonghobae Sep 8, 2026
c1c2106
test(process): scope Tauri containment regression
seonghobae Sep 8, 2026
9b6340a
test(process): reject success-path descendant pipe hang
seonghobae Sep 8, 2026
650ff2f
fix(process): drain residual descendants after parent exit
seonghobae Sep 8, 2026
04ebdf1
docs(product): cover terminal descendant containment
seonghobae Sep 8, 2026
5e1903d
docs(changelog): record terminal descendant cleanup
seonghobae Sep 8, 2026
6d3af83
docs(security): doctor subprocess terminal containment
seonghobae Sep 8, 2026
1c2f9b9
docs(architecture): align subprocess containment truth
seonghobae Sep 8, 2026
26b16ae
docs(security): cover terminal descendant pipe cleanup
seonghobae Sep 8, 2026
fb04b95
test(process): reject unbounded import output capture
seonghobae Sep 8, 2026
90cbe99
fix(process): bound captured helper output
seonghobae Sep 8, 2026
6abb294
refactor(process): expose bounded output owner
seonghobae Sep 8, 2026
2b99124
docs(process): bound helper output evidence
seonghobae Sep 8, 2026
0fbe2cf
docs(gap): include bounded subprocess output admission
seonghobae Sep 8, 2026
c7334e5
docs(security): bound subprocess capture memory
seonghobae Sep 8, 2026
d766304
docs(changelog): record bounded helper output
seonghobae Sep 8, 2026
a0d7f13
fix(process): compile Unix group termination
seonghobae Sep 8, 2026
11acaf5
test(audio): reject slow helper after output overflow
seonghobae Sep 8, 2026
ab9b8a1
fix(audio): terminate helper on output admission failure
seonghobae Sep 8, 2026
0dc2faf
docs(audio): record prompt output-admission termination
seonghobae Sep 8, 2026
8770768
docs(product): align helper-output admission baseline
seonghobae Sep 8, 2026
170a2e8
docs(changelog): record helper overflow termination
seonghobae Sep 8, 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
11 changes: 6 additions & 5 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-07

## Brand source

Expand Down Expand Up @@ -111,9 +111,10 @@ 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.
- 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.
- Those bootstrap roots should resolve from app-owned Tauri data/cache paths instead of the shared system temp namespace.
- Local analysis orchestration uses typed Tauri IPC commands and a Python subprocess over stdin/stdout rather than a loopback HTTP listener. Renderer-visible commands are synchronized across the invoke handler, `AppManifest::commands`, generated command permissions, and the window capability; the WebView never receives a PID or generic process handle.
- Local audio intake validates source metadata and encoded size before decode, stages admitted bytes into an app-owned project area, and commits the immutable project source with a path-free size/SHA-256 receipt. Unix publication uses a same-filesystem no-clobber hard link plus project-directory synchronization; Windows uses no-replace `MoveFileExW` with `MOVEFILE_WRITE_THROUGH`. A pre-existing project source is preserved rather than overwritten or deleted.
- Those project and temp/cache roots resolve from app-owned Tauri data/cache paths instead of the shared system temp namespace.
- Analysis cancellation is job-specific. Queued work can terminate as typed `cancelled`; running work currently kills and reaps only the directly owned analysis child. This is not process-tree containment: descendant termination, inherited-handle closure, temp-artifact cleanup, and bounded cancellation latency remain acceptance work across Windows/macOS/Linux.
- 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 All @@ -126,4 +127,4 @@ Last updated: 2026-03-11
- Security docs and checks are part of the default quickcheck path so design drift is caught early.
- Supply-chain docs, workflow pinning, and lockfile verification are part of the default quickcheck path so dependency drift is caught early.
- Quickcheck and CI are expected to verify dependency review, audit, supplemental inventory, and SBOM baseline presence as part of bootstrap.
- Cross-platform build workflow presence and trigger coverage are part of the default supply-chain verification path.
- Cross-platform build workflow presence and trigger coverage are part of the default supply-chain verification path so dependency drift is caught early.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@
- Display the analyzed song tempo (BPM) as a badge in the rehearsal workspace.
- 각 합주 역할(Role)별 개인 연습 진행도를 0~100% 범위로 기록 및 시각화할 수 있는 연습 진척도(`practiceProgress`) 트래커 기능 추가. UI 컨트롤(슬라이더 및 +/- 버튼)과 한/영 다국어 지원 포함.

### Fixed

- 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.
Comment thread
cursor[bot] marked this conversation as resolved.
- Commit an admitted local source through a platform-specific no-clobber durability barrier before returning path-free project authority: Unix synchronizes the project directory after hard-link publication/stage removal, while Windows uses no-replace `MoveFileExW` with `MOVEFILE_WRITE_THROUGH`.
- 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.
- Advance the local-audio resource policy to v2 and bind the admitted canonical decoded mono buffer to the production float32 representation: 158,760,000 bytes for the existing 39,690,000-sample / 15-minute ceiling, preventing a wider floating buffer from silently consuming twice the intended canonical artifact memory while keeping the same sample count.
- Advance the local-audio resource policy to v3 and require the PCM artifact admitted to MIR to be native NumPy `float32`; noncanonical artifacts passed directly to policy validation fail closed with `decoded_dtype_unsupported`, while decoder-returned floating arrays are normalized only after their sample count and already-allocated bytes fit the shared policy.
- Reject an oversized or over-budget decoder-returned array before float32 normalization can allocate a second canonical PCM buffer; decoder/resampler allocations made internally before `librosa.load` returns remain outside the artifact ceiling and require separate peak-RSS measurement.
- Bound canonical PCM finiteness validation to 1 MiB temporary boolean-mask chunks instead of allocating a full-song NumPy mask, while preserving NaN and positive/negative infinity rejection.
- Add job-specific native analysis cancellation without exposing PIDs or generic process authority to the renderer: queued work can terminate as typed `cancelled`, running work kills and reaps the directly owned analysis child, and the worker clears cancellation state and releases its in-flight slot once. Process-tree containment and measured descendant/temp cleanup remain separate acceptance work.
- 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.

### Changed

- Consolidated Bandit, dependency audits, supplemental secret checks, and Trivy into one trusted-branch security backstop, delegated CodeQL to GitHub default setup, and removed duplicate local PR security and release-preflight runs.
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ BandScope is a local-first desktop app for rehearsal prep: it turns a song into
Three layers, decoupled through shared contracts:

- `apps/desktop` — Tauri 2 + Vite + React 19 shell (Tailwind 4, Base UI, Storybook). Feature screens live in `src/features/` (home, workspace, chords, ranges, player, settings). The ready workspace names tonight's first playable range and the next instrument check. `src/lib/analysis.ts` and `src/lib/job_runner.ts` call typed Tauri IPC commands, with a browser fallback that serves demo data when not running inside Tauri.
- `apps/desktop/src-tauri/src/main.rs` — the Rust orchestration boundary. Tauri commands (`start_analysis_job`, `get_analysis_job_status`, `select_local_audio_source`, `import_youtube_url`) validate untrusted input (project IDs, file paths, URLs) and spawn the Python engine as a subprocess. There is no loopback HTTP listener and no network path for local analysis.
- `apps/desktop/src-tauri/src/main.rs` — the Rust orchestration boundary. Tauri commands cover analysis start/status/cancellation, local-audio selection and YouTube import, project save/load, and bounded score-PDF attach/read/remove operations. Each renderer-visible application command must remain synchronized across the invoke handler, `AppManifest::commands`, generated permission, and window capability. Commands validate untrusted input and spawn the allowlisted Python engine as a subprocess; no PID or generic process handle is exposed to the WebView. There is no loopback HTTP listener and no network path for local analysis.
- `services/analysis-engine` — Python package `bandscope_analysis` (librosa/numpy). Entry point `cli.py` reads a JSON job request on stdin and prints a structured job-status JSON envelope on stdout (`--progress-jsonl` streams progress lines). `api.py` orchestrates the pipeline across the `separation`, `sections`, `roles`, `chords`, `ranges`, `temporal`, `transcription`, and `youtube` modules.

Data flow: React UI → Tauri IPC command → Rust validation + Python subprocess over stdin/stdout → job status and progress events emitted back to the UI.
Expand Down
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
Loading