Commit Graph
3208 Commits
Author SHA1 Message Date
James cfe8467b58 chore: release v0.7.76 2026-07-27 05:08:40 +00:00
James RussoandGitHub 4508998466 Merge pull request #2823 from heygen-com/fix/plan-v2-sparse-inactive-videos
fix(producer): materialize sparse video directories
2026-07-26 21:59:48 -07:00
Xuanru LiandGitHub 6c7a9b054e fix(check): elongated pivot drift + counterfactual connector_detached (#2819) 2026-07-26 21:43:42 -07:00
James 503e45ad46 fix(producer): materialize sparse video directories 2026-07-27 04:22:26 +00:00
James 4548c34f64 chore: release v0.7.75 2026-07-27 03:38:16 +00:00
James RussoandGitHub 9e8c1d12a8 Merge pull request #2821 from heygen-com/fix/distributed-beginframe-fallback
fix(producer): fallback distributed capture safely
2026-07-26 20:32:10 -07:00
James bcbe7f1104 fix(producer): fallback distributed capture safely 2026-07-27 03:08:40 +00:00
James RussoandGitHub 41f4b9628a Merge pull request #2820 from heygen-com/fix/plan-v2-fixture-shard-schedule
fix(regression): schedule Plan v2 color fixture
2026-07-26 20:04:32 -07:00
James 008f87f704 fix(regression): schedule plan v2 color fixture 2026-07-27 02:31:46 +00:00
James RussoandGitHub 7d9dea369e ci(regression): compute the shard matrix from recorded fixture timings (#2815)
* ci(regression): compute the shard matrix from recorded fixture timings

* ci(regression): refresh shard timings from a green post-PSNR run

* fix(ci): close two silent-skip holes in the shard schedule contract

* ci(regression): schedule the new static-volume-future-set fixture

* test(producer): regenerate static-volume-future-set golden in the pinned container
2026-07-26 19:16:39 -07:00
James RussoandGitHub d9c8651082 chore: release v0.7.74 (#2818) 2026-07-26 21:57:54 -04:00
James RussoandGitHub a24b078df9 fix(producer): accept partial color metadata in plan v2 (#2814)
* fix(producer): accept partial color metadata in plan v2

* test(engine): make partial color probe hermetic

* fix(producer): validate plan v2 sentinels in fallback mode
2026-07-26 21:48:51 -04:00
James RussoandGitHub 3bb78e9857 perf(producer): compute regression PSNR in one ffmpeg pass (#2813)
* perf(producer): compute regression PSNR in one ffmpeg pass

* fix(producer): fail loudly when one PSNR input runs out of frames
2026-07-26 18:14:53 -07:00
James RussoandGitHub ce2d19a9dc Merge pull request #2817 from heygen-com/fix/2810-gcp-beginframe-contract
fix(gcp): enforce effective BeginFrame capture
2026-07-26 18:11:53 -07:00
James RussoandGitHub 7a6df32300 Merge pull request #2816 from heygen-com/fix/2809-static-volume-live-seek
fix(core): avoid live volume probe during render
2026-07-26 18:11:12 -07:00
James 05549e631b fix(gcp): enforce effective BeginFrame capture 2026-07-27 00:02:37 +00:00
James f7d579f21b fix(core): avoid live volume probe during render 2026-07-26 22:39:58 +00:00
James RussoandGitHub 44ea1fb5be Merge pull request #2812 from heygen-com/release/v0.7.73
chore: release v0.7.73
2026-07-26 17:36:13 -04:00
James 1164b321ad chore: release v0.7.73 2026-07-26 21:25:03 +00:00
James RussoandGitHub 17b1b2cf4f fix(producer): align frame coverage with extraction rounding (#2770)
## What

- model expected video-frame counts using the same rounding contract as the extraction branch:
  - CFR `-vf fps=<fps>`: nearest output-frame boundary
  - VFR `-fps_mode cfr -r <fps>`: ceil
- retain fail-closed ceil behavior when extraction metadata is missing
- keep positive sub-frame clips at a minimum of one expected frame
- preserve the existing 95% truncation gate and source-duration credit

## Why

The coverage gate universally used `ceil(duration * fps)`, but FFmpeg's CFR fps filter rounds to the nearest boundary. This made successfully extracted short CFR clips such as 0.616666s at 30 fps look truncated (18 captured vs 19 expected).

In the dashboard window, 124 of 335 video-coverage failures were exactly one frame short. Historical logs do not include `isVFR`, so that is the maximum addressable cohort rather than a guaranteed reduction. Zero-frame and materially truncated extraction failures remain fail-closed.

## Safety

- VFR still uses ceil and the existing strict coverage threshold.
- Missing extraction metadata still uses ceil.
- No retry, fallback, Temporal workflow, or render-plan behavior changes.
- Intended rollout is through the producer sidecar canary with explicit internal in-process jobs before dev and production promotion.

## Test

- `bunx vitest run packages/producer/src/services/render/videoFrameCoverage.test.ts` (28 passed)
- `bun run --filter @hyperframes/producer typecheck`
- `bunx oxlint ...videoFrameCoverage.ts ...videoFrameCoverage.test.ts`
- `bunx oxfmt --check ...videoFrameCoverage.ts ...videoFrameCoverage.test.ts`
- `bunx fallow audit --base origin/main --fail-on-issues`
- repository pre-commit gates
2026-07-26 17:20:25 -04:00
James 881aacc920 fix(producer): align frame coverage with extraction rounding 2026-07-26 20:33:19 +00:00
James RussoandGitHub 94718a25d9 fix(producer): type video extraction failures (#2776)
## Summary
- classify per-source video download/probe/decode/extraction failures with a bounded taxonomy and safe producer-facing summaries
- add candidate-only, at-most-one transient retry with cleanup and retry telemetry
- preserve default engine/producer behavior when the policy is off
- carry allowlisted extraction error codes through blocking JSON and SSE responses

## Stack
Depends on #2774 for atomic remote downloads and its single owned download retry. This PR is intentionally based on `fix/atomic-video-download-retry`; rebase/change the base to `main` after #2774 merges.

## Default compatibility
`HF_VIDEO_EXTRACTION_FAILURE_MODE` defaults to `off` and forces `maxTransientRetries=0`.

With the feature off:
- metadata probe failures keep the legacy Promise rejection
- grouped extraction keeps the existing grouped-to-direct fallback
- no new producer failure gate is enforced
- render-plan schema, Plan v1 artifacts, chunk routing, and distributed execution are unchanged

Typed metadata aggregation is explicit and enabled only by the candidate enforce lane.

## Retry ownership
- remote downloads: exactly one retry owned by #2774
- metadata/FFmpeg extraction: at most one retry only when `HF_VIDEO_EXTRACTION_MAX_RETRIES=1`
- invalid, missing, rejected, out-of-range, zero-output, cancellation, and unknown/internal failures do not retry
- non-finite or invalid runtime retry budgets fail closed to zero
- the superset optimization is never retried; on failure it preserves direct-member fallback, and only the individual ranges can use the bounded retry
- retry counters increment when a retry is scheduled, including exhausted retries

The internal sidecar and Experiment Framework must treat both exhausted stage codes as workflow-terminal after the producer-local budget. Candidate enforcement must not be enabled until those companion mappings are deployed, or Temporal can multiply producer attempts.

## Failure contract
- `VIDEO_SOURCE_UNRENDERABLE`: at least one deterministic/unknown source failure
- `VIDEO_EXTRACTION_FAILED`: all source failures are transient but the producer-local budget is exhausted

Only the allowlisted code and kind/count summaries cross JSON/SSE. Raw diagnostics remain engine-local because they may contain signed URLs or local paths.

## Rollout
1. merge and deploy with stable/candidate both `off`
2. candidate `observe`, retries 0
3. candidate `observe`, retries 1
4. deploy internal + EF terminal transport mappings
5. candidate `enforce`, retries 1
6. keep stable off until success delta, retry counts, extraction latency, CPU/disk, and queue backlog are acceptable

## Validation
- engine focused suites: 105 passed
- producer focused suites: 15 passed
- full engine suite: 1,176 passed, 3 skipped
- full producer unit lane: 32 Vitest files / 393 tests plus all classified Bun unit tests
- engine and producer typechecks passed
- oxlint, oxfmt, Fallow, tracked-artifact, and commit hooks passed
- independent review: approved for merge default-off; candidate enforcement held on companion transport rollout
2026-07-26 16:33:00 -04:00
James 66e44e77dc fix(render): aggregate extraction launch failures 2026-07-26 19:47:33 +00:00
James a142085ca2 fix(producer): narrow extraction error shapes honestly 2026-07-26 19:47:33 +00:00
James 18ff1f885f fix(producer): type video extraction failures 2026-07-26 19:47:33 +00:00
James RussoandGitHub 86454b6d65 fix(engine): make remote video downloads atomic (#2774)
## Summary
- stage remote video downloads in private per-attempt directories and atomically publish only complete non-empty files
- keep the deadline active through response-body streaming and retry one bounded transient failure
- preserve render cancellation without sharing abort ownership across independent callers
- manually follow at most five redirects, validating HTTPS/public-host policy before every hop
- remove stale zero-byte finals and avoid a permanent render-scoped cache map

## Root cause
The previous downloader wrote directly to the final cache path and cleared its timeout as soon as response headers arrived. A body timeout or mid-stream socket reset could therefore leave a truncated file at a path that later extraction treated as complete. The downstream symptom was zero extracted frames followed by a generic video coverage failure.

## Retry policy
Exactly one retry is allowed for 408, 429, 5xx, timeouts, empty successful bodies, and network/socket failures including nested Undici errors. Cancellation, 404/410, other 4xx, URL/redirect validation errors, and filesystem errors are not retried.

## Security and portability
- `mkdtempSync` creates an unguessable same-filesystem staging directory; exclusive writes plus atomic rename prevent symlink planting and partial publication
- redirects use `redirect: "manual"` and every resolved `Location` is revalidated before the next request, blocking redirect-to-private/IMDS bypasses
- the partial file is opened read/write for `fsync`, which preserves flush semantics and avoids Windows `EPERM`

## Rollout safety
This does not change render-plan schema, Plan v1 artifacts, chunk routing, or distributed rendering semantics. It is suitable for the candidate sidecar lane first; stable can remain pinned while we compare video extraction and coverage failures.

## Validation
- focused urlDownloader suite: 28 passed
- full engine suite: 1,169 passed, 3 skipped
- engine typecheck passed
- oxlint and oxfmt passed
- fallow audit passed
- independent code review: approved, no blockers
2026-07-26 15:45:50 -04:00
James 3d93eb037a fix(engine): block future-use IPv4 downloads 2026-07-26 19:00:41 +00:00
James c8b749b10d fix(engine): close downloader trust-boundary gaps 2026-07-26 19:00:41 +00:00
James bf89116243 fix(engine): narrow network error shapes honestly 2026-07-26 19:00:41 +00:00
James 15696acf90 fix(engine): make video downloads atomic and retry transient failures 2026-07-26 19:00:41 +00:00
James RussoandGitHub 78f59cfb26 fix(producer): attribute and stop oversized plans early (#2773)
## What

- add an exact, symlink-safe plan-size breakdown with fixed or hashed component labels
- reject oversized plans after the compiled tree stabilizes, before video extraction
- reject again after artifact promotion but before the full freeze/hash read
- retain the exact post-freeze ceiling check and existing `PLAN_TOO_LARGE` contract/message prefix
- remove only freeze-owned stale metadata before the preliminary check when callers reuse a plan directory

## Why

The existing ceiling only runs after a multi-GiB plan has been fully materialized and hashed. Production examples range from roughly 3 GiB to 12.6 GiB. This gives us enough attribution to design Plan v2 from real data while avoiding obviously wasted extraction and hashing work.

## Compatibility and rollout

- no v1 plan artifact or `plan.json` format changes
- no queue, routing, retry, worker-count, or steady-state render changes
- under-limit plan bytes/hashes remain governed by the existing freeze path
- intended for the candidate sidecar and canary lane before broader rollout

This does not interrupt a single FFmpeg extraction once it is running. A canaried extraction-budget monitor is a separate follow-up.

## Validation

- focused distributed-plan tests: 54 passed
- full producer unit lane: 31 Vitest files / 384 tests plus all classified Bun lanes passed
- typecheck, lint, format, Fallow, tracked-artifact checks passed
- independent code review approved
2026-07-26 15:00:14 -04:00
James 9db91e7cd6 fix(producer): reset distributed plan scratch state 2026-07-26 18:12:15 +00:00
James dbc4bd2a12 fix(producer): attribute and stop oversized plans early 2026-07-26 18:12:15 +00:00
Ular KimsanovandGitHub b4fa3d932d Merge pull request #2797 from heygen-com/feat/studio-professional-color-grading
feat(studio): add professional grading controls
2026-07-26 10:45:43 -07:00
Ular KimsanovandGitHub 966b12580d Merge pull request #2798 from heygen-com/feat/agent-native-color-grading
feat(cli): expose agent-native color grading
2026-07-26 03:23:29 -07:00
Ular KimsanovandGitHub e5543f46fe Merge pull request #2796 from heygen-com/feat/professional-color-grading-core
feat(core): add professional color grading controls
2026-07-26 02:38:42 -07:00
ukimsanov 3aae354559 fix(studio): align professional grading contracts 2026-07-26 01:47:06 -07:00
ukimsanov 84169edee6 fix(studio): clear stale color scopes 2026-07-26 01:29:32 -07:00
ukimsanov 6953f1c9f1 feat(studio): add professional grading controls 2026-07-26 01:29:32 -07:00
ukimsanov 2378951161 test(cli): harden media treatment parity 2026-07-26 01:29:05 -07:00
ukimsanov b349a7ca88 fix(core): register media analyzer subpath 2026-07-26 01:25:42 -07:00
ukimsanov c78191645c fix(cli): address media treatment review findings 2026-07-26 01:25:42 -07:00
ukimsanov 1773e72140 feat(cli): expose agent-native color grading 2026-07-26 01:25:42 -07:00
ukimsanov dcce69c2e5 fix(core): align secondary mask contracts 2026-07-26 01:25:16 -07:00
James RussoandGitHub bd745efdae feat(gcp-cloud-run): publish plan v2 directly to GCS (#2799)
## What

- publishes Plan v2 content-addressed artifacts directly from the Cloud Run planner's private staging directory to GCS
- commits the Plan v2 manifest only after every referenced artifact is durable
- removes the second local Plan v2 CAS directory and preserves the existing Cloud Workflows wire contract
- exports a reusable GCS publisher adapter

## Why

Cloud Run planner, chunk, and assembler requests are independent containers and do not share a filesystem. The distributed contract must contain only durable GCS locators.

This layer makes the Plan v2 publication path object-store-native. Like the AWS parent PR, it still relies on one planner-local frozen v1 tree inside the producer; eliminating that remaining staging tree requires direct Plan v2 emission in a later layer.

## Design invariants

- local paths never cross a request or worker boundary
- manifest and artifact locators derive from one validated GCS output prefix
- immutable objects use generation-zero conditional creation and exact digest/size verification
- retries may reuse exact objects but never overwrite conflicts
- the manifest is the final publication commit point
- chunk and assembler requests independently download and verify only their target artifacts

## Test plan

- [x] all 95 GCP Cloud Run package tests pass
- [x] package typecheck passes
- [x] package build passes
- [x] changed-file lint, format, fallow, and repository commit gates pass
- [x] end-to-end adapter test covers plan, target-scoped chunk, and assemble through Fake GCS with no shared local directory
2026-07-26 04:12:50 -04:00
ukimsanov 9deeb873e4 fix(core): preserve curve compiler subpath exports 2026-07-25 23:38:32 -07:00
James RussoandGitHub 43c286d237 Merge pull request #2795 from heygen-com/feat/plan-v2-aws-direct-publisher
feat(aws-lambda): publish plan v2 directly to S3
2026-07-26 02:23:35 -04:00
ukimsanov b8d40ebb4c fix(core): address grading review findings 2026-07-25 23:16:50 -07:00
James RussoandGitHub 4868240ab0 chore: release v0.7.72 (#2800) 2026-07-26 02:01:10 -04:00
James a436589a44 feat(gcp-cloud-run): publish plan v2 directly to GCS 2026-07-26 05:48:38 +00:00