Repository navigation
[Reliability] Add a versioned crash-safe project format, autosave, migration and recovery #962
Description
Activity
- addedarea: accessibilityAccessibility and assistive-technology supportAccessibility and assistive-technology supportarea: apiAPI, protocol, event, or external contractAPI, protocol, event, or external contractarea: authAuthentication, authorization, identity, or tenant isolationAuthentication, authorization, identity, or tenant isolationarea: securitySecurity boundary, hardening, or vulnerability preventionSecurity boundary, hardening, or vulnerability preventionpriority: mediumNormal-priority or P2 workNormal-priority or P2 workscope: product-gapCustomer-visible product gapCustomer-visible product gapscope: researchResearch, statistical validation, or scientific evidenceResearch, statistical validation, or scientific evidencestatus: triagedOpen issue has an organization taxonomy assignmentOpen issue has an organization taxonomy assignmenttype: featureNew or expanded product capabilityNew or expanded product capability
on Aug 22, 2026 seonghobae commented
on Sep 5, 2026 CollaboratorAuthorMore actionsFresh prerequisite finding from the #961/#1160 player stack: the current shared
RehearsalSongcontract already admitstempo,collaboration, and role-levelharmonicExplanation,transpositionPlan,transcription, andpracticeProgress, while nativeRehearsalSongPayloadon #1160 predecessorded24060f7cd7e3ab5cc69111d7545e76ccbbe0eomitted them underdeny_unknown_fields. The ordinary renderer Save path validates the shared contract first and then nativesave_projectdeserializes it again, so a valid current song could fail withInvalid project payloadbefore reaching disk.A test-first prerequisite repair is now carried on Draft #1160 because selected-source persistence cannot safely build on a Save path that rejects the current song contract: RED
0926ab89950221e595e0f002962838330b464066adds an exact native round-trip fixture; causal fix38b1328b12bf2285f3ca632f208ecf82029ede0arestores structural field parity without weakeningdeny_unknown_fields; TRACEABILITY44601e9d49e6c7caf163f7ffab4edffb71a3f55d; current format documentation978441510fc85206626a6aa4695fba4e8a5313dd.This does not transfer #962 ownership into #1160 and does not claim crash safety.
save_projectstill publishes with directstd::fs::write;project_format_version, atomic stage/flush/validate/replace, backup, autosave, recovery, migration, bounds/fault injection and portable durable player semantics remain #962 work. When Active Player selection becomes durable, persist a stable semantic (e.g. source kind) through this canonical project contract, never the revocable opaque playback authority or renderer-local receipt.- added a commit that references this issue
on Sep 5, 2026 seonghobae commented
on Sep 5, 2026 CollaboratorAuthorMore actionsCanonical #970 owner update: protected-base drift is repaired without force-push.
fix/project-save-atomic-publication-962now descends fromdevelop@314ddeae7b775a4957594b599358c8255617eb2ethrough two-parent merge7e2fb827198655e46ebc87d7faa70bb853c28921; fresh compare isbehind_by=0while retaining the Project Persistence delta.New canonical RED
93e9e80fa13d93692fdbd8d7d9acd10714ee8e8dproves current strict native persistence still rejects sharedRehearsalSongfields already present in the product contract: collaboration and role-levelharmonicExplanation,transpositionPlan,transcription,practiceProgress. Keepdeny_unknown_fieldsand the v1 envelope; repair by typed DTO parity rather thanserde_json::Valuepassthrough. Until that RED is GREEN, #970 must remain Draft.Separately, RED
becb11c0a75059fdf5889b8181c962a58de468e8exposed that the Windows persistence evidence lane was not triggered by core DTO/fixture or Tauri entry/manifests changes. Fix5b397ce9cc8bf5aa8bb1cb61a826a2f0091587b9expands only the path filter; the pinned Windows test command and protected gates are unchanged.Selected Active Player source persistence remains downstream of this foundation: persist a stable semantic (
full_mix|vocals|bass|drums|otheror its eventual canonical equivalent), never a revocablebandscope-playbackauthority; reload must re-resolve through current native availability and fail closed to Full mix when unavailable.seonghobae commented
on Sep 5, 2026 CollaboratorAuthorMore actionsCanonical Project Persistence owner #970 advanced to exact head
c461d4664fd372964306328962c44bfea76b7286without force-push. The shared-song schema drift is now repaired in the owner branch rather than duplicated downstream: structural RED93e9e80fa13d93692fdbd8d7d9acd10714ee8e8d→ typed DTO fix819d8af80e425dc5627d86659a5fc97ec90c2767, then domain-parity RED6bcdf160a7e95cc540d96e49e25868c19a438106→ fixa1cf37ea98db2f8024ca710d563d879c04204961. Native persistence now preserves current collaboration plus roleharmonicExplanation,transpositionPlan,transcription, andpracticeProgress, uses exact shared collaboration state enums, and rejects progress outside integer 0..100 while retainingdeny_unknown_fields, finite-positive tempo validation, andprojectFormatVersion: 1. Traceability:docs/traceability/project-persistence-shared-song-contract.md.This does not complete #962. Remaining owner-path findings include exact cross-language parity for older stringly DTO domains and optional-field
nullsemantics, autosave/backup rotation, globally discoverable startup recovery, deterministic migrations beyond v1, restore/compare/discard UX, exhaustive fault injection, and stable selected-playback-source persistence. Selected source must be durable semantic (full_mix | vocals | bass | drums | other), never a revocablebandscope-playbackauthority; reload must resolve a fresh native authority and fail closed to Full mix when unavailable. Current exact-head hosted checks are still queued/pending, so #970 remains Draft and no GREEN/merge is claimed.seonghobae commented
on Sep 5, 2026 CollaboratorAuthorMore actionsFresh owner-path evidence from canonical Project Persistence PR #970:
- Current fix(project): enforce crash-safe revision-bound persistence #970 exact head is
aff7ecc4547f771eff6a0fc081e07077bc555f20, ordinary-descended from protecteddevelop@314ddeae7b775a4957594b599358c8255617eb2e(behind_by=0). - Shared-song structural parity, collaboration/progress domains, omission-vs-explicit-null semantics, and the remaining stringly shared closed domains are now covered by RED→fix chains on fix(project): enforce crash-safe revision-bound persistence #970. The latest chain is closed-domain RED
2b0a47e6305b7b7a3e87857335d0f36dfabc9712→ typed native fix96d66ed6f5fad918b0ddef8a1e6494b76f8bafd0, with positive coveragef8c30150375b39d54e1775d941f6515d2686410cfor every current valid section-form/confidence/provenance/role/cue/priority/export token.deny_unknown_fields, finite-positive tempo validation and the v1 envelope remain intact. - Current exact-head hosted workflows are materialized but non-terminal, so this is not repository GREEN and fix(project): enforce crash-safe revision-bound persistence #970 remains Draft.
Next durable Active Player integration should not be added as another optional field inside the existing v1 song payload. #970 already documents
projectFormatVersion: 1as a compatibility view until source/derived/decision/handoff/preference/runtime sections are promoted in a later format version, and this issue requires those concerns to remain separated. #1160 already defines the stable renderer semantic asfull_mix | vocals | bass | drums | other; a future project-format revision should persist that semantic in the preference/player-state boundary, never the revocablebandscope-playbackauthority. Reopen must resolve a fresh authority from current native availability and fail closed to Full mix when the saved semantic is unavailable.Do not silently expand v1 in a way an older v1 reader would reject without a version change. The next implementation slice therefore needs an explicit later-version envelope plus deterministic v1→current migration/fixture evidence before selected-source persistence is wired into #1160.
- Current fix(project): enforce crash-safe revision-bound persistence #970 exact head is
seonghobae commented
on Sep 5, 2026 CollaboratorAuthorMore actionsProject Persistence owner #970 advanced the selected-playback-source prerequisite instead of adding a second writer in #1160.
Current exact owner head:
ae97f885fbd91da1ec0958444b94e3af2fa68410.Test-first chain:
- RED
86207ea0459f1a6e27e80f571ad5d6462a0d6fab: v1/legacy → v2 migration, exactfull_mix | vocals | bass | drums | otherdomain, realisticbandscope-playback://...rejection, no-runtime-authority typed construction. - Causal source
be4ce61f9a865229aad9b46ad27adb79b1028258: currentprojectFormatVersion: 2boundary with typedpreferences.selectedPlaybackSource; historical v1/legacy parser remains the strict migration authority. - Golden v2 fixture
4aa18fa8cbe5e59cf3f1e195f9a20e51c36e4da7+ fixture test73dc9a7314c0e20938fc767c207e4102e1bbf106. - Format docs
9518d84eb621b03211a4ad5a164969268ae68cdd; Security Notes/decision traceabilityae97f885fbd91da1ec0958444b94e3af2fa68410.
Migration is deliberately evidence-conservative: v1 has no selected-stem record, so it migrates to
full_mixrather than fabricating a stem choice. Revocable playback URLs, filesystem paths, and generation receipts are not durable state.This does not close #962 or selected-source reopen. Existing Tauri song-only save callers now have a v2 compatibility writer but still write the deterministic Full-mix default. Next consumer work is #1160 → typed Project Persistence preference on save, then reopen → fresh native availability → fresh authority, falling back to Full mix when the persisted stem is unavailable. Autosave, backup rotation, startup recovery UX, migration receipts/hashes, downgrade/rollback, descriptor-bound parent authority, and exhaustive interruption/power-loss evidence remain open. #970 stays Draft pending exact-head checks and independent review.
- RED
44 remaining items
seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actionsProject Persistence owner #970 advanced the restart/reopen revision boundary on exact head
a6d399067186c74c94e7c488e0ed8ae4f9bd9fc8without moving ownership into Score Storage.Valid hosted RED:
1109799c69a2f75234f9ae6bd4e793191638be17added a native restart-binding regression requiring an existing app-owned workspace to return its current content revision when the renderer has lost its process-local receipt but the canonical reopened candidate is byte-identical. Pre-fix exact runs failed on both owner lanes: macOS35485742398/ job106011658681, Windows Server 202535485742321/ job106011658268.Repair: native Project Persistence now performs recovery and exact-workspace identity/digest validation under the existing process-external admission lease.
None + existing targetis accepted only for exact candidate equality, returning the current SHA-256 receipt without staging/replacing bytes. A differing existing workspace still fails closed withProject changed since it was opened.; selected/import file path or digest is never workspace authority. The renderer reopen bridge now binds through the BandScope-minted project id before returning the loaded document to UI state. An additional edge regression proved equality binding cannot bypass ordinary content admission; empty and >5 MiB candidates remain rejected before revision binding.Exact-current-head native evidence is terminal GREEN on both supported desktop lanes: macOS run
35486114211, job106012683805; Windows run35486114237, job106012683969. Both succeeded on exacta6d399...with the warning-gated native Project Persistence regression suite.This does not close #962. Repository
ciremains the execution authority for the TypeScript reopen bridge and must settle on the exact head before frontend GREEN is claimed. The next Project Persistence slice is buyer-visible revision-conflict handling for a differing durable workspace: Reload / Compare / Recover / Discard or equivalent, keyboard/screen-reader operable, no local-path exposure, and no automatic stale snapshot replay/rebase.PDF durable -> attachment metadata not durableremains a separate recovery-candidate boundary with #1239/#1241. Packaged process-kill, disk-full, permission, cancellation, power-loss, signing/notarization, immutable release/provenance/updater rollback also remain open.seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actions#970 owner update — rejected reopen must not revoke the still-active session's CAS authority.
Fresh review of exact
a6d399067186c74c94e7c488e0ed8ae4f9bd9fc8found thatloadProjectDocument()deliberately deleted the process-local revision receipt before restart equality binding, but a nativeProject changed since it was opened.rejection left that receipt deleted even though App rejected the Open attempt and retained the previously active project. The next mutation of that still-active aggregate therefore crossed the native boundary without its previously verifiedexpectedContentSha256and became an avoidable availability/integrity dead end.Source-level RED
afd03ea5583a6afaeabbdc5aa4a4b329a8bd5d9eestablishes a valid active receipt, forces a conflicting reopen for the same BandScope project id, then requires a subsequent mutation of the still-active project to forward the original receipt. A descendant repair was pushed before repository CI reached terminal RED, so this is not claimed as hosted RED.Causal fix
b0beeb2f230ecd446ae1caeaff91b081950e6210keeps the restart bind receipt-free, snapshots the prior session receipt, and restores it after bind rejection only when no newer receipt has appeared for that project id. This avoids both silent revocation and rolling a concurrent newer accepted revision back to older renderer authority. Traceability is code-current at8250dcf6e4adf40782086350aef50f9dc04a7e81.This does not close the buyer-visible conflict UX acceptance criterion. Reload / Compare / Recover / Discard or an equivalent bounded, keyboard/screen-reader operable contract remains the next #970/#962 vertical; automatic retry/replay/merge remains out of scope without an explicit semantic merge contract.
seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actions#970 Project Persistence owner update — exact
fdbbe93854c426cb1c18fedb2f1bdb5e11d09a9fFresh product-path review found that native CAS was storage-safe but the application treated
Project changed since it was opened.as a fatal generic error. In Workspace view that replaced the still-authoritative accepted rehearsal with ErrorState; in Score view the same conflict could be invisible.Repair lineage:
b19f59009ca55ba7cbf1b4f6ad944a4bbaab750d: source-level RED for conflicting reopen and stale mutation preserving the accepted rehearsal. No hosted RED claimed; repair landed before workflow materialization.cbf21d6c5e9c3e5ac60af2b21c456bffd3c371c4: exact owner-error classification + path-free bounded conflict state; generic failures remain generic. Only existing actions are exposed: keep/dismiss current rehearsal or choose another project.76bfba5fbe3c6c6b3aaea48c8f990bfae93e9fef: source-level RED showing the first repair hid the notice in Score view. Its CI was superseded before terminal assertion verdict.44b0dd7971a6b9d6f6da8d847c48b4a7f90d4acb: conflict notice moved above Workspace/Score switching so the accepted aggregate and warning remain visible from both rehearsal surfaces.fdbbe93854c426cb1c18fedb2f1bdb5e11d09a9f: TRACEABILITY updated with decision, trust boundary, privacy/safe-failure notes, test points, and remaining reconciliation scope.
Exact-current-head native owner evidence is GREEN: macOS run
35488483937SUCCESS; Windows Server 2025 run35488483902SUCCESS. Repositoryciis still queued andbuild-baselineis in progress; Security Scan/SBOM/Semgrep are queued and CodeQL PR pending, so no frontend/repository-wide GREEN is claimed. Fresh formal review has no qualifying independent non-author APPROVED; returned review threads are resolved. REST reportsmergeable=true,mergeable_state=blocked, so this is gate-blocked rather than a source conflict with protecteddevelop@314ddeae7b775a4957594b599358c8255617eb2e.This does not satisfy the issue's Restore / Compare / Discard acceptance. The UI intentionally does not pretend those owner operations exist. The next Project Persistence contract is explicit semantic reconciliation: inspect/reload the exact app-owned durable workspace, retain a rejected edit as a recovery candidate where warranted, and discard a side only with auditable user intent. Automatic stale-snapshot replay/merge remains prohibited. EN/KO exist because the current repository i18n runtime exposes those locales only; JA/ZH/VI/ES/DE/FR plus keyboard/screen-reader/400%/responsive packaged evidence remain open.
seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actionsProject Persistence integration finding repaired on #970: a successfully reopened app-owned project preserved its native-admitted
sourceReference.projectIdinjobResultPublicationProjectId, butScoreViewstill consumedjobResultBootstrap?.projectId. Because reopen intentionally clears the transient analysis bootstrap, Score attachment read/attach/remove could remain disabled after restart even though Project Persistence had rebound the durable project identity.Source-level RED:
8412c96bdf981aec98ccca2d7b6498f477ed3aaeaddsApp.score-project-identity.test.tsx, reopening a project with a valid path-free source reference and requiring the Score application boundary to receive its project id. No hosted RED is claimed: no workflow run materialized for that test-only head before repair.Causal fix:
0b43dad7fe4a1d78e84f16155fbca390390e611dwiresScoreView.projectIdtojobResultPublicationProjectId, the same Project Persistence identity already used by durable workspace mutation. Portable documents with no admitted source reference still get no Score Storage authority; no path/hash identity is inferred.CI ownership was repaired so the focused regression is a tracked input of both native Project Persistence workflow trigger sets and the workflow-policy contract (
3e30aaf...,670a577...,e323263...). A focused traceability contract now lives atdocs/traceability/project-persistence-score-publication-identity.md; current branch head after traceability trigger ownership repair isaee578a54f2960c2a847aebd5c6427cb502c9a05.Claim boundary: this restores admitted project identity to the Score orchestration surface after reopen. It does not close
PDF durable -> project attachment metadata not durable; that restart-reconciliation state remains a separate Project Persistence / Score Storage recovery-candidate problem and must not be solved by silent PDF adoption/deletion.seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actions#970 Project Persistence exact head is now
75e5efe1be2c4f4b818d191b2ed8d79a04a38d2b.Valid restart-recovery gap verified: after Score Storage can enumerate validated published score ids (#1241), Project Persistence still lacked a canonical way to compare that byte/object truth with durable
scoreAttachmentsreferences without scanning storage or copying Score Storage validation.Source-level RED
3484d5169b6e9b00501f4c6bf2f48e1165d6e144defined the path-free reconciliation contract. Causal implementation67febe0a049e642f5ced0c8cfb355d8b1108e25baddsderive_score_attachment_recovery_candidates, classifying (1) referenced+published, (2) published-without-reference, and (3) referenced-but-missing ids. Malformed/duplicate identities fail closed; the service performs no I/O and never infers attach/delete intent. Canonical export is95aee6d...; TRACEABILITY is85d7440...; macOS/Windows/workflow-policy ownership is51901c8...,b8f3a37...,1114d2e....Self-review caught a test-compilation defect in the initial error assertion (
Result<T, String>::as_deref()on a non-Deref success type). That was repaired ine8f8da6...and final75e5efe...usingerr().as_deref(); no hosted RED is claimed for the superseded test-only head.Claim boundary remains strict:
unreferenced_published_score_idsis a recovery candidate set, not an orphan-delete list, because the same state can mean interrupted attach or completed detach with failed byte cleanup. #970 does not consume #1241 implementation until the canonical owner path is integrated/protected. Exact-head hosted gates for75e5efe...are being materialized; predecessor GREEN is not transferred.seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actionsExact-head follow-up: #970 moved once more to
5f74aeb12a1b87f16ef9db4954d08467f73a29aaonly to make the TRACEABILITY record include the test-harness RCA. Production reconciliation semantics are unchanged from67febe0a...; theerr().as_deref()compilation repairs remaine8f8da6.../75e5efe.... Fresh exact-head macOS, Windows, CI, build-baseline, Security, SBOM, Semgrep, and CodeQL runs are now materialized and queued; no predecessor GREEN is transferred.seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actionsProject Persistence recovery disposition follow-up on #970 exact
03921928f1d0bdc5226b011dc5342d15a56978d8:- source-level RED
25a3e6c93db2464de90063910ae0de58aa8e7f05proves that public recovery classification alone must not become destructive cleanup authority; 93a2e9ce313db949eda2fa5ee4535feb3c26af78adds explicitPreserve/Discarddecisions plus opaqueAuthorizedUnreferencedScoreRecoveryAction;- authorization revalidates canonical score-id shape, uniqueness and mutual exclusion across all three recovery sets, and refuses referenced, missing-reference, unknown, malformed or forged cross-set identities;
- Project Persistence still performs no Score Storage I/O or byte deletion.
Discardis intent evidence only for later owner integration.
No hosted RED is claimed because repair commits followed before terminal workflow verdict. Exact-current-head macOS/Windows owner runs are now in progress and repository/security/SBOM/CodeQL gates are queued.
Next owner gap is not classification anymore: truthful reattach presentation metadata. #1241 inventory intentionally returns score ids only, but durable
ScoreAttachmentmetadata needs a displayfileName; a crash after PDF publication and before project metadata durability cannot currently restore the original selected filename. Add an owner-safe recovery metadata receipt or a truthful generated recovery label—do not claim the original filename was recovered.- source-level RED
seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actions#970 review follow-up: the explicit Project Persistence core allowlist had a valid fail-open drift risk. Source-level RED
4ebb60f73389589a4720453ef3a58be4434a912anow discovers the actualproject_persistence*.rs,project_format*.rs,project_migration*.rsintegration targets plus the shared content-identity contract, parses workflow--testexecution, and requires exact set equality on both macOS and Windows. A hostile future-contract fixture proves an unexecuted matching test fails policy. The same review exposed a real trigger hole:project_migration_receipt_input_binding.rswas executed butproject_migration*.rschanges did not trigger the owner lanes.757881a975fae50b12c7a04e67b6fb7fe634349cand4984b5d001a387941bd6a018d32519931e2a484cadd that trigger coverage without returning to--all-targets. Exact-head native runs are materialized; no predecessor GREEN is transferred.seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actionsProject Persistence recovery follow-up on #970 exact
95ea6f7f154ab7d57411fcc496c8834de2dc3b05:- Source-level RED
e1ff85e77c08b030bc54995b8213c47cc634a5abrequires an explicitRecoverdecision for a currentunreferenced_publishedscore and proves Preserve/Discard cannot be converted into reattachment metadata. No hosted RED is claimed because causal descendants followed before terminal verdict. 184690416054be6aba415e574f94965f3e89338caddsRecover, opaqueRecoveredScoreAttachmentMetadata, andrecovery_attachment_metadata_for_action.- Restart inventory does not contain the buyer's original selected filename. Recovery therefore uses the truthful deterministic presentation label
recovered-score-<score-id>.pdf; it does not fabricate filename provenance or expose a local path. 6a77bec1353ced292337e034435111da6a3f6289exports the contract;95ea6f7f154ab7d57411fcc496c8834de2dc3b05updates TRACEABILITY.
This remains domain authorization/presentation only: no filesystem I/O, no auto-attach/delete, and no accepted attachment until the application persists recovered metadata through Project Persistence CAS/durability. #1241 remains Score Storage owner for restart inventory/bytes. Next buyer vertical is cross-owner application orchestration plus explicit Recover / Preserve / Discard UX and missing-reference presentation.
Exact-head macOS/Windows Project Persistence owner workflows are currently running; repository/security gates and independent approval are not settled, so #970 stays Draft.
- Source-level RED
seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actionsProject Persistence recovery freshness repair on canonical #970:
- source-level RED
f22b3d235343e38f7cafe54807004e61bcffbdd7models a stale recovery dialog: Recover/Discard is authorized while a score isunreferenced_published, then fresh owner evidence shows the same score has become durably referenced before the decision is consumed; - causal fix
cf89afc80c780ecf71dc550910849aadde751992addsrevalidate_unreferenced_score_recovery_actionand makes recovered-metadata construction require fresh reconciliation; - export
707431ab52e990a10fb38753f503f9836007b668and TRACEABILITY5873c023cbcb74461abb497f071bbbdf7429f18bmake the authorization explicitly session-local intent rather than a durable capability.
Current #970 exact head is
5873c023cbcb74461abb497f071bbbdf7429f18b, Open/Draft/mergeable on protecteddevelop@314ddeae7b775a4957594b599358c8255617eb2e. Exact-head workflows have materialized but are queued; predecessor GREEN is not transferred. No qualifying independent approval exists, so merge/release gates remain closed.Claim boundary: this prevents an older Recover/Discard decision from crossing a later Project Persistence/Score Storage lifecycle change. It does not yet implement the product recovery flow because #1241 restart inventory is not protected/released into this owner branch. After owner integration, the application must refresh both owner evidences immediately before Recover metadata commit or Score Storage Discard, and must surface missing references without silent metadata rewrite.
- source-level RED
seonghobae commented
on Sep 20, 2026 CollaboratorAuthorMore actionsProject Persistence recovery finding / repair update (exact source lineage):
A recovery decision was fresh with respect to score lifecycle state but was not bound to the active project aggregate. Project A and Project B can both classify the same opaque score id as
unreferenced_published; if a recovery dialog survives a project switch, a decision authorized under A could otherwise pass score-set revalidation under B.- Source-level RED:
3aaf84d9dd34b3f7f7c12f17cd4a9ffa97b8dca9adds a project-switch regression with identical recovery candidate sets and rejects malformed project identity. No hosted RED is claimed because causal descendants followed before terminal workflow evidence. - Causal repair:
f0fc96b67d18c9a2c168f1864a091edf835ea3e2adds opaqueProjectScopedScoreRecoveryAction, canonical project-id validation, and mutation-boundary project identity + fresh lifecycle revalidation. - Public boundary hardening:
85c48a02ed8d09b11df1dd2bebf5eae60b38570fremoves unscoped recovery mutation authority from the desktop-core crate-root API and exposes only the project-scoped wrapper. - CI ownership / traceability:
d87e6fe9570d71d187ac9652b49de896e0d6886d,f63668fcdc271c67cd1dfd4ac166b3a2859b7377,dfc8bc82403c6cf619b7248968cbaa02284dabb4,c0b0b284f84e9b191aa7e5d7d2ba2e2a2d403de4,b909ac80934031bbf7366bc909984735d7792866,a30749871792b1a5ec569441f8c4f5766c24bd3e,17ee600cec13fec9475e988402efbb7e1370bbd6make the new source and project-scope TRACEABILITY exact-head inputs of both macOS and Windows owner lanes.
Current #970 exact head is
17ee600cec13fec9475e988402efbb7e1370bbd6; fresh owner workflows have materialized but are not yet terminal, so predecessor GREEN is not transferred. The repair is domain-level only: application recovery still awaits protected/released Score Storage inventory integration (#1241), explicit Recover/Preserve/Discard UX, re-read of both owner evidence plus active project identity at action time, Project Persistence CAS for Recover, and Score Storage-only byte cleanup for Discard.- Source-level RED:
seonghobae commented
on Sep 22, 2026 CollaboratorAuthorMore actions현재 canonical Project Persistence implementation owner는 Draft PR #970입니다. Issue 본문의 “no live PR is designated” 문구는 역사적 baseline으로만 해석해야 합니다.
Fresh owner authority:
- protected base:
develop@314ddeae7b775a4957594b599358c8255617eb2e - fix(project): enforce crash-safe revision-bound persistence #970 exact head:
2892a43615fc29b119fefb3851d34aa511020965 - state: Open / Draft / mergeable
직전 exact
0f147709ccdce2aa367ebd2fbee1fd2dd0f737af의 repositorycirun35671231614는 queued가 아니라 terminal FAILURE였습니다. Ubuntubuild-and-testjob106598332027의 유일한 terminal defect는services/analysis-engine/src/bandscope_analysis/api.py의 Ruff 0.15.5I001import-order failure였습니다. Native Windows/macOS, build-baseline, Semgrep, Security Scan, SBOM predecessor success는 이 새 head로 전용하지 않습니다.Repair lineage:
82bbfe5aec6d480d5ac1ecc9c842fb6dc2c235ed: private aliased cache-publication import block을 같은 module의 non-aliased block보다 앞에 배치.- immediate diff inspection에서 섞인 unrelated
HarmonyPayloaddocstring delta를 발견했고, ordinary descendant2892a43615fc29b119fefb3851d34aa511020965에서 제거. 0f147709...→2892a436...최종 delta는api.py한 파일의 import block reorder만 남습니다 (+3/-3). Persistence/cache runtime semantics, resource bound, warning/test/workflow gate는 변경하지 않았습니다.
현재 exact-head generation은 live/nonterminal입니다: Windows native
35704190409in_progress, macOS native35704190460queued, build-baseline35704190549pending, ci35704190510queued, Security35704190381queued, Semgrep35704190442queued, SBOM35704190467queued, CodeQL35704190383pending. Qualifying independent non-author current-headAPPROVED도 아직 없습니다. 따라서 #962/#970은 계속 Open/Draft이며 protected integration, recovery UX/fault evidence와 release gates가 남아 있습니다.- protected base:
seonghobae commented
on Sep 22, 2026 CollaboratorAuthorMore actionsCurrent Project Persistence owner update:
- canonical source PR remains fix(project): enforce crash-safe revision-bound persistence #970, exact source head
2892a43615fc29b119fefb3851d34aa511020965; - protected product truth remains
develop@314ddeae7b775a4957594b599358c8255617eb2e; - fix(project): enforce crash-safe revision-bound persistence #970 is now intentionally stacked on canonical formatter prerequisite repair(ci): format consolidated supply-chain policy test #1176 (
bolt-performance-chart-export-13223013812255847379@8fe6b6d99c009527ef0bcba419e6f6debdb23c23) rather than copying protected-base formatting debt into Project Persistence.
Fresh hosted RCA supersedes the earlier runnerless-CI description. Repository
cirun35704190510is terminal FAILURE at Ubuntubuild-and-testjob106717643693: Ruff 0.15.5format --checknames five files. Four are #970-owned Project Persistence files (final_result_cache.py,test_analysis_cache_admission_identity.py,test_final_result_cache_shared_contract.py,test_project_persistence_workflow_policy.py) and remain #970 repair work. The fifth,test_supply_chain_policy.py, is not a #970 delta and is already owned by one-file prerequisite #1176.The unchanged #970 source head still has Windows/macOS native persistence, build-baseline, Security Scan, Semgrep and SBOM success from its direct-
developgeneration. Those receipts are lineage after the base retarget, not final stacked merge evidence. No qualifying independent current-head approval exists; CodeQL is unsettled. Keep #962 and #970 open/Draft until #1176 normally reaches protected ancestry, #970 reconciles ordinary/non-force, its four owned formatter findings are repaired, and fresh exact-head/base gates plus buyer recovery evidence are obtained.No force-push, destructive rebase, duplicate formatter fix, no-op wake commit, blind rerun, self-approval or gate weakening was used.
- canonical source PR remains fix(project): enforce crash-safe revision-bound persistence #970, exact source head
seonghobae commented
on Sep 22, 2026 CollaboratorAuthorMore actionsProject Persistence owner update: canonical PR #970 is now exact
25b6095f12d461ef9e3a7e647fa2a31a27e6fc1c, stacked on #11768fe6b6d99c009527ef0bcba419e6f6debdb23c23with actual ordinary two-parent ancestry, not base-label retargeting only. The branch was fast-forwarded (force=false), and fresh compare from #1176 is ahead=815 / behind=0 with merge base exactly #1176.The hosted direct-
developCI RCA is now exact from job106717643693: Ruff 0.15.5 would reformat five files.test_supply_chain_policy.pyis the foreign protected-base defect canonically owned by #1176 and is now consumed through ancestry. Four files remain Project Persistence-owned and unresolved:final_result_cache.py,test_analysis_cache_admission_identity.py,test_final_result_cache_shared_contract.py, andtest_project_persistence_workflow_policy.py. Do not treat the ancestry repair as fixing those four.Current stacked head has no repository-owned workflow generation; that is absence of evidence, not GREEN. Required order remains: #1176 protected integration → ordinary #970 reconciliation → four owner Ruff repairs → fresh exact-head/base repository/native/security/SBOM/CodeQL/review evidence. #962 acceptance remains open.
seonghobae commented
on Sep 22, 2026 CollaboratorAuthorMore actionsProject Persistence authority update:
Canonical implementation remains PR #970. Its dependency topology is now actual ancestry rather than metadata-only retargeting:
- repair(ci): format consolidated supply-chain policy test #1176 formatter prerequisite
8fe6b6d99c009527ef0bcba419e6f6debdb23c23; - fix(shared): enforce valid transcription timing intervals #1254 shared TranscriptionNote timing prerequisite
c21c18ccd630614feee1fef3e0b7e5cf4fdce658, itself descended from repair(ci): format consolidated supply-chain policy test #1176; - fix(project): enforce crash-safe revision-bound persistence #970 exact current head
3dfd77e11187211e9b7ed2317b8f559e5e1fb018, basefix/shared-transcription-timing-1253, Open / Draft / mergeable.
A real persisted-cache contract drift was found while reconciling the stack. #1254 rejects finite but impossible audio-relative note intervals (
onset < 0,offset <= onset), while #970's Python final-result cache validator still accepted any finite onset/offset pair. #970 now carries source RED3314730077b7c24c077e2f15cec73eb627b8d75efor negative, zero-duration and inverted intervals, followed by minimal consumer repair3dfd77e11187211e9b7ed2317b8f559e5e1fb018adding onlyonset >= 0andoffset > onset. Shared timing policy remains #1254-owned; no duplicate consumer policy branch was created.Evidence boundary remains fail-closed: current stacked #970 exact head has zero repository-owned check runs, so there is no final exact-head GREEN to claim. Four #970-owned Ruff-format findings from the last direct-
developCI are still unresolved/unproven. The previous semantic head's native Windows/macOS, build, Security, Semgrep and SBOM successes remain predecessor semantic evidence only.The previous #970 CodeQL run
35704190383is now known to be terminal, not merely pending: language detection succeeded, three compatibility jobs failed at verdict enforcement, and the current-head CodeQL scan dispatch only materialized afterward. That same-generation publication/re-entry evidence has been routed to canonical central owner ContextualWisdomLab/.github#1929 rather than treated as a Project Persistence source-security finding.Issue #962 stays Open. Crash/power-loss/disk-full/permission fault acceptance, recovery UI/a11y, protected prerequisite integration, final exact-head gates/review, signing/notarization and release/rollback evidence are still incomplete.
- repair(ci): format consolidated supply-chain policy test #1176 formatter prerequisite
Parent: #958
Baseline: #968
Buyer-visible gap
A rehearsal project is durable user work: local audio references, role selections, analysis results, user-corrected boundaries, cue decisions, handoff metadata, and future player state. The current 83-PR inventory contains handoff and many UI/security slices, but no live PR is designated as the canonical owner of a versioned crash-safe project format, autosave, atomic publication, migration, backup, and recovery.
A commercial desktop product must prove that a crash, power loss, interrupted write, application upgrade, or rollback does not silently destroy or reinterpret a band's work.
Product outcome
BandScope owns one documented, versioned, and recoverable local project format:
Required scope
Canonical project contract
project_format_versionindependent of the application package version.Atomic persistence
Autosave and recovery
Migration and rollback
Boundary with current handoff work
Live PRs #737 and #740 own versioned outbound/inbound rehearsal handoff slices. They are portable, bounded interchange contracts—not substitutes for the durable local project source of truth.
The project contract must integrate the active rehearsal-player state from #961 only after that public state machine is stable.
Acceptance criteria
Real-world fault cases
Non-goals