From 8cbf63f86022fde3a760534195615b59afbe7c55 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 16 May 2026 19:31:00 +0000 Subject: [PATCH] chore(producer): drop internal plan-doc refs from source + docs The producer source + docs referenced an internal coordination doc (DISTRIBUTED-RENDERING-PLAN.md) that doesn't ship in the OSS repo, leaving broken cross-links for adopters. Drops the references and the bare section-number shorthand that depended on them; behavioural content (hash contract, retry semantics, threshold rationale) is preserved inline where it was previously offloaded to a section number. --- packages/producer/README.md | 2 -- packages/producer/src/distributed.ts | 6 ++--- .../src/regression-harness-distributed.ts | 15 +++++++------ .../src/services/render/stages/planHash.ts | 9 ++++---- .../src/services/render/stages/probeStage.ts | 8 ++++--- .../src/services/renderOrchestrator.ts | 4 ++-- packages/producer/tests/README.md | 22 ++++++++++--------- 7 files changed, 35 insertions(+), 31 deletions(-) diff --git a/packages/producer/README.md b/packages/producer/README.md index c77691732..dc96d1920 100644 --- a/packages/producer/README.md +++ b/packages/producer/README.md @@ -136,8 +136,6 @@ await assemble( The three activity functions plus their result types are also re-exported from `@hyperframes/producer` so callers that pin the main package don't need a separate subpath import. Supported formats: `mp4` SDR, `mov` ProRes 4444, and `png-sequence`. webm and HDR mp4 trip a typed `FormatNotSupportedInDistributedError` — use the in-process renderer (`executeRenderJob`) for those. -See [`DISTRIBUTED-RENDERING-PLAN.md`](../../DISTRIBUTED-RENDERING-PLAN.md) for the full architecture. - ## How it works 1. **Serve** — spins up a local file server for the HTML composition diff --git a/packages/producer/src/distributed.ts b/packages/producer/src/distributed.ts index 8a402187d..c63b3d533 100644 --- a/packages/producer/src/distributed.ts +++ b/packages/producer/src/distributed.ts @@ -1,9 +1,9 @@ /** * `@hyperframes/producer/distributed` — the distributed render primitives. * - * See `DISTRIBUTED-RENDERING-PLAN.md` for the full architecture. The three - * activities (`plan` → `renderChunk` × N → `assemble`) are pure functions - * over local file paths; networking + orchestration live in adapters. + * The three activities (`plan` → `renderChunk` × N → `assemble`) are pure + * functions over local file paths; networking + orchestration live in + * adapters. * * Adopters (AWS Lambda, Cloud Run Jobs, Temporal, K8s Jobs, plain SSH): * diff --git a/packages/producer/src/regression-harness-distributed.ts b/packages/producer/src/regression-harness-distributed.ts index 61123aa78..d2d2b3c15 100644 --- a/packages/producer/src/regression-harness-distributed.ts +++ b/packages/producer/src/regression-harness-distributed.ts @@ -18,11 +18,11 @@ * pass the same quality bar the in-process renderer passes against the * same frozen baseline. A separate {@link DISTRIBUTED_SIMULATED_MIN_PSNR_DB} * pathology floor catches the case where a fixture authored a permissive - * threshold and distributed regresses to fully-black output. The §5.1 - * 50 dB target was written for per-render comparison (fresh in-process vs - * fresh distributed); against the frozen baseline file it's unreachable - * for either mode due to shared encoder/JPEG-capture jitter, so the - * harness can't use it as a per-test gate. + * threshold and distributed regresses to fully-black output. The 50 dB + * "distributed vs in-process" contract is a per-render comparison + * (fresh in-process vs fresh distributed); against the frozen baseline + * file it's unreachable for either mode due to shared encoder/JPEG- + * capture jitter, so the harness can't use it as a per-test gate. * * Not every fixture can run in distributed-simulated mode. Distributed mode * refuses webm, HDR mp4, NTSC framerates, and non-{24,30,60} fps at plan @@ -44,8 +44,9 @@ export type HarnessMode = "in-process" | "distributed-simulated"; * a chunk that renders fully-black against a fixture authored with a * permissive `minPsnr`. Non-pathological drift is caught by the fixture's * own threshold; both modes share the same encoder/JPEG-capture jitter - * floor against the frozen baseline file, so the §5.1 50 dB target is - * unreachable for either mode and isn't a useful per-test gate. + * floor against the frozen baseline file, so the 50 dB distributed-vs- + * in-process contract value is unreachable for either mode and isn't a + * useful per-test gate. */ export const DISTRIBUTED_SIMULATED_MIN_PSNR_DB = 10; diff --git a/packages/producer/src/services/render/stages/planHash.ts b/packages/producer/src/services/render/stages/planHash.ts index effa2ea50..ae03e4157 100644 --- a/packages/producer/src/services/render/stages/planHash.ts +++ b/packages/producer/src/services/render/stages/planHash.ts @@ -1,7 +1,7 @@ /** * planHash — content-addressed hash for distributed render plans. * - * See DISTRIBUTED-RENDERING-PLAN.md §4.2 for the contract: + * Hash contract: * * planHash = sha256( * SCHEMA_PREFIX @@ -14,9 +14,10 @@ * ⊕ fps ⊕ width ⊕ height ⊕ format * ) * - * Two invocations with identical inputs MUST produce the same hash. Adapters - * use this to short-circuit `plan()` on workflow replay and to detect - * cross-version mismatches (§9.3 PLAN_HASH_MISMATCH). + * Two invocations with identical inputs MUST produce the same hash. + * Adapters use this to short-circuit `plan()` on workflow replay and to + * detect cross-version mismatches via a typed PLAN_HASH_MISMATCH error + * (defined in `errors.ts` and enumerated in `events.ts`). * * Pure utility; no caller exists yet — the distributed-render * `services/distributed/plan.ts` will compose it. diff --git a/packages/producer/src/services/render/stages/probeStage.ts b/packages/producer/src/services/render/stages/probeStage.ts index 478f5428e..8dcba9b20 100644 --- a/packages/producer/src/services/render/stages/probeStage.ts +++ b/packages/producer/src/services/render/stages/probeStage.ts @@ -8,9 +8,11 @@ * clean them up in its `finally` block. * * Hard constraints preserved verbatim from the in-process renderer: - * - `recompileWithResolutions` runs inside this stage because it depends - * on browser-resolved durations, even though §2.1 of the distributed - * plan lists recompile as a sibling phase. + * - `recompileWithResolutions` runs inside this stage because it + * depends on browser-resolved durations. (Distributed-pipeline + * callers can think of recompile as logically separate from probe, + * but the implementation co-locates them here because they share + * the browser session.) * - `composition` (videos/audios/duration) is mutated in place — callers * downstream see the reconciled view through the same object reference. * - The stage computes the final composition `duration` and `totalFrames` diff --git a/packages/producer/src/services/renderOrchestrator.ts b/packages/producer/src/services/renderOrchestrator.ts index 3a8ee69f1..4b598b7e2 100644 --- a/packages/producer/src/services/renderOrchestrator.ts +++ b/packages/producer/src/services/renderOrchestrator.ts @@ -1452,8 +1452,8 @@ export async function executeRenderJob( // returned on `compileResult.forceScreenshot`. The sequencer stores it // in a local `captureForceScreenshot` below; the BeginFrame calibration // fallback updates the local — not `cfg` — and capture stages receive - // the value as an explicit parameter. See DISTRIBUTED-RENDERING-PLAN.md - // §4.3 (`LockedRenderConfig.forceScreenshot`). + // the value as an explicit parameter. This keeps `cfg` immutable for + // the rest of the pipeline. const enableChunkedEncode = cfg.enableChunkedEncode; const chunkedEncodeSize = cfg.chunkSizeFrames; // Declared outside the try so `finally` can stop the interval, but diff --git a/packages/producer/tests/README.md b/packages/producer/tests/README.md index 906b7ac41..2ef35f447 100644 --- a/packages/producer/tests/README.md +++ b/packages/producer/tests/README.md @@ -98,14 +98,16 @@ passing in the summary): Both modes use the fixture's authored `minPsnr` as the per-test threshold — distributed must clear the same quality bar in-process -clears against the same frozen baseline. (`DISTRIBUTED-RENDERING-PLAN.md` -§5.1's 50 dB target is a per-render distributed-vs-in-process contract; -against the frozen baseline file, neither mode reaches it consistently -due to shared encoder/JPEG-capture jitter.) An absolute 10 dB pathology -floor catches fully-black-output regressions when a fixture authors a -permissive threshold. A distributed failure at the fixture's own -threshold means the distributed pipeline has drifted — file an issue -rather than relaxing the fixture. +clears against the same frozen baseline. (Internal contract: distributed +vs in-process renders of the same fixture should clear 50 dB PSNR +against each other within the same Docker image. Against the frozen +committed baseline, neither mode reaches that consistently due to +shared encoder/JPEG-capture jitter — that's why the fixture's authored +threshold gates here, not the 50 dB contract value.) An absolute 10 dB +pathology floor catches fully-black-output regressions when a fixture +authors a permissive threshold. A distributed failure at the fixture's +own threshold means the distributed pipeline has drifted — file an +issue rather than relaxing the fixture. `--update` is incompatible with `--mode=distributed-simulated`: the in-process renderer is the source of truth for baselines, and the @@ -145,8 +147,8 @@ exercises one of: - per-format chunk-boundary correctness (mp4 H.264, mp4 H.265, ProRes, png-sequence) - per-adapter chunk-seam state preservation (GSAP, Anime.js, Three.js, Lottie, CSS, WAAPI) -See `DISTRIBUTED-RENDERING-PLAN.md` §10.2 for the equivalence axes each -distributed fixture covers. +Each distributed fixture covers one or more equivalence axes — see the +`meta.json` `description` field for what a given fixture is locking in. ### Fixture pattern (4.2 onward)