Use an exact Portal runtime manifest, remove retired media proof routes, and delete stale JPEG gate filters.
- commit
- 28d94b5185eb47c07c522c7438f1958ad0c8f097
- parent
- e388c67f80453c7d29b64f582411f9f04e1eab4d
- author
- Dami <dami.etoile@gmail.com>
| A | portal/ | 35 | ++++++++++++ |
| M | scripts/ | 90 | ++++++------------------------ |
| A | scripts/ | 75 | +++++++++++++++++++++++++ |
| M | scripts/ | 16 | ----- |
| M | src-tauri/ | 85 | ++++++++++++++++++---------- |
@@ -0,0 +1,35 @@
1+# Exact top-level files embedded in the signed Portal webview bundle.2+adaptive-feedback.mjs3+audio-envelope.mjs4+audio-pipeline.mjs5+audio-ring.mjs6+audio-ui.mjs7+audio-worklet.js8+av-sync.mjs9+codecs.js10+connection-attempt.mjs11+connection-state.mjs12+control-runtime.mjs13+controller-runtime.mjs14+controller-state.mjs15+decoder-recovery.mjs16+enrollment.mjs17+frame-envelope.mjs18+frame-session.mjs19+frame-stats.mjs20+index.html21+input-runtime.mjs22+input-state.mjs23+keyboard-map.mjs24+main.js25+network-diagnostics.mjs26+pointer-feedback.mjs27+stream-metrics.mjs28+stream-runtime.mjs29+style.css30+video-capability.mjs31+video-decoder-config.mjs32+video-format-transition.mjs33+video-pipeline.mjs34+window-geometry.mjs35+window-runtime.mjs@@ -21,8 +21,6 @@ keyframe_request_log="accepted MoQ keyframe request"
2121 session_gate_name="control"2222 keyframe_recovery="ok"2323 media_v3=false24-media_v2=false25-media_v1=false2624 relay_only=false2725 expected_path_mode=direct2826 @@ -43,10 +41,6 @@ Options:
4341 --probe-timeout-seconds SEC Probe per-operation timeout (default: 15)4442 --media-v3 Exercise custom grouped media v3 compatibility4543 instead of upstream MoQ46- --media-v2 Exercise independent media v2 compatibility47- instead of upstream MoQ48- --media-v1 Exercise ordered media v1 compatibility49- instead of upstream MoQ5044 --relay-only Remove direct probe transports and require the5145 control, media, and input paths to stay relayed5246 --help Show this help@@ -96,38 +90,12 @@ while [[ $# -gt 0 ]]; do
9690 probe_timeout_seconds="$2"9791 shift 29892 ;;99- --media-v1)100- [[ "$media_v2" == false && "$media_v3" == false ]] \101- || die "media compatibility flags cannot be combined"102- media_transport="reliable-v1"103- media_alpn="sigil/media/1"104- media_accept_log="media client accepted"105- media_release_log="media client released"106- session_gate_name="media"107- keyframe_recovery="not-requested"108- media_v1=true109- shift110- ;;11193 --relay-only)11294 relay_only=true11395 expected_path_mode=relay11496 shift11597 ;;116- --media-v2)117- [[ "$media_v1" == false && "$media_v3" == false ]] \118- || die "media compatibility flags cannot be combined"119- media_transport="independent-v2"120- media_alpn="sigil/media/2"121- media_accept_log="media v2 client accepted"122- media_release_log="media v2 client released"123- session_gate_name="media"124- keyframe_recovery="not-requested"125- media_v2=true126- shift127- ;;12898 --media-v3)129- [[ "$media_v1" == false && "$media_v2" == false ]] \130- || die "media compatibility flags cannot be combined"13199 media_transport="grouped-v3"132100 media_alpn="sigil/media/3"133101 media_accept_log="media v3 client accepted"@@ -160,12 +128,10 @@ require_positive_integer "--primary-frames" "$primary_frames"
160128 require_positive_integer "--reconnect-cycles" "$reconnect_cycles"161129 require_positive_integer "--reconnect-frames" "$reconnect_frames"162130 require_positive_integer "--probe-timeout-seconds" "$probe_timeout_seconds"163-if [[ "$media_v1" == false && "$media_v2" == false ]]; then164- [[ "$primary_frames" -ge 4 ]] \165- || die "--primary-frames must be at least 4 for keyframe recovery"166- [[ "$reconnect_frames" -ge 4 ]] \167- || die "--reconnect-frames must be at least 4 for keyframe recovery"168-fi131+[[ "$primary_frames" -ge 4 ]] \132+ || die "--primary-frames must be at least 4 for keyframe recovery"133+[[ "$reconnect_frames" -ge 4 ]] \134+ || die "--reconnect-frames must be at least 4 for keyframe recovery"169135 170136 # A fresh Iroh endpoint performs relay discovery and path establishment on171137 # every reconnect. Keep the default three-cycle proof fast, but scale the host@@ -412,9 +378,6 @@ validate_probe_log() {
412378 local log_path="$1"413379 local expected_frames="$2"414380 local expected_request_id="$3"415- if [[ "$media_v1" == true || "$media_v2" == true ]]; then416- expected_request_id="not-requested"417- fi418381 grep -Fxq 'probe=ok' "$log_path" || return 1419382 grep -Fxq "frames=${expected_frames}" "$log_path" || return 1420383 grep -Fxq 'dimensions=1280x800' "$log_path" || return 1@@ -488,11 +451,7 @@ run_probe() {
488451 if [[ "$relay_only" == true ]]; then489452 set -- --relay-only "$@"490453 fi491- if [[ "$media_v1" == true ]]; then492- "$probe_bin" --media-v1 "$@"493- elif [[ "$media_v2" == true ]]; then494- "$probe_bin" --media-v2 "$@"495- elif [[ "$media_v3" == true ]]; then454+ if [[ "$media_v3" == true ]]; then496455 "$probe_bin" --media-v3 "$@"497456 else498457 "$probe_bin" "$@"@@ -502,11 +461,7 @@ run_probe() {
502461 run_proof_probe() {503462 local request_id="$1"504463 shift505- if [[ "$media_v1" == false && "$media_v2" == false ]]; then506- run_probe --keyframe-smoke --keyframe-request-id "$request_id" "$@"507- else508- run_probe "$@"509- fi464+ run_probe --keyframe-smoke --keyframe-request-id "$request_id" "$@"510465 }511466 512467 cd "$workspace_dir"@@ -555,7 +510,7 @@ primary_probe_args=(
555510 --timeout-seconds "$probe_timeout_seconds"556511 --expect-size 1280x800557512 )558-if [[ "$media_v1" == false && "$media_v2" == false && "$media_v3" == false ]]; then513+if [[ "$media_v3" == false ]]; then559514 primary_probe_args+=(--slow-consumer-ms 1500)560515 fi561516 run_proof_probe 1 "${primary_probe_args[@]}" >"$primary_log" 2>&1 &@@ -602,10 +557,8 @@ validate_probe_log "$primary_log" "$primary_frames" 1 || {
602557 sed -n '1,240p' "$primary_log" >&2 || true603558 die "primary probe evidence is incomplete"604559 }605-if [[ "$media_v1" == false && "$media_v2" == false ]]; then606- wait_for_keyframe_request "$host_log" 1 "$host_pid" 'sigil' \607- || die "primary keyframe request was not accepted by the host"608-fi560+wait_for_keyframe_request "$host_log" 1 "$host_pid" 'sigil' \561+ || die "primary keyframe request was not accepted by the host"609562 610563 wait_for_log_count "$host_log" "$media_release_log" 1 "$host_pid" 'sigil' \611564 || die "primary session was not released"@@ -626,10 +579,8 @@ while [[ "$cycle" -le "$reconnect_cycles" ]]; do
626579 sed -n '1,240p' "$reconnect_log" >&2 || true627580 die "reconnect cycle $cycle evidence is incomplete"628581 }629- if [[ "$media_v1" == false && "$media_v2" == false ]]; then630- wait_for_keyframe_request "$host_log" "$reconnect_request_id" "$host_pid" 'sigil' \631- || die "reconnect cycle $cycle keyframe request was not accepted by the host"632- fi582+ wait_for_keyframe_request "$host_log" "$reconnect_request_id" "$host_pid" 'sigil' \583+ || die "reconnect cycle $cycle keyframe request was not accepted by the host"633584 wait_for_log_count "$host_log" "$media_release_log" "$((cycle + 1))" "$host_pid" 'sigil' \634585 || die "reconnect cycle $cycle was not released"635586 wait_for_log_count "$host_log" 'input client released' "$((cycle + 1))" "$host_pid" 'sigil' \@@ -637,15 +588,13 @@ while [[ "$cycle" -le "$reconnect_cycles" ]]; do
637588 cycle=$((cycle + 1))638589 done639590 640-if [[ "$media_v1" == false && "$media_v2" == false ]]; then641- request_id=1642- while [[ "$request_id" -le $((reconnect_cycles + 1)) ]]; do643- request_count="$(host_keyframe_request_count "$host_log" "$request_id")"644- [[ "$request_count" -eq 1 ]] \645- || die "keyframe request $request_id was accepted $request_count times; expected exactly once"646- request_id=$((request_id + 1))647- done648-fi591+request_id=1592+while [[ "$request_id" -le $((reconnect_cycles + 1)) ]]; do593+ request_count="$(host_keyframe_request_count "$host_log" "$request_id")"594+ [[ "$request_count" -eq 1 ]] \595+ || die "keyframe request $request_id was accepted $request_count times; expected exactly once"596+ request_id=$((request_id + 1))597+done649598 650599 kill -TERM "$host_pid" 2>/dev/null || true651600 if wait "$host_pid"; then@@ -672,8 +621,7 @@ printf 'probe_sha256=%s\n' "$(sha256_file "$probe_bin")"
672621 printf 'node_id=%s\n' "$node_id"673622 printf 'primary_frames=%s\n' "$primary_frames"674623 grep -E '^(transport|control_alpn|transport_alpn|first_configured_idr|frame_sequence|group_sequence|keyframe_recovery|keyframe_recovery_micros|keyframe_request_id|keyframes|sequence_gaps|media_objects_dropped|media_objects_late|moq_catalog|moq_group_capacity|moq_cancelled_groups|moq_group_gaps|moq_unrecovered_group_gaps|moq_maximum_group_objects|moq_maximum_group_bytes|moq_historical_suffix_frames|recovery_barrier|slow_consumer|slow_consumer_stall_ms|slow_consumer_first_post_stall|slow_consumer_historical_suffix_frames|slow_consumer_recovery_micros|slow_consumer_cancellation_delta|slow_consumer_group_advance|slow_consumer_sequence_advance|slow_consumer_capture_advance_micros|slow_consumer_input_ack_micros|input_ack_micros|path_mode|path_rtt_ms|control_path_mode|control_path_rtt_ms|media_path_mode|media_path_rtt_ms|input_path_mode|input_path_rtt_ms|forced_relay)=' "$primary_log"675-printf 'keyframe_request_correlation=%s\n' \676- "$([[ "$media_v1" == false && "$media_v2" == false ]] && printf unique || printf not-requested)"624+printf 'keyframe_request_correlation=unique\n'677625 printf 'active_client_rejection=ok\n'678626 printf 'reconnect_cycles=%s\n' "$reconnect_cycles"679627 printf 'cleanup=ok\n'@@ -0,0 +1,75 @@
1+2+3+set -euo pipefail4+5+script_dir="$(CDPATH='' cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"6+repo_dir="$(CDPATH='' cd -- "$script_dir/../.." && pwd -P)"7+source_dir="$repo_dir/portal"8+dist_dir="$repo_dir/portal-dist"9+manifest="$source_dir/runtime-files.txt"10+fixture_name="unlisted-runtime-payload-fixture.mjs"11+fixture_source="$source_dir/$fixture_name"12+fixture_dist="$dist_dir/$fixture_name"13+fixture_dir="$dist_dir/unlisted-runtime-payload-fixture"14+temp_parent="${TMPDIR:-/tmp}"15+temp_parent="${temp_parent%/}"16+temp_root="$(mktemp -d "$temp_parent/goq-portal-runtime-payload.XXXXXX")"17+18+cleanup() {19+ local exit_status=$?20+ trap - EXIT INT TERM HUP21+ rm -f -- "$fixture_source" "$fixture_dist"22+ case "$fixture_dir" in23+ "$dist_dir"/unlisted-runtime-payload-fixture)24+ rm -rf -- "$fixture_dir"25+ ;;26+ esac27+ case "$temp_root" in28+ "$temp_parent"/goq-portal-runtime-payload.??????)29+ rm -rf -- "$temp_root"30+ ;;31+ esac32+ exit "$exit_status"33+}34+trap cleanup EXIT INT TERM HUP35+36+if [[ -L "$manifest" || ! -f "$manifest" ]]; then37+ printf 'portal runtime payload manifest must be a regular file: %s\n' "$manifest" >&238+ exit 139+fi40+41+printf 'export const shouldNotShip = true;\n' >"$fixture_source"42+mkdir -p "$fixture_dir"43+printf 'stale\n' >"$fixture_dist"44+printf 'stale\n' >"$fixture_dir/stale.test.mjs"45+46+if [[ -f "${HOME}/.cargo/env" ]]; then47+ # shellcheck source=/dev/null48+ source "${HOME}/.cargo/env"49+fi50+cargo check --locked -p portal --quiet51+52+if [[ -e "$fixture_dist" || -e "$fixture_dir" ]]; then53+ printf 'portal build retained an unallowlisted generated payload entry\n' >&254+ exit 155+fi56+57+sed -e '/^[[:space:]]*#/d' -e '/^[[:space:]]*$/d' "$manifest" \58+ | LC_ALL=C sort >"$temp_root/expected"59+find "$dist_dir" -mindepth 1 -maxdepth 1 -type f -exec basename {} \; \60+ | LC_ALL=C sort >"$temp_root/actual"61+cmp "$temp_root/expected" "$temp_root/actual"62+63+while IFS= read -r -d '' entry; do64+ if [[ -L "$entry" || ! -f "$entry" ]]; then65+ printf 'portal-dist contains a non-regular entry: %s\n' "$entry" >&266+ exit 167+ fi68+done < <(find "$dist_dir" -mindepth 1 -maxdepth 1 -print0)69+70+if find "$dist_dir" -type f -name '*.test.mjs' -print -quit | grep -q .; then71+ printf 'portal-dist contains a test suite\n' >&272+ exit 173+fi74+75+printf 'portal_runtime_payload_tests=ok\n'@@ -131,22 +131,6 @@ cargo test --locked -p portal --release \
131131 commands::state::tests::ordinary_release_excludes_direct_node_bypass \132132 -- --exact133133 134-cargo test --locked -p portal --release \135- commands::state::tests::rejects_force_jpeg_when_debug_mode_is_disabled \136- -- --exact137-138-cargo test --locked -p portal --release \139- commands::state::tests::ordinary_release_excludes_force_jpeg_override \140- -- --exact141-142-cargo test --locked -p portal --release \143- commands::state::tests::app_state_accepts_force_jpeg_only_in_debug_builds \144- -- --exact145-146-cargo test --locked -p portal --release --features demo-direct-node \147- commands::state::tests::app_state_accepts_force_jpeg_only_in_debug_builds \148- -- --exact149-150134 cargo test --locked -p portal --release --features demo-direct-node \151135 commands::state::tests::app_state_accepts_direct_node_only_in_debug_builds \152136 -- --exact@@ -1,7 +1,9 @@
11 use std::collections::BTreeSet;22 use std::env;33 use std::fs;4-use std::path::Path;4+use std::path::{Component, Path};5+6+const PORTAL_PAYLOAD_MANIFEST: &str = "runtime-files.txt";57 68 fn main() {79 assemble_portal_dist();@@ -23,37 +25,46 @@ fn assemble_portal_dist() {
2325 let source_dir = Path::new(&manifest_dir).join("../portal");2426 let dist_dir = Path::new(&manifest_dir).join("../portal-dist");2527 26- // Fixed, non-module runtime entry points. Anything not matched here or by27- // the module sweep below does not ship.28- let mut wanted: BTreeSet<String> = [29- "index.html",30- "style.css",31- "main.js",32- "codecs.js",33- "audio-worklet.js",34- ]35- .iter()36- .map(|name| (*name).to_string())37- .collect();38- for name in &wanted {39- if !source_dir.join(name).is_file() {40- panic!("allowlisted portal payload file is missing: {name}");41- }42- }43-44- // Every top-level ES module except test suites.45- for entry in fs::read_dir(&source_dir).expect("portal source directory must exist") {46- let entry = entry.expect("readable portal source entry");47- let is_file = entry48- .file_type()49- .map(|kind| kind.is_file())50- .unwrap_or(false);51- if !is_file {28+ let manifest_path = source_dir.join(PORTAL_PAYLOAD_MANIFEST);29+ let manifest = fs::read_to_string(&manifest_path)30+ .expect("portal runtime payload manifest must be readable");31+ let mut wanted = BTreeSet::new();32+ for (line_index, raw_name) in manifest.lines().enumerate() {33+ let line_number = line_index + 1;34+ let name = raw_name.trim();35+ if name.is_empty() || name.starts_with('#') {5236 continue;5337 }54- let name = entry.file_name().to_string_lossy().into_owned();55- if name.ends_with(".mjs") && !name.ends_with(".test.mjs") {56- wanted.insert(name);38+ if name != raw_name {39+ panic!("portal runtime payload manifest line {line_number} has surrounding whitespace");40+ }41+ let path = Path::new(name);42+ if !matches!(43+ path.components().collect::<Vec<_>>().as_slice(),44+ [Component::Normal(_)]45+ ) {46+ panic!(47+ "portal runtime payload manifest line {line_number} is not one top-level file: {name}"48+ );49+ }50+ if name.ends_with(".test.mjs") {51+ panic!(52+ "portal runtime payload manifest line {line_number} includes a test suite: {name}"53+ );54+ }55+ if !wanted.insert(name.to_owned()) {56+ panic!("portal runtime payload manifest repeats {name}");57+ }58+ }59+ if wanted.is_empty() {60+ panic!("portal runtime payload manifest must name at least one file");61+ }62+ for name in &wanted {63+ let metadata = fs::symlink_metadata(source_dir.join(name)).unwrap_or_else(|error| {64+ panic!("allowlisted portal payload file {name} is missing: {error}")65+ });66+ if !metadata.file_type().is_file() {67+ panic!("allowlisted portal payload file is missing: {name}");5768 }5869 }5970 @@ -72,10 +83,22 @@ fn assemble_portal_dist() {
7283 let entry = entry.expect("readable portal-dist entry");7384 let name = entry.file_name().to_string_lossy().into_owned();7485 if !wanted.contains(&name) {75- let _ = fs::remove_file(entry.path());86+ let file_type = entry87+ .file_type()88+ .expect("portal-dist entry type is readable");89+ if file_type.is_dir() {90+ fs::remove_dir_all(entry.path()).unwrap_or_else(|error| {91+ panic!("failed to prune portal-dist directory {name}: {error}")92+ });93+ } else {94+ fs::remove_file(entry.path()).unwrap_or_else(|error| {95+ panic!("failed to prune portal-dist file {name}: {error}")96+ });97+ }7698 }7799 }78100 79101 // Watch the directory itself so added or removed source files re-run this.102+ println!("cargo:rerun-if-changed=../portal/{PORTAL_PAYLOAD_MANIFEST}");80103 println!("cargo:rerun-if-changed=../portal");81104 }