@skyphusion-labs/vivijure-core 1.23.0 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Pre-flight input-bytes admission check for a chunked assemble (cf#815).
3
+ *
4
+ * WHAT THIS BOUNDS, AND WHY IT IS NOT AN OUTPUT CAP. The container writes the assembled film to
5
+ * local disk before streaming it to R2, and nothing bounds that write. Chunked assemble (cf#784)
6
+ * flattened peak disk for the BATCH stage -- each batch dir is removed on flush and every partial
7
+ * goes straight to R2 -- but it left the FINALIZE stage untouched:
8
+ *
9
+ * containers/video-finish/app.py:315 `_silent.mp4` <- the joined film
10
+ * containers/video-finish/app.py:786 `final.mp4` <- _mux_bed_onto, written FROM _silent.mp4
11
+ *
12
+ * `_silent.mp4` is never removed (the only `os.remove` calls in the chunked path are the two that
13
+ * reap batch partials, app.py:266 and :270), and the no-bed branch still writes `final.mp4` with
14
+ * `-c copy` rather than renaming. So finalize holds TWO full-length copies of the film at once.
15
+ * That is the term this check bounds. NOTE: the container's own comment at app.py:57-59 says
16
+ * "peak disk at that stage is one film"; the code above says two, and this file follows the code.
17
+ *
18
+ * WHY THE THRESHOLD IS NOT `MAX_CLIPS x MAX_CLIP_BYTES`. cf#813 measures that product (80 x 256 MB
19
+ * = 20.0 GB) as 23x to 120x above what a real film weighs, because `MAX_CLIP_BYTES` is the size at
20
+ * which a DOWNLOAD is refused, not a payload. A gate written against it could never fire, which is
21
+ * worse than no gate because it reads as protection. It is also the wrong QUANTITY: cf#813 measures
22
+ * the normalized-to-source byte ratio at 0.98x to 5.09x, so source bytes do not predict the film.
23
+ *
24
+ * WHAT IT IS WRITTEN AGAINST INSTEAD: bitrate x duration, from cf#813's measured encodes through
25
+ * this container's exact normalize command. See NORMALIZED_BITS_PER_PIXEL_FRAME.
26
+ *
27
+ * WHERE IT RUNS. On the Worker, before the first presign is minted. The Worker has the clip list
28
+ * and the per-clip measured durations for free; the container learns a clip's length only by
29
+ * downloading it. Refusing here costs nothing, refusing there costs the whole download.
30
+ */
31
+ /**
32
+ * Normalized video bits per pixel per frame at the container's encode settings
33
+ * (`libx264 -crf 18 -preset medium`, containers/video-finish/app.py:612).
34
+ *
35
+ * DERIVED FROM cf#813's MEASUREMENT, not picked. Its 1080p24 band tops out at 11.16 Mbps:
36
+ *
37
+ * 11.16e6 bits/s / (1920 x 1080 x 24 px/s) = 0.2243 bits/px/frame
38
+ *
39
+ * Rounded UP to 0.225. Cross-checked against the same measurement's 720p24 ceiling, which is an
40
+ * independent row: 0.225 x 1280 x 720 x 24 = 4.98 Mbps against a measured 4.82 Mbps, i.e. 3.3%
41
+ * conservative. Bits-per-pixel being near-constant across the two resolutions is what lets one
42
+ * number serve any delivery target instead of a per-resolution table that would rot.
43
+ *
44
+ * THE CEILING OF THE BAND, DELIBERATELY, and the direction of error is the point. This predicts
45
+ * the LARGEST film a given input can normalize to, so the refusal comes early rather than after
46
+ * the disk is already full. cf#813 also warns that its pan-based proxies UNDERESTIMATE real
47
+ * generated video (no subject deformation, no per-frame diffusion shimmer), which argues for the
48
+ * ceiling rather than the middle of the band as well.
49
+ *
50
+ * A film's predicted bytes are therefore an upper bound on its size and a lower bound on nothing:
51
+ * a legitimate film lands well under, which is what keeps the CONTROL case admitted.
52
+ */
53
+ export declare const NORMALIZED_BITS_PER_PIXEL_FRAME = 0.225;
54
+ /**
55
+ * Ephemeral disk of the container instance the finish tier runs on.
56
+ *
57
+ * `instance_type = "standard-4"` (vivijure-cf wrangler.toml.example:238), documented there at
58
+ * :201 as "the LARGEST Cloudflare offers (4 vCPU / 12 GiB / 20 GB disk)". Read as DECIMAL GB, the
59
+ * smaller of the two readings, because guessing GiB here would silently widen the budget by 7%.
60
+ */
61
+ export declare const CONTAINER_DISK_BYTES = 20000000000;
62
+ /**
63
+ * Full-length copies of the film resident on disk at once during finalize.
64
+ *
65
+ * TWO, not one: `_silent.mp4` then `final.mp4`, with no remove between them. See the file header
66
+ * for the exact lines. This is the multiplier the whole check turns on, so it is a named constant
67
+ * with its evidence rather than a `* 2` inline.
68
+ */
69
+ export declare const FINALIZE_FILM_COPIES = 2;
70
+ /**
71
+ * Peak disk the BATCH stage may occupy, mirroring the container's own budget at
72
+ * containers/video-finish/app.py:49-50: `3 x (MAX_BATCH_BYTES + MAX_CLIP_BYTES)` -- a batch's
73
+ * sources, their normalized copies, and the batch partial.
74
+ *
75
+ * Reserved even though the batch dirs are removed before the final join, so the two stages do not
76
+ * in fact coexist. cf#815 asks for headroom for "the assembled film plus one batch working set",
77
+ * and a reserve that survives a future reordering of those stages is worth 4 GB of a 20 GB disk.
78
+ *
79
+ * cf#813 argues this multiplier should be ~5x rather than 3x against SOURCE bytes, because the
80
+ * normalized copy is roughly 2x its source while the fixed 1920x1080 target is still upscaling.
81
+ * Correcting the container's constant is cf#813's acceptance item, not this one's; this reserve
82
+ * deliberately quotes the container's CURRENT number so the two cannot silently disagree about
83
+ * what is reserved today.
84
+ */
85
+ export declare const CONTAINER_BATCH_PEAK_BYTES: number;
86
+ /** `MAX_AUDIO_BYTES`, containers/video-finish/app.py:41. The bed lands on disk beside the film. */
87
+ export declare const CONTAINER_AUDIO_BED_BYTES: number;
88
+ /**
89
+ * Disk the image, the OS and ffmpeg's own scratch occupy, which the film must not be allowed to
90
+ * claim. A RESERVE, stated as one: it is not a measurement of the image, and it is deliberately
91
+ * generous, because the cost of over-reserving is a lower film ceiling and the cost of
92
+ * under-reserving is the ENOSPC this check exists to prevent.
93
+ */
94
+ export declare const CONTAINER_IMAGE_RESERVE_BYTES = 2000000000;
95
+ /**
96
+ * Frames per second the container normalizes to when the payload omits `fps`.
97
+ *
98
+ * `int(body.get("fps", 24))`, containers/video-finish/app.py:391 (and :205, :1107).
99
+ *
100
+ * THREE NUMBERS HAVE TO AGREE HERE and a comment cannot make them: the container's fallback, core's
101
+ * `DEFAULT_DELIVERY_FPS` (film-model.ts:1458), and this prediction. `assemble-admission.test.ts`
102
+ * asserts this constant equals `DEFAULT_DELIVERY_FPS`, so a future edit to either one fails a test
103
+ * rather than silently mispredicting every film by the ratio between them.
104
+ */
105
+ export declare const CONTAINER_DEFAULT_FPS = 24;
106
+ /** The largest predicted film the container can finalize on its ephemeral disk. */
107
+ export declare function assembleFilmByteCeiling(): number;
108
+ /** Predicted normalized bytes for `seconds` of video at a delivery target. */
109
+ export declare function predictNormalizedBytes(width: number, height: number, fps: number, seconds: number): number;
110
+ /** Seconds of film this assemble will produce, and how much of that is EVIDENCE. */
111
+ export interface AssembleSecondsBasis {
112
+ /** Summed seconds of every clip whose length is known. */
113
+ seconds: number;
114
+ /** Clips whose length came from the container's own probe (delivered_frames / delivered_fps). */
115
+ measured: number;
116
+ /** Clips whose length came from the plan (bundle target_seconds, else the authored scene). */
117
+ planned: number;
118
+ /** Clips with neither. They contribute ZERO seconds, so `seconds` is a LOWER bound. */
119
+ unknown: number;
120
+ }
121
+ /**
122
+ * Resolve the film's length from what the Worker already holds.
123
+ *
124
+ * MEASURED WINS, PLAN FILLS, ABSENCE IS NAMED. This mirrors the #697 duration gate's discipline
125
+ * (`findClipDurationShortfalls`): the check fires on EVIDENCE and never on absence, so a clip with
126
+ * no known length cannot by itself refuse a film. It contributes zero seconds and is COUNTED, so
127
+ * the caller can say the prediction is a lower bound instead of implying it is complete.
128
+ *
129
+ * A lower bound is still enough to refuse on: if the clips we CAN size already exceed the disk,
130
+ * the ones we cannot size do not make the film smaller.
131
+ */
132
+ export declare function resolveAssembleSeconds(finalClips: {
133
+ shot_id: string;
134
+ }[], measuredSeconds: Map<string, number> | ReadonlyMap<string, number>, plannedSeconds: Record<string, number>): AssembleSecondsBasis;
135
+ export interface AssembleAdmissionInput {
136
+ clipCount: number;
137
+ width: number;
138
+ height: number;
139
+ fps?: number;
140
+ basis: AssembleSecondsBasis;
141
+ }
142
+ export interface AssembleAdmission {
143
+ admitted: boolean;
144
+ predictedBytes: number;
145
+ ceilingBytes: number;
146
+ /** Seconds of film the ceiling allows at this delivery target. The actionable number. */
147
+ allowedSeconds: number;
148
+ basis: AssembleSecondsBasis;
149
+ /** Loud, arithmetic-bearing refusal. Set only when `admitted` is false. */
150
+ reason?: string;
151
+ }
152
+ /**
153
+ * Admit or refuse an assemble before a single byte is fetched.
154
+ *
155
+ * PURE. Every number it uses is either passed in or a constant above with its provenance, so the
156
+ * arithmetic in the refusal is reproducible from the message alone.
157
+ *
158
+ * REFUSAL IS LOUD AND TERMINAL, never a degrade (cf#815, the #249/#77 discipline). A film that
159
+ * cannot fit is not silently truncated to one that does: the caller is told what was asked, what
160
+ * fits, by how much it is over, and what length would be accepted.
161
+ */
162
+ export declare function admitAssemble(input: AssembleAdmissionInput): AssembleAdmission;
163
+ //# sourceMappingURL=assemble-admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assemble-admission.d.ts","sourceRoot":"","sources":["../src/assemble-admission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,+BAA+B,QAAQ,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,cAAiB,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,0BAA0B,QAA+C,CAAC;AAEvF,mGAAmG;AACnG,eAAO,MAAM,yBAAyB,QAAoB,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,aAAgB,CAAC;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,mFAAmF;AACnF,wBAAgB,uBAAuB,IAAI,MAAM,CAIhD;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,MAAM,CAGR;AAED,oFAAoF;AACpF,MAAM,WAAW,oBAAoB;IACnC,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,QAAQ,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,EACjC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAClE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,oBAAoB,CAsBtB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,oBAAoB,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,yFAAyF;IACzF,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,sBAAsB,GAAG,iBAAiB,CAwB9E"}
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Pre-flight input-bytes admission check for a chunked assemble (cf#815).
3
+ *
4
+ * WHAT THIS BOUNDS, AND WHY IT IS NOT AN OUTPUT CAP. The container writes the assembled film to
5
+ * local disk before streaming it to R2, and nothing bounds that write. Chunked assemble (cf#784)
6
+ * flattened peak disk for the BATCH stage -- each batch dir is removed on flush and every partial
7
+ * goes straight to R2 -- but it left the FINALIZE stage untouched:
8
+ *
9
+ * containers/video-finish/app.py:315 `_silent.mp4` <- the joined film
10
+ * containers/video-finish/app.py:786 `final.mp4` <- _mux_bed_onto, written FROM _silent.mp4
11
+ *
12
+ * `_silent.mp4` is never removed (the only `os.remove` calls in the chunked path are the two that
13
+ * reap batch partials, app.py:266 and :270), and the no-bed branch still writes `final.mp4` with
14
+ * `-c copy` rather than renaming. So finalize holds TWO full-length copies of the film at once.
15
+ * That is the term this check bounds. NOTE: the container's own comment at app.py:57-59 says
16
+ * "peak disk at that stage is one film"; the code above says two, and this file follows the code.
17
+ *
18
+ * WHY THE THRESHOLD IS NOT `MAX_CLIPS x MAX_CLIP_BYTES`. cf#813 measures that product (80 x 256 MB
19
+ * = 20.0 GB) as 23x to 120x above what a real film weighs, because `MAX_CLIP_BYTES` is the size at
20
+ * which a DOWNLOAD is refused, not a payload. A gate written against it could never fire, which is
21
+ * worse than no gate because it reads as protection. It is also the wrong QUANTITY: cf#813 measures
22
+ * the normalized-to-source byte ratio at 0.98x to 5.09x, so source bytes do not predict the film.
23
+ *
24
+ * WHAT IT IS WRITTEN AGAINST INSTEAD: bitrate x duration, from cf#813's measured encodes through
25
+ * this container's exact normalize command. See NORMALIZED_BITS_PER_PIXEL_FRAME.
26
+ *
27
+ * WHERE IT RUNS. On the Worker, before the first presign is minted. The Worker has the clip list
28
+ * and the per-clip measured durations for free; the container learns a clip's length only by
29
+ * downloading it. Refusing here costs nothing, refusing there costs the whole download.
30
+ */
31
+ /**
32
+ * Normalized video bits per pixel per frame at the container's encode settings
33
+ * (`libx264 -crf 18 -preset medium`, containers/video-finish/app.py:612).
34
+ *
35
+ * DERIVED FROM cf#813's MEASUREMENT, not picked. Its 1080p24 band tops out at 11.16 Mbps:
36
+ *
37
+ * 11.16e6 bits/s / (1920 x 1080 x 24 px/s) = 0.2243 bits/px/frame
38
+ *
39
+ * Rounded UP to 0.225. Cross-checked against the same measurement's 720p24 ceiling, which is an
40
+ * independent row: 0.225 x 1280 x 720 x 24 = 4.98 Mbps against a measured 4.82 Mbps, i.e. 3.3%
41
+ * conservative. Bits-per-pixel being near-constant across the two resolutions is what lets one
42
+ * number serve any delivery target instead of a per-resolution table that would rot.
43
+ *
44
+ * THE CEILING OF THE BAND, DELIBERATELY, and the direction of error is the point. This predicts
45
+ * the LARGEST film a given input can normalize to, so the refusal comes early rather than after
46
+ * the disk is already full. cf#813 also warns that its pan-based proxies UNDERESTIMATE real
47
+ * generated video (no subject deformation, no per-frame diffusion shimmer), which argues for the
48
+ * ceiling rather than the middle of the band as well.
49
+ *
50
+ * A film's predicted bytes are therefore an upper bound on its size and a lower bound on nothing:
51
+ * a legitimate film lands well under, which is what keeps the CONTROL case admitted.
52
+ */
53
+ export const NORMALIZED_BITS_PER_PIXEL_FRAME = 0.225;
54
+ /**
55
+ * Ephemeral disk of the container instance the finish tier runs on.
56
+ *
57
+ * `instance_type = "standard-4"` (vivijure-cf wrangler.toml.example:238), documented there at
58
+ * :201 as "the LARGEST Cloudflare offers (4 vCPU / 12 GiB / 20 GB disk)". Read as DECIMAL GB, the
59
+ * smaller of the two readings, because guessing GiB here would silently widen the budget by 7%.
60
+ */
61
+ export const CONTAINER_DISK_BYTES = 20_000_000_000;
62
+ /**
63
+ * Full-length copies of the film resident on disk at once during finalize.
64
+ *
65
+ * TWO, not one: `_silent.mp4` then `final.mp4`, with no remove between them. See the file header
66
+ * for the exact lines. This is the multiplier the whole check turns on, so it is a named constant
67
+ * with its evidence rather than a `* 2` inline.
68
+ */
69
+ export const FINALIZE_FILM_COPIES = 2;
70
+ /**
71
+ * Peak disk the BATCH stage may occupy, mirroring the container's own budget at
72
+ * containers/video-finish/app.py:49-50: `3 x (MAX_BATCH_BYTES + MAX_CLIP_BYTES)` -- a batch's
73
+ * sources, their normalized copies, and the batch partial.
74
+ *
75
+ * Reserved even though the batch dirs are removed before the final join, so the two stages do not
76
+ * in fact coexist. cf#815 asks for headroom for "the assembled film plus one batch working set",
77
+ * and a reserve that survives a future reordering of those stages is worth 4 GB of a 20 GB disk.
78
+ *
79
+ * cf#813 argues this multiplier should be ~5x rather than 3x against SOURCE bytes, because the
80
+ * normalized copy is roughly 2x its source while the fixed 1920x1080 target is still upscaling.
81
+ * Correcting the container's constant is cf#813's acceptance item, not this one's; this reserve
82
+ * deliberately quotes the container's CURRENT number so the two cannot silently disagree about
83
+ * what is reserved today.
84
+ */
85
+ export const CONTAINER_BATCH_PEAK_BYTES = 3 * (1024 * 1024 * 1024 + 256 * 1024 * 1024);
86
+ /** `MAX_AUDIO_BYTES`, containers/video-finish/app.py:41. The bed lands on disk beside the film. */
87
+ export const CONTAINER_AUDIO_BED_BYTES = 256 * 1024 * 1024;
88
+ /**
89
+ * Disk the image, the OS and ffmpeg's own scratch occupy, which the film must not be allowed to
90
+ * claim. A RESERVE, stated as one: it is not a measurement of the image, and it is deliberately
91
+ * generous, because the cost of over-reserving is a lower film ceiling and the cost of
92
+ * under-reserving is the ENOSPC this check exists to prevent.
93
+ */
94
+ export const CONTAINER_IMAGE_RESERVE_BYTES = 2_000_000_000;
95
+ /**
96
+ * Frames per second the container normalizes to when the payload omits `fps`.
97
+ *
98
+ * `int(body.get("fps", 24))`, containers/video-finish/app.py:391 (and :205, :1107).
99
+ *
100
+ * THREE NUMBERS HAVE TO AGREE HERE and a comment cannot make them: the container's fallback, core's
101
+ * `DEFAULT_DELIVERY_FPS` (film-model.ts:1458), and this prediction. `assemble-admission.test.ts`
102
+ * asserts this constant equals `DEFAULT_DELIVERY_FPS`, so a future edit to either one fails a test
103
+ * rather than silently mispredicting every film by the ratio between them.
104
+ */
105
+ export const CONTAINER_DEFAULT_FPS = 24;
106
+ /** The largest predicted film the container can finalize on its ephemeral disk. */
107
+ export function assembleFilmByteCeiling() {
108
+ const reserved = CONTAINER_BATCH_PEAK_BYTES + CONTAINER_AUDIO_BED_BYTES + CONTAINER_IMAGE_RESERVE_BYTES;
109
+ return Math.max(0, Math.floor((CONTAINER_DISK_BYTES - reserved) / FINALIZE_FILM_COPIES));
110
+ }
111
+ /** Predicted normalized bytes for `seconds` of video at a delivery target. */
112
+ export function predictNormalizedBytes(width, height, fps, seconds) {
113
+ if (!(width > 0) || !(height > 0) || !(fps > 0) || !(seconds > 0))
114
+ return 0;
115
+ return Math.ceil((NORMALIZED_BITS_PER_PIXEL_FRAME * width * height * fps * seconds) / 8);
116
+ }
117
+ /**
118
+ * Resolve the film's length from what the Worker already holds.
119
+ *
120
+ * MEASURED WINS, PLAN FILLS, ABSENCE IS NAMED. This mirrors the #697 duration gate's discipline
121
+ * (`findClipDurationShortfalls`): the check fires on EVIDENCE and never on absence, so a clip with
122
+ * no known length cannot by itself refuse a film. It contributes zero seconds and is COUNTED, so
123
+ * the caller can say the prediction is a lower bound instead of implying it is complete.
124
+ *
125
+ * A lower bound is still enough to refuse on: if the clips we CAN size already exceed the disk,
126
+ * the ones we cannot size do not make the film smaller.
127
+ */
128
+ export function resolveAssembleSeconds(finalClips, measuredSeconds, plannedSeconds) {
129
+ let seconds = 0;
130
+ let measured = 0;
131
+ let planned = 0;
132
+ let unknown = 0;
133
+ for (const c of finalClips ?? []) {
134
+ if (!c || typeof c.shot_id !== "string")
135
+ continue;
136
+ const m = measuredSeconds?.get(c.shot_id);
137
+ if (typeof m === "number" && Number.isFinite(m) && m > 0) {
138
+ seconds += m;
139
+ measured += 1;
140
+ continue;
141
+ }
142
+ const p = plannedSeconds?.[c.shot_id];
143
+ if (typeof p === "number" && Number.isFinite(p) && p > 0) {
144
+ seconds += p;
145
+ planned += 1;
146
+ continue;
147
+ }
148
+ unknown += 1;
149
+ }
150
+ return { seconds, measured, planned, unknown };
151
+ }
152
+ function gb(bytes) {
153
+ return `${(bytes / 1_000_000_000).toFixed(2)} GB`;
154
+ }
155
+ /**
156
+ * Admit or refuse an assemble before a single byte is fetched.
157
+ *
158
+ * PURE. Every number it uses is either passed in or a constant above with its provenance, so the
159
+ * arithmetic in the refusal is reproducible from the message alone.
160
+ *
161
+ * REFUSAL IS LOUD AND TERMINAL, never a degrade (cf#815, the #249/#77 discipline). A film that
162
+ * cannot fit is not silently truncated to one that does: the caller is told what was asked, what
163
+ * fits, by how much it is over, and what length would be accepted.
164
+ */
165
+ export function admitAssemble(input) {
166
+ const fps = input.fps && input.fps > 0 ? input.fps : CONTAINER_DEFAULT_FPS;
167
+ const { width, height, basis, clipCount } = input;
168
+ const ceilingBytes = assembleFilmByteCeiling();
169
+ const predictedBytes = predictNormalizedBytes(width, height, fps, basis.seconds);
170
+ const perSecond = predictNormalizedBytes(width, height, fps, 1);
171
+ const allowedSeconds = perSecond > 0 ? Math.floor(ceilingBytes / perSecond) : 0;
172
+ if (predictedBytes <= ceilingBytes) {
173
+ return { admitted: true, predictedBytes, ceilingBytes, allowedSeconds, basis };
174
+ }
175
+ const over = predictedBytes - ceilingBytes;
176
+ const bound = basis.unknown > 0 ? " (a LOWER bound: " + basis.unknown + " clip(s) of unknown length contributed 0s)" : "";
177
+ const reason = `assemble refused before any clip was fetched: ${clipCount} clip(s) totalling ` +
178
+ `${basis.seconds.toFixed(1)}s at ${width}x${height}@${fps} predict ${gb(predictedBytes)} of ` +
179
+ `normalized video${bound}, and the container can finalize at most ${gb(ceilingBytes)}. ` +
180
+ `Over by ${gb(over)}. Budget: ${gb(CONTAINER_DISK_BYTES)} ephemeral disk (standard-4), less ` +
181
+ `${gb(CONTAINER_BATCH_PEAK_BYTES)} batch working set, ${gb(CONTAINER_AUDIO_BED_BYTES)} audio ` +
182
+ `bed and ${gb(CONTAINER_IMAGE_RESERVE_BYTES)} image reserve, divided by ` +
183
+ `${FINALIZE_FILM_COPIES} full-length copies resident at finalize. ` +
184
+ `Basis: ${basis.measured} measured, ${basis.planned} planned, ${basis.unknown} unknown. ` +
185
+ `This delivery target admits at most ${allowedSeconds}s; reduce the film, or lower ` +
186
+ `delivery_width/delivery_height.`;
187
+ return { admitted: false, predictedBytes, ceilingBytes, allowedSeconds, basis, reason };
188
+ }
189
+ //# sourceMappingURL=assemble-admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assemble-admission.js","sourceRoot":"","sources":["../src/assemble-admission.ts"],"names":[],"mappings":"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"}
@@ -64,6 +64,20 @@ export declare function measuredClipDimensions(env: Env, job: FilmJob): Promise<
64
64
  width: number;
65
65
  height: number;
66
66
  }>>;
67
+ /**
68
+ * Per-shot MEASURED clip seconds, from the clip doc the render already wrote.
69
+ *
70
+ * Sibling of `measuredClipDimensions` above, reading the same single R2 object: `delivered_frames`
71
+ * and `delivered_fps` are persisted on every done clip by `validateDoneClips`
72
+ * (render-orchestrator.ts:163-164) from the container's own probe. `frames / fps` is therefore a
73
+ * measurement of what the clip IS, not a plan for what it should have been.
74
+ *
75
+ * A MISS IS NOT A DEFAULT, for the same reason as the dimensions sibling. No clip doc, an
76
+ * unparseable doc, a shot with neither field, or a non-positive fps all yield NO ENTRY, and the
77
+ * caller falls back to the PLAN and counts the fallback. Inventing a duration here would put a
78
+ * fabricated number into a refusal message, which is the one place it must not appear.
79
+ */
80
+ export declare function measuredClipSeconds(env: Env, job: FilmJob): Promise<Map<string, number>>;
67
81
  /** Call the video-finish container's POST /finish, retrying on a transient gateway status -- 503 (a
68
82
  * cold container can 503 while its port is still binding -- same shape as callImagePrep in
69
83
  * bundle-assembler) or 504 (a cold-boot + ffmpeg concat that exceeds the request window; issue #82).
@@ -1 +1 @@
1
- {"version":3,"file":"film-orchestrator.d.ts","sourceRoot":"","sources":["../src/film-orchestrator.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oCAAoC,CAAC;AAyC9D,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,UAAU,EAGf,KAAK,eAAe,EACpB,KAAK,OAAO,EAkDb,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAEV,gBAAgB,EAIhB,WAAW,EAIX,YAAY,EAGZ,WAAW,EAOX,aAAa,EACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAML,mBAAmB,EAMnB,KAAK,OAAO,EAEb,MAAM,0BAA0B,CAAC;AAmBlC,cAAc,iBAAiB,CAAC;AAYhC,oFAAoF;AACpF,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAsB9B;AAmCD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAGhF;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CAGR;AAuED,gGAAgG;AAChG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,SAAS,GAAG,YAAY,EAAE,CAEpF;AA0ND;;;;;;;;mFAQmF;AACnF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,cAAc,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAG3G;AAED;yGACyG;AACzG,wBAAgB,yBAAyB,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAIzG;AAED,uGAAuG;AACvG,wBAAgB,0BAA0B,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAI1G;AAED;;;oFAGoF;AACpF,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gBAAgB,EAAE,EAC3B,cAAc,EAAE,OAAO,EACvB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACrD,gBAAgB,EAAE,CAOpB;AA0cD;;;;;gGAKgG;AAChG,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED;;mGAEmG;AACnG,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,EACZ,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CA2Cf;AAED,yGAAyG;AACzG,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBtF;AAED;gGACgG;AAChG;;;;;;;;;;;;;;gFAcgF;AAChF,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAoBzD;AAwKD;;;;;mGAKmG;AACnG,wBAAsB,eAAe,CACnC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE;IACP,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,EACD,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAClD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAqB1B;AAcD;;gFAEgF;AAChF,wBAAsB,YAAY,CAChC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE;IACP,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,EACD,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAClD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAqB1B;AAED;;mEAEmE;AACnE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAGnE;AAiDD,eAAO,MAAM,mCAAmC,OAAO,CAAC;AAoHxD;2FAC2F;AAC3F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,OAAO,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,EAAE,CAAA;SAAE,CAAA;KAAE,CAAC;IAC7F,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IAGf,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI1C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AACD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAMlB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAKlB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAI/C,eAAO,MAAM,qCAAqC,OAAO,CAAC;AA4D1D;;kGAEkG;AAClG,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;2FAM2F;AAC3F,wBAAsB,YAAY,CAChC,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CA8B9E;AAgDD;;kFAEkF;AAClF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAE9E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAG1E;AAED,4FAA4F;AAC5F,wBAAgB,uBAAuB,CACrC,GAAG,EAAE;IAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,EACnC,SAAS,EAAE,OAAO,GACjB,IAAI,CAIN;AA+CD;;;;;;;;;;;6EAW6E;AAC7E,wBAAsB,aAAa,CACjC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,kBAAkB,EACzB,UAAU,CAAC,EAAE,gBAAgB,EAAE,EAC/B,IAAI,CAAC,EAAE;IAIL,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAK7D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAInE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAKjE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACA,OAAO,CAAC,mBAAmB,CAAC,CAyL9B;AA2cD,gGAAgG;AAChG,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,GAAG,EACR,IAAI,EAAE;IACJ,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,+FAA+F;IAC/F,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,WAAW,EAAE,WAAW,GAAG,iBAAiB,CAAC;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IAOnB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;wFACoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,EACD,UAAU,CAAC,EAAE,gBAAgB,EAAE,GAC9B,OAAO,CAAC,OAAO,CAAC,CAgGlB;AAED,yGAAyG;AACzG,wBAAsB,YAAY,CAChC,GAAG,EAAE,GAAG,EACR,IAAI,EAAE;IACJ,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,EAAE,CAAC;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvI,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,+FAA+F;IAC/F,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,OAAO,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,EAAE,CAAA;SAAE,CAAA;KAAE,CAAC;IAC7F;wFACoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,EACD,UAAU,CAAC,EAAE,gBAAgB,EAAE,GAC9B,OAAO,CAAC,OAAO,CAAC,CAoHlB;AAED,kFAAkF;AAClF,wBAAsB,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAqBrF;AAED;;;;;;;;;mEASmE;AACnE,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;AACxC,mGAAmG;AACnG,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GACxB,OAAO,CAAC,eAAe,EAAE,CAAC,CAoC5B;AAED;;;yFAGyF;AACzF,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAYtF;AA0ND;;;;;sFAKsF;AACtF,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,EACZ,UAAU,CAAC,EAAE,gBAAgB,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAuDD,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAE/B;;;6EAG6E;AAC7E,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAI5J;AAmJD;;;;;;;;;;;8CAW8C;AAC9C,wBAAsB,cAAc,CAClC,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,gBAAgB,EAAE,GAC9B,OAAO,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAAC,CAkC3D"}
1
+ {"version":3,"file":"film-orchestrator.d.ts","sourceRoot":"","sources":["../src/film-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ import { usageOf } from "./motion-usage.js";
17
17
  import { LINE_WAV_MIN_SECONDS, mintSilenceWav, normalizeLineWav, secondsForShot, } from "./wav-duration.js";
18
18
  import { claimFilmSubmit, naturalKeyForStartFilmJob, naturalKeyForStartFromKeyframes, releaseFilmSubmitClaim, } from "./film-submit-idempotency.js";
19
19
  import { filmJobDocKey as filmKey, clipJobDocKey as clipDocKey, orderFinalClips, joinKeyframesToScenes, composeMotionPrompt, spokenLineForShot, applyVoiceSeed, applyFinishOutput, applyFinishOutputOrRefuse, adoptFinishStepOutput, applySpeechOutput, FINISH_STEP_MAX_ATTEMPTS, classifyFinishFailure, classifyFinishRetry, resolveFinishConfigs, finishShotAdoptableFromR2, finishShotRecoverable, finishPhaseBlockers, reclaimFinishShotsFromR2, finishStepOutputKey, finishStepAppliedTag, finishShotLedgerReconciles, MASTER_STEP_MAX_ATTEMPTS, MASTER_STALL_SECONDS, filmSeconds, masteredBedKey, applyMasterOutput, degradeMasterStep, masterChainDone, coerceSceneIds, coerceDialogueLineIds, resolveKeyframeParallel, partitionContiguous, KEYFRAME_STALL_SECONDS, PHASE_HARD_DEADLINE_SECONDS, phaseCeilingVerdict, POLLABLE_PHASES, phaseAgeSeconds, stampFilmProgress, resolveClipDurationFloor, mapClipDurationsToShots, resolvePlannedSeconds, findClipDurationShortfalls, captionDurations, resolveDeliveryResolution, DEFAULT_DELIVERY_FPS, } from "./film-model.js";
20
+ import { admitAssemble, resolveAssembleSeconds, } from "./assemble-admission.js";
20
21
  import { retimeSrt } from "./srt.js";
21
22
  import { loadInstallConfig } from "./operator-config.js";
22
23
  import { startClipJob, advanceClipJob, cancelInFlightClips, summarizeJob, describeClipFailures, clipFileMatchesShot, finishedClipFileMatchesShot, listClipsByShotId, reclaimClipsFromR2, validateDoneClips, } from "./render-orchestrator.js";
@@ -1081,6 +1082,40 @@ export async function measuredClipDimensions(env, job) {
1081
1082
  }
1082
1083
  return out;
1083
1084
  }
1085
+ /**
1086
+ * Per-shot MEASURED clip seconds, from the clip doc the render already wrote.
1087
+ *
1088
+ * Sibling of `measuredClipDimensions` above, reading the same single R2 object: `delivered_frames`
1089
+ * and `delivered_fps` are persisted on every done clip by `validateDoneClips`
1090
+ * (render-orchestrator.ts:163-164) from the container's own probe. `frames / fps` is therefore a
1091
+ * measurement of what the clip IS, not a plan for what it should have been.
1092
+ *
1093
+ * A MISS IS NOT A DEFAULT, for the same reason as the dimensions sibling. No clip doc, an
1094
+ * unparseable doc, a shot with neither field, or a non-positive fps all yield NO ENTRY, and the
1095
+ * caller falls back to the PLAN and counts the fallback. Inventing a duration here would put a
1096
+ * fabricated number into a refusal message, which is the one place it must not appear.
1097
+ */
1098
+ export async function measuredClipSeconds(env, job) {
1099
+ const out = new Map();
1100
+ if (!job.clip_job_id)
1101
+ return out;
1102
+ try {
1103
+ const obj = await env.R2_RENDERS.get(clipDocKey(job.clip_job_id));
1104
+ if (!obj)
1105
+ return out;
1106
+ const clipJob = JSON.parse(await obj.text());
1107
+ for (const sh of clipJob.shots || []) {
1108
+ const frames = Number(sh.delivered_frames), fps = Number(sh.delivered_fps);
1109
+ if (Number.isFinite(frames) && frames > 0 && Number.isFinite(fps) && fps > 0) {
1110
+ out.set(sh.shot_id, frames / fps);
1111
+ }
1112
+ }
1113
+ }
1114
+ catch {
1115
+ return out;
1116
+ }
1117
+ return out;
1118
+ }
1084
1119
  async function advanceFinishPhase(env, job, preModules) {
1085
1120
  const envRec = env;
1086
1121
  // Read once per pass, not per shot: one GET serves every shot in this dispatch.
@@ -2306,6 +2341,45 @@ async function enterAssemblePhase(env, job, finalClips, preModules) {
2306
2341
  height: delivery.height,
2307
2342
  };
2308
2343
  if (!job.assemble_poll) {
2344
+ // cf#815: PRE-FLIGHT INPUT ADMISSION. Refuse a film that cannot fit the container's ephemeral
2345
+ // disk BEFORE a presign is minted, so nothing is downloaded, normalized or encoded first.
2346
+ //
2347
+ // Inside the `!job.assemble_poll` branch deliberately: this is the one pass that mints URLs and
2348
+ // submits, so it is the only pass where a refusal costs nothing. Later ticks are polls, and
2349
+ // re-gating them would burn two R2 reads each to re-derive an answer that cannot have changed.
2350
+ //
2351
+ // WHY NOT AN OUTPUT CAP, AND WHY NOT `MAX_CLIPS x MAX_CLIP_BYTES`: see src/assemble-admission.ts.
2352
+ // Short form: an output cap rejects after the whole film has been built, and that product is
2353
+ // measured 23x-120x above a real film (cf#813), so a gate written against it could never fire.
2354
+ const [measuredSecs, bundleDurations] = await Promise.all([
2355
+ measuredClipSeconds(env, job),
2356
+ readShotDurationsFromBundle(env, job.bundle_key),
2357
+ ]);
2358
+ const admission = admitAssemble({
2359
+ clipCount: finalClips.length,
2360
+ width: delivery.width,
2361
+ height: delivery.height,
2362
+ fps: DEFAULT_DELIVERY_FPS,
2363
+ basis: resolveAssembleSeconds(finalClips, measuredSecs, resolvePlannedSeconds(job.scenes, bundleDurations)),
2364
+ });
2365
+ if (!admission.admitted) {
2366
+ // TERMINAL and LOUD, never a degrade (cf#815, the #249/#77 discipline). Truncating the film to
2367
+ // something that fits would ship a different film than was asked for and call it done.
2368
+ emitStructuredEvent({
2369
+ ev: "assemble.refused",
2370
+ film_id: job.film_id,
2371
+ clips: finalClips.length,
2372
+ seconds: Math.round(admission.basis.seconds * 1000) / 1000,
2373
+ predicted_bytes: admission.predictedBytes,
2374
+ ceiling_bytes: admission.ceilingBytes,
2375
+ allowed_seconds: admission.allowedSeconds,
2376
+ basis: admission.basis,
2377
+ reason: admission.reason,
2378
+ });
2379
+ job.phase = "failed";
2380
+ job.error = admission.reason;
2381
+ return;
2382
+ }
2309
2383
  // ASSEMBLE_PRESIGN_TTL_SECONDS, not the old hardcoded 1800. Under chunked assemble batch N
2310
2384
  // downloads its clips only after batch N-1 has finished encoding, and the final pass reads
2311
2385
  // the FIRST partial at the very END of the job, so every URL here has to cover the whole