fix(score): publish attachments through private bounded storage - #1241
seonghobae wants to merge 169 commits into
Conversation
Integrate protected develop@749511c3ad4000090048718f685c6bee6b3d2c25 into the canonical #864 owner branch without rewriting history. Preserve the shipped npm/PDF security baseline and first-playable-range changelog truth while retaining the bounded native score-PDF read implementation and regressions.
Re-emit the unchanged #864 tree so cancelled/never-materialized current-head workflow evidence is replaced by fresh exact-head runs. No production, test, dependency, workflow, or documentation content changes.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
seonghobae
left a comment
There was a problem hiding this comment.
Exact-head owner-currentness review for d8f38b86da9db7f96a41135cdab4e3912bb02b8f: this branch has moved beyond the PR body's declared 1d0bb7176d3461743d9fe3dea2e9bc94021610a9, so the body's owner-native GREEN and exact-head gate narrative are predecessor evidence only.
The new exact adds the valid receipt-bound detach/delete contract in score_pdf_attachment_wiring.rs: the UI must obtain the current Score Storage receipt before mutating project metadata and may delete bytes only with remove_score_pdf_if_receipt_matches. Current ScoreView.tsx still calls id-only removeScorePdf(activeProjectId, attachment.id) after metadata update, so this exact should be treated as an intentional product RED until the application boundary is causally repaired.
RED/GREEN acceptance for the canonical owner:
- capture the exact current
{score_id, content_sha256}receipt immediately before the destructive flow, not from stale UI state; - re-read active project identity and Project Persistence recovery/CAS authority immediately before mutation;
- commit the project-metadata detach only through the Project Persistence owner contract, then invoke Score Storage deletion with the captured receipt; an ABA republish with the same score id but different content must be preserved/fail closed rather than deleted;
- if metadata update fails, score bytes remain; if receipt-bound byte deletion fails after metadata acceptance, surface durable recovery state rather than synthesizing success or trying id-only cleanup;
- exercise project switch/stale intent, same-id republish, concurrent detach, process restart, and deletion failure through real application orchestration; no cross-owner filesystem or project-document source copy;
- after production GREEN, reacquire macOS/Windows owner-native and repository-wide CI/security/SBOM/CodeQL evidence on the unchanged new head. The
1d0bb717...GREEN cannot transfer.
Please currentize the PR body/TRACEABILITY on the next substantive owner mutation so the live head_sha and acceptance matrix no longer advertise predecessor authority. Keep Draft; this new RED is useful progress, but it is not merge/release authority.
Owner / scope
Canonical Score Storage / Score Attachment implementation for #1239. This PR owns write-time PDF confidentiality, bounded publication, storage-object identity, interrupted-publication recovery, restart inventory/content receipts, retention/removal authority, successful-return storage durability, and the narrow Score UI boundary that coordinates project-metadata acceptance with score-byte publication/deletion.
It does not absorb #865 read-time allocation/content validation, #970 Project Persistence durable-project/workspace/revision-CAS authority, or Resource Admission/MIR. Node/npm runtime acquisition remains canonical #896 authority; this lane consumes that contract only after it reaches protected truth.
Protected base:
develop@314ddeae7b775a4957594b599358c8255617eb2eFoundation: #865 exact
1f4877413e2eed30b224eaf1b095af3b0b905cb0Exact current head:
b29b7b522478780db44db1c754ab7f660ed2b17bState: Open / Draft / mergeable. Exact-head focused UI/repository/security evidence and qualifying independent non-author approval remain gates; predecessor verdicts never transfer automatically.
Fresh protected-base compare is ordinary-forward (
ahead=169,behind=0, merge base exactly protecteddevelop).Current product finding — same-song stale aggregate after async work
The existing
(projectId, song.id)freshness guard correctly rejects continuations after project/song navigation, and the live-selection guard clears a score opened while detach waits. A narrower same-context defect remained:handleAttachandhandleRemovecaptured render-timesong/scoreAttachmentsbefore awaiting native publication or receipt lookup. If the same project/song rerendered with newer metadata while that wait was pending, the continuation could submit the stale aggregate toonSongUpdate, overwriting newer visible title/attachment state.8dd038be0f115377cda7071e2d49a909effb3013is the focused source RED. It adds two regressions: pending attach must preserve a newer same-song title and concurrent attachment when native publication resolves; pending detach must remove only the target from the newer same-song snapshot after receipt lookup. The predecessor implementation uses the old render closure and violates both contracts. Repair followed before a terminal hosted verdict for this test-only head, so no hosted RED is claimed.8529ec09254ae5c6c27d92454a1ae8a02629c27bis the minimal causal fix. ScoreView keeps the latest renderedRehearsalSongin a ref and, only after(projectId, song.id)revalidation, constructs attach/detach metadata proposals from that latest snapshot and its current attachment list. Score Storage filesystem/deletion authority is unchanged.b29b7b522478780db44db1c754ab7f660ed2b17bcurrentizesdocs/traceability/score-attachment-project-context.mdwith the new invariant and its explicit limit: this prevents knowingly submitting stale rendered same-song state after ScoreView's own async wait; durable concurrent-writer arbitration/revision CAS remains #970 Project Persistence authority.Existing project-context / storage contracts retained
(projectId, song.id);useLayoutEffectbefore repaint;{score_id, content_sha256}before metadata mutation and performs only receipt-bound deletion after accepted metadata detachment; no id-only destructive fallback exists;ENOSPC, metadata barriers where supported, deterministic public-publisher process termination and owner-only desktop-package fault harness; release builds reject fault-injection leakage.This still does not prove ordinary bundled/notarized/signed
bandscope-desktopcancellation, sudden power loss, Windows directory-entry power-loss durability, old-unleased-build coexistence, or disposition of the final Unix basename race.Exact-head evidence — UI runtime failure now classified
Current exact owner generation is
score-storage-nativerun35543493216forb29b7b52....106165239883: SUCCESS on the exact current head, including owner unit/regression suites, release fault-feature exclusion, public-publisher process termination and desktop-package executable termination.106165239907: SUCCESS on the exact current head with the same owner-native/release-fault-exclusion contract.106165239933: FAILURE. It finally received a runner and failed at step 4,Install locked JavaScript dependencies; the focused ScoreView/scoreStorage regression step was skipped. Therefore the new latest-rendered same-song regressions still do not have hosted GREEN.The failing workflow exact source sets up Node
22.22.3and immediately runs rawnpm ci. The same tree pinspackageManager: npm@10.9.9anddevEngines.packageManager.version: 10.9.9withonFail: error. Node's official v22.22.3 archive identifies its bundled npm as10.9.8. The observable configuration is therefore inconsistent with the repository's exact npm-runtime contract. The available GitHub job API does not expose the stderr text from the failednpm cistep here, so the exact emitted npm diagnostic is not asserted.Canonical #896 already owns the pinned npm acquisition/verification boundary (
activate_pinned_npm_runtime.sh) and explicitly forbids fallback to bundled npm. That helper is still Draft/unreleased and is absent from protecteddevelop, so this PR will not copy or vendor a mutable owner implementation merely to make the UI lane pass. Downstream evidence has been routed to #896. Required consumer order is: #896 protected integration → ordinary/non-force reconciliation of this lane → replace raw npm dependency admission with the protected canonical activation path → fresh exact-head UI run. No blind rerun or no-op wake commit is justified before that owner dependency is available.Exact-current-head build-baseline,
ci, Security Scan, SAST Semgrep, SBOM and CodeQL PR settlement plus qualifying independent non-author approval remain required. Formal review inventory still lacks a qualifying current-headAPPROVED.Cross-owner boundary
#970 remains owner of durable active-project identity, Project Persistence revision/CAS/durability, restart reconciliation and buyer lifecycle authorization. #1241 does not mutate project documents directly and does not claim durable conflict freedom merely because it now uses the latest rendered same-song snapshot. #970 must not copy Score Storage filesystem/receipt/UI source.
After #1176 → #865 and this owner become protected/released truth, #970 must ordinary/non-force reconcile, consume the released receipt contract, consolidate shared
content_sha256rather than retain duplicate source, and implement Recover / Preserve / Discard using fresh Project Persistence classification plus fresh Score Storage receipt immediately before mutation.Merge / release gate
Keep Draft. Foundation/runtime prerequisites must reach protected truth first, then this lane ordinary/non-force reconciles and reacquires exact-head evidence. No blind rerun, source-neutral wake commit, force-push, destructive rebase, self-approval, gate weakening, Ready transition, merge, tag or release while authorities are unsettled.
Remaining buyer/release work includes successful exact-head focused UI execution after canonical npm-runtime consumption; repository/security settlement; released #970 consumption and durable revision/CAS; Recover / Preserve / Discard and
missing_referenced_score_idsUX; project deletion/recovery rollback; old-build coexistence and Unix final-basename disposition; keyboard/touch, Narrator/VoiceOver, 400% zoom, responsive and KO/EN/JA/ZH/VI/ES/DE/FR packaged acceptance; shipped cancellation/power-loss/Windows durability; signing/notarization, SBOM/provenance/reproducibility, immutable release and updater rollback.UI Delivery Gate: FAIL — source covers project-switch, pre-paint, live-selection and latest-rendered same-song freshness, but the exact-current-head UI job failed in dependency admission before focused regressions ran; material recovery/a11y/localization acceptance also remains incomplete.
Commercial Release Gate: FAIL — exact native macOS/Windows owner lanes are GREEN, but UI runtime integration, repository/security evidence, dependency integration and independent review remain incomplete; release/signing/power-loss acceptance remains open.