Repository navigation
feat(share): attach verified source snapshots from CLI - #7137
Conversation
7d4a332 to
a955b0a
Compare
b15a9d6 to
05b822b
Compare
a955b0a to
d84b0bc
Compare
05b822b to
e21f751
Compare
d84b0bc to
9aacd2a
Compare
e21f751 to
109c0a0
Compare
9aacd2a to
15a19b9
Compare
109c0a0 to
e295ce2
Compare
15a19b9 to
545cc86
Compare
e295ce2 to
3694130
Compare
545cc86 to
23158dd
Compare
3694130 to
111fa26
Compare
5461341 to
2f79994
Compare
6ec6d5a to
95e550d
Compare
jrusso1020
left a comment
There was a problem hiding this comment.
Reviewed at ebc5bea70c31119b60b0ea7199bc650cbb675abb (base #7135 at abd4c1a5698554ac0ac885f1218f08ad87ab6ba9).
In the inspected transfer path, the client hashes the actual streamed bytes, rejects untrusted origins/redirects, and preserves upload identity across retries. Source failures require an explicit video-only retry.
Important — render/source verification omits render inputs under hidden directories. packages/cli/src/share/render.ts:7-8,61 uses projectFingerprint(..., {byContent:true}) as its additional content check. That still calls snapshotProject, whose isOutsideFilm skips every dot-directory, including .media and the portable .hyperframes render settings/media which captureProject includes. The callback in packages/cli/src/share/sources.ts:36-39 consequently accepts a changed source snapshot against the old video.
Repro: render HTML referencing .media/voice.mp3, edit that audio, then share/update. Both saved-render fingerprints remain equal, so prepareShareRender reuses the old MP4; source capture contains the new audio. An independent adapter probe using the CLI's exact fingerprint callback returns ready and an attachable snapshot containing the edited audio. This needs no preserved timestamps. I independently reproduced sameContentFingerprint:true, manifestChanged:true with the actual snapshot/capture functions. The same inventory exclusion covers portable Studio edit metadata and prepared podcast media; those additional cases were identified by code inspection.
Fix: use a share-specific content inventory that covers the portable render inputs (including .media and the explicitly portable .hyperframes paths), record its digest around rendering, and compare it during source preparation and final attachment. Keep generated renders, locks, and retry records excluded. Avoid changing Desktop watcher's existing inventory globally. Add regressions showing that changing referenced .media audio and portable Studio edit metadata invalidates the cached render and prevents attachment to that old render.
Audited: CLI share/render/source/error integration; shareSources; capture, policy, manifest, limits, binding store, API/wire parsing, transfer/upload and review-export integration; source docs and tests. Trusting: generated Unicode table/vector contents (read metadata and exercised bundled vectors, no independent upstream regeneration); no actual video render, signed-in backend upload or recipient Get/Edit acceptance.
Validation: node --test packages/share/tests/*.test.mjs: 82 passed; vitest run src/share/service.test.ts src/share/sources.test.ts: 24 passed. Adapter repro: node adversary-media-probe.mjs yields prepare: "ready", a non-null filesForExport, and uploaded "changed audio" after the recorded render fingerprint was taken. A control using the portable capture digest refuses preparation (unavailable, null attachment, zero uploaded bytes). The existing tests do not catch the inventory mismatch above. Known credential filenames and dependency directories are excluded; capture uses the documented filename policy, not secret scanning or Git ignore rules. Older review-space responses without share_files:true select video-only without source preparation; unexpected source errors remain explicit failures.
Need: yes · Size: ok, mostly pinned contract data and focused source modules · Reuse: existing sharing kernel, signed-in transport and upload-origin policy · Simpler: retain the existing adapter boundary; correct its render inventory · Structure: fine
Risk: medium — source/video integrity crosses rendering, local capture and remote snapshot publication.
— hf-review
Verdict: REQUEST CHANGES
Reasoning: The CLI prepares an attachable source snapshot after media has changed from the cached render. Align the render content inventory and cover the hidden render-input cases before approval.
|
Addressed @jrusso1020 in f2b5f41. The CLI now records the portable source manifest digest before and after rendering and rechecks it during source preparation and final attachment. This includes Also fixed an independently reproduced retry dead-end: a confirmed unusable pending upload is cancelled and cleared so unchanged files can retry with a new key. Verification and conflict outcomes remain preserved, including cancellation races. Validation: full workspace build, sharing declarations, CLI typecheck, 87 sharing tests, 29 focused CLI tests, lint/format/comment checks, and repository pre-commit checks including Fallow passed. Hosted CI and re-review are pending. Signed-in source delivery and recipient Get/Edit remain unverified. Please re-review this head; #7135 remains draft and nothing has been merged. |
jrusso1020
left a comment
There was a problem hiding this comment.
Reviewed at f2b5f413321bfbf6ba142df43aeca8f14d2478ac (base #7135 at abd4c1a5698554ac0ac885f1218f08ad87ab6ba9, present in this head).
The prior render/source inventory blocker is resolved. shareSourceFingerprint uses the portable capture manifest digest, and CLI render caching records/checks that digest before and after rendering. The existing preparation/final-attachment callback now checks the same inventory. .media and portable .hyperframes inputs therefore participate without changing Desktop's watcher semantics.
The added unusable-upload recovery cancels and clears a confirmed terminal pending operation, while retaining verifying/conflict state when cancellation races another transition. Other errors still fail explicitly rather than silently dropping source.
Audited: the complete seven-file delta since ebc5bea70c31119b60b0ea7199bc650cbb675abb, full touched production files and their render/preparation/attachment/recovery callers. The prior review covers unchanged transport, exclusions, limits and credential boundaries. Generated Unicode/vector data is unchanged and was not independently regenerated. No actual video render, signed-in backend delivery or recipient Get/Edit acceptance was exercised.
Validation at this head: node --test packages/share/tests/*.test.mjs: 87 passed; CLI vitest run src/share/render.test.ts src/share/sources.test.ts src/share/service.test.ts: 29 passed (render execution mocked). The original adapter probe now returns unavailable, null attachment and zero uploaded bytes. Replacing only the new digest helper with the old inventory makes both hidden-input adapter regressions fail (2 failed); source restored afterward. Fresh adversarial code pass found no additional blocker.
Need: yes · Size: ok · Reuse: portable capture manifest and existing upload recovery · Simpler: already minimal · Structure: fine
Risk: medium — render/source integrity and persisted upload recovery cross local and remote boundaries.
— hf-review
Verdict: APPROVE
Reasoning: The original hidden-input mismatch is closed across cache reuse and attachment, and the recovery delta preserves unresolved server outcomes. No new blocking issue found in the reviewed delta.
|
Test-only follow-up pushed at All CLI Explicitly dispatched full CI and CodeQL on this head. Exact-head re-review requested while those run. Nothing merged; #7135 remains draft. |
jrusso1020
left a comment
There was a problem hiding this comment.
Reviewed at 8a3a0cc3a1d7e3207f734ea66016e98c92fee419.
The sole delta from approved parent f2b5f413321bfbf6ba142df43aeca8f14d2478ac adds the missing shareSourceFingerprint export to the lifecycle test's @hyperframes/share mock. Read the complete test: its embedded-render and failed-render cleanup assertions remain intact. The mock's stable content digest matches the unchanged-project scenario; no production files or prior integrity/recovery fixes changed.
Validation: verified the commit's parent and complete file/patch list, then read the full test. No local test rerun on this test-only head; the prior 87 sharing/29 CLI results belong to the parent, not a fresh run here.
Need: yes · Size: ok · Reuse: existing lifecycle test mock · Simpler: already minimal · Structure: fine
Risk: low — mock-only repair with production code unchanged.
— hf-review
Verdict: APPROVE
Reasoning: The missing mock export is supplied without weakening assertions or changing production behavior. Re-pinning the reviewed sharing implementation to this test-only head.
…7135) * feat(cli): share rendered videos through unified reviews (heygen-com#7135) * feat(share): attach editable project sources to reviews (heygen-com#7137) * feat(share): measure local sharing outcomes (heygen-com#7138) * feat(cli): stage the sixty-day publish transition (heygen-com#7136) * feat(studio): share review pages from local preview (heygen-com#7140) Advertise the CLI sharing bridge before bootstrapping it so standalone Studio does not request unsupported routes. Preserve origin and session checks. Budget the intended sharing artifact: clean main packs at 8,060,519 bytes versus 8,162,979 with sharing (8,169,168 in CI). Required policy and Unicode tables, bundled sharing code, and Studio controls account for the growth. Set the packed-only budget to 8,577,627, following the 5% headroom convention; retain the unpacked cap and all package checks. * fix(share): persist refusals and improve CLI retry feedback * fix(ci): restore render diagnostics and include sharing workspace * fix(cli): keep sharing owner error codes stable * fix(share): clarify update feedback and align audience changes * fix(share): clarify updates and avoid scratch-file rerenders * fix(cli): report active shares and preserve update channels * fix(cli): resolve update channel when checking registry * fix(ci): refresh sharing package budgets after rebase * fix(share): require consent before uploading project files
Allow
hyperframes shareto attach editable project files for the rendered version when the workspace supports it. Verify that the snapshot matches the video, resume interrupted multipart uploads, and require an explicit--video-onlyretry when a requested source upload fails. Workspaces without source eligibility can still share a video.Targets #7135 for integration; this is not a standalone release. Capture uses a fixed portable-file policy, not Git ignore rules or secret scanning. The source guide explains what is included and how to opt out. Uploads require trusted storage origins and reject redirects; stalled transfers stop after 60 seconds without progress and retain retry state.
Most added lines are the pinned Unicode data and manifest test vectors. The Unicode license and upstream input hashes are included. Automated sharing tests require no account or service credentials.
Validation at
f2b5f4133:.media/Studio input cache and attachment regressions, unusable-upload retry recovery, and verification/conflict cancellation races.Still unverified: signed-in source delivery and recipient Get/Edit acceptance. Local Mintlify validation could not finish because its tooling installation exhausted available disk space; the temporary installation was removed. No UI changes in this PR.