diff --git a/SKILL.md b/SKILL.md index 52f2a29..e51a648 100644 --- a/SKILL.md +++ b/SKILL.md @@ -223,8 +223,21 @@ Look for: - pairing flow strings - device type names or codenames - reservation flow allowlists and package IDs +- Steam client ARM64 beta/publicbeta manifest movement, especially `steam_client_beta_linuxarm64` - support or OOBE changes +Client manifest focus: + +- Treat `steam_client_beta_linuxarm64` as a high-signal Steam Machine / Fremont watch target. +- Track `steam_client_publicbeta_linuxarm64` beside it so beta-to-publicbeta movement is visible. +- Watch ARM64 hardware/runtime blocks, especially: + - `bins_hardware_linuxarm64` + - `bins_linuxarm64` + - `steam_linuxarm64` + - `runtime_steamrt_linuxarm64` + - `bins_steamrt_linuxarm64` +- Manifest movement is a readiness heuristic only. It does not confirm product identity, preorder timing, or launch readiness without SteamKit/PICS or Valve public API movement. + Known reservation-package code baseline: - Machine package IDs `1629446`, `1629447`, `1629458`, `1629460` and Frame package IDs `1629484`, `1629486` first appear in SteamTracking bundle snapshots at commit `334bd31a28a0` on `2026-04-28T23:46:34Z` diff --git a/references/sources.md b/references/sources.md index b90967c..70f1345 100644 --- a/references/sources.md +++ b/references/sources.md @@ -130,6 +130,17 @@ High-yield files from the seeded baseline: - `Protobufs/steammessages_clientsettings.proto` - `steamcommunity.com/public/javascript/webui/friends.js` - `Strings/steamclient.txt` +- `ClientManifest/steam_client_beta_linuxarm64` +- `ClientManifest/steam_client_publicbeta_linuxarm64` +- `ClientManifest/steamdeck_publicbeta` + +Steam client manifest blocks to watch: + +- `bins_hardware_linuxarm64` +- `bins_linuxarm64` +- `steam_linuxarm64` +- `runtime_steamrt_linuxarm64` +- `bins_steamrt_linuxarm64` Useful search terms: diff --git a/scripts/check_steamtracking.sh b/scripts/check_steamtracking.sh index a59d340..79fa370 100755 --- a/scripts/check_steamtracking.sh +++ b/scripts/check_steamtracking.sh @@ -9,6 +9,7 @@ fi RUN_DIR="$1" TRACKING_DIR="${2:-/tmp/SteamTracking-master}" OUT_DIR="$RUN_DIR/reports" +SCRIPT_DIR="$(CDPATH= cd -- "$(dirname "$0")" && pwd)" mkdir -p "$OUT_DIR" if [ ! -d "$TRACKING_DIR" ]; then @@ -24,6 +25,11 @@ rg -n -i "ShouldTritonPairInOobe|PairDongleTriton|UnpairedTriton|ibex_internal|i "$TRACKING_DIR" \ > "$OUT_DIR/steamtracking-pairing-focus.txt" || true +python3 "$SCRIPT_DIR/parse_steamtracking_client_manifests.py" \ + --run-dir "$RUN_DIR" \ + --tracking-dir "$TRACKING_DIR" + printf '%s\n' \ "Saved SteamTracking grep output to $OUT_DIR/steamtracking-hits.txt" \ - "Saved pairing-focused grep output to $OUT_DIR/steamtracking-pairing-focus.txt" + "Saved pairing-focused grep output to $OUT_DIR/steamtracking-pairing-focus.txt" \ + "Saved client manifest report to $OUT_DIR/steamtracking-client-manifests.md" diff --git a/scripts/compare_runs.py b/scripts/compare_runs.py index aaa2801..6c25563 100755 --- a/scripts/compare_runs.py +++ b/scripts/compare_runs.py @@ -124,6 +124,7 @@ def build_summary(prev_dir: Path, curr_dir: Path): deltas.extend(compare_report_sets(prev_dir, curr_dir, "Komodo frame media", "komodo-frame-media.tsv")) deltas.extend(compare_text_lines(prev_dir, curr_dir, "SteamKit/PICS", "steamkit-pics-key-lines.txt")) deltas.extend(compare_text_lines(prev_dir, curr_dir, "SteamDB", "steamdb-key-lines.txt")) + deltas.extend(compare_text_lines(prev_dir, curr_dir, "Steam client manifests", "steamtracking-client-manifests-key-lines.txt")) deltas.extend(compare_text_lines(prev_dir, curr_dir, "SteamVR depots", "steamvr-depots-key-lines.txt")) deltas.extend(compare_text_lines(prev_dir, curr_dir, "SteamOS mirror", "steamos-mirror-key-lines.txt")) deltas.extend(compare_text_lines(prev_dir, curr_dir, "Valve endpoint", "valve-key-lines.txt")) diff --git a/scripts/draft_status_update.py b/scripts/draft_status_update.py index e0a632d..e60097d 100755 --- a/scripts/draft_status_update.py +++ b/scripts/draft_status_update.py @@ -50,6 +50,9 @@ def build_draft(run_dir: Path): steamdb_lines = first_n_nonempty(reports / "steamdb-key-lines.txt", 8) valve_lines = first_n_nonempty(reports / "valve-key-lines.txt", 8) tracking_lines = first_n_nonempty(reports / "steamtracking-pairing-focus.txt", 8) + client_manifest_lines = first_n_nonempty( + reports / "steamtracking-client-manifests-key-lines.txt", 8 + ) steamvr_lines = first_n_nonempty(reports / "steamvr-depots-key-lines.txt", 8) steamos_lines = first_n_nonempty(reports / "steamos-mirror-key-lines.txt", 8) customs_key_lines_path = reports / "customs-shipments-key-lines.txt" @@ -127,6 +130,9 @@ def build_draft(run_dir: Path): lines.extend([f"- `{line}`" for line in tracking_lines]) else: lines.append("- No focused SteamTracking report found.") + if client_manifest_lines: + lines.extend(["", "Steam client manifest focus:"]) + lines.extend([f"- `{line}`" for line in client_manifest_lines]) lines.extend(["", "#### SteamVR Depots"]) if steamvr_blocked: diff --git a/scripts/parse_steamtracking_client_manifests.py b/scripts/parse_steamtracking_client_manifests.py new file mode 100644 index 0000000..20af311 --- /dev/null +++ b/scripts/parse_steamtracking_client_manifests.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python3 +import argparse +import csv +import re +import shutil +from pathlib import Path + + +WATCHED_MANIFESTS = ( + "steam_client_beta_linuxarm64", + "steam_client_publicbeta_linuxarm64", + "steam_client_publicbeta_ubuntu12", + "steam_client_publicbeta_win64", + "steam_client_publicbeta_osx", + "steamdeck_publicbeta", + "steam_client_win64", + "steam_client_ubuntu12", + "steam_client_osx", + "steamdeck_stable", +) + +FOCUS_BLOCKS = ( + "bins_hardware_linuxarm64", + "bins_linuxarm64", + "steam_linuxarm64", + "runtime_steamrt_linuxarm64", + "bins_steamrt_linuxarm64", + "bins_codecs_linuxarm64", + "bins_misc_linuxarm64", + "webkit_linuxarm64", + "sdl3_linuxarm64", + "bins_hardware_all", +) + +OUTPUT_FIELDS = ( + "manifest", + "arch", + "version", + "block", + "file", + "size", + "sha2", + "changed_since_previous", + "previous_version", + "previous_file", + "previous_size", + "previous_sha2", +) + + +def parse_manifest(path: Path): + text = path.read_text(encoding="utf-8", errors="ignore") + arch_match = re.match(r'\s*"([^"]+)"', text) + version_match = re.search(r'"version"\s+"([^"]+)"', text) + blocks = {} + current = None + for line in text.splitlines(): + block_match = re.match(r'\s*"([^"]+)"\s*$', line) + if block_match: + current = block_match.group(1) + blocks[current] = {} + continue + if current: + field_match = re.match(r'\s*"([^"]+)"\s+"([^"]*)"', line) + if field_match: + blocks[current][field_match.group(1)] = field_match.group(2) + return { + "arch": arch_match.group(1) if arch_match else "", + "version": version_match.group(1) if version_match else "", + "blocks": blocks, + } + + +def find_previous_report(run_dir: Path): + parent = run_dir.parent + if not parent.exists(): + return None + previous = None + for candidate in sorted(parent.glob("????-??-??")): + if candidate == run_dir: + continue + if candidate.name < run_dir.name: + previous = candidate + if not previous: + return None + path = previous / "reports" / "steamtracking-client-manifests.tsv" + return path if path.exists() else None + + +def load_previous(path: Path | None): + if not path or not path.exists(): + return {} + with path.open(encoding="utf-8", newline="") as handle: + reader = csv.DictReader(handle, delimiter="\t") + return {(row["manifest"], row["block"]): row for row in reader} + + +def changed(row, previous): + prior = previous.get((row["manifest"], row["block"])) + if not prior: + return "new" + if row["block"] == "__manifest__": + return "yes" if row["version"] != prior.get("version", "") else "no" + for field in ("file", "size", "sha2"): + if row[field] != prior.get(field, ""): + return "yes" + return "no" + + +def build_rows(tracking_dir: Path, previous): + manifest_dir = tracking_dir / "ClientManifest" + rows = [] + for manifest in WATCHED_MANIFESTS: + path = manifest_dir / manifest + if not path.exists(): + continue + parsed = parse_manifest(path) + manifest_row = { + "manifest": manifest, + "arch": parsed["arch"], + "version": parsed["version"], + "block": "__manifest__", + "file": "", + "size": "", + "sha2": "", + "changed_since_previous": "", + "previous_version": "", + "previous_file": "", + "previous_size": "", + "previous_sha2": "", + } + prior = previous.get((manifest, "__manifest__"), {}) + manifest_row["previous_version"] = prior.get("version", "") + manifest_row["changed_since_previous"] = changed(manifest_row, previous) + rows.append(manifest_row) + + for block in FOCUS_BLOCKS: + values = parsed["blocks"].get(block) + if not values: + continue + row = { + "manifest": manifest, + "arch": parsed["arch"], + "version": parsed["version"], + "block": block, + "file": values.get("file", ""), + "size": values.get("size", ""), + "sha2": values.get("sha2", ""), + "changed_since_previous": "", + "previous_version": "", + "previous_file": "", + "previous_size": "", + "previous_sha2": "", + } + prior = previous.get((manifest, block), {}) + row["previous_version"] = prior.get("version", "") + row["previous_file"] = prior.get("file", "") + row["previous_size"] = prior.get("size", "") + row["previous_sha2"] = prior.get("sha2", "") + row["changed_since_previous"] = changed(row, previous) + rows.append(row) + return rows + + +def write_tsv(rows, path: Path): + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("w", encoding="utf-8", newline="") as handle: + writer = csv.DictWriter(handle, fieldnames=OUTPUT_FIELDS, delimiter="\t") + writer.writeheader() + writer.writerows(rows) + + +def write_key_lines(rows, path: Path): + focus_manifests = {"steam_client_beta_linuxarm64", "steam_client_publicbeta_linuxarm64"} + focus_blocks = {"__manifest__", "bins_hardware_linuxarm64", "bins_linuxarm64", "steam_linuxarm64", "runtime_steamrt_linuxarm64"} + lines = [] + for row in rows: + if row["manifest"] not in focus_manifests or row["block"] not in focus_blocks: + continue + if row["block"] == "__manifest__": + lines.append( + f"{row['manifest']} version={row['version']} arch={row['arch']} changed={row['changed_since_previous']} previous={row['previous_version']}" + ) + else: + lines.append( + f"{row['manifest']} block={row['block']} version={row['version']} file={row['file']} size={row['size']} changed={row['changed_since_previous']} previous_file={row['previous_file']}" + ) + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text("\n".join(lines) + ("\n" if lines else ""), encoding="utf-8") + + +def write_markdown(rows, path: Path): + lines = [ + "# SteamTracking Client Manifests", + "", + "Focused Steam client channel manifest snapshot for ARM64 and hardware package movement.", + "", + "| Manifest | Arch | Version | Block | File | Size | Changed |", + "| --- | --- | --- | --- | --- | ---: | --- |", + ] + for row in rows: + if row["manifest"] not in ("steam_client_beta_linuxarm64", "steam_client_publicbeta_linuxarm64"): + continue + lines.append( + "| " + + " | ".join( + ( + row["manifest"], + row["arch"], + row["version"], + row["block"], + row["file"], + row["size"], + row["changed_since_previous"], + ) + ) + + " |" + ) + lines.extend( + [ + "", + "## Interpretation", + "", + "- `steam_client_beta_linuxarm64` is high signal for possible ARM64 Steam hardware monitoring.", + "- `bins_hardware_linuxarm64`, `steam_linuxarm64`, and Steam Runtime ARM64 blocks are the highest-value fields.", + "- Manifest movement is not launch confirmation without Valve store/package readiness.", + "", + ] + ) + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text("\n".join(lines), encoding="utf-8") + + +def copy_raw_manifests(tracking_dir: Path, output_dir: Path): + source_dir = tracking_dir / "ClientManifest" + output_dir.mkdir(parents=True, exist_ok=True) + for manifest in WATCHED_MANIFESTS: + source = source_dir / manifest + if source.exists(): + shutil.copyfile(source, output_dir / manifest) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--run-dir", required=True, type=Path) + parser.add_argument("--tracking-dir", required=True, type=Path) + parser.add_argument("--previous-report", type=Path) + args = parser.parse_args() + + reports = args.run_dir / "reports" + raw_dir = args.run_dir / "api" / "steamtracking" / "client-manifests" + previous = load_previous(args.previous_report or find_previous_report(args.run_dir)) + rows = build_rows(args.tracking_dir, previous) + copy_raw_manifests(args.tracking_dir, raw_dir) + write_tsv(rows, reports / "steamtracking-client-manifests.tsv") + write_key_lines(rows, reports / "steamtracking-client-manifests-key-lines.txt") + write_markdown(rows, reports / "steamtracking-client-manifests.md") + + +if __name__ == "__main__": + main() diff --git a/scripts/write_run_summary.py b/scripts/write_run_summary.py index 77e0410..579fcca 100755 --- a/scripts/write_run_summary.py +++ b/scripts/write_run_summary.py @@ -153,6 +153,7 @@ def build(run_dir: Path): notable.extend([f"- SteamKit/PICS: `{line}`" for line in filtered_first(reports / "steamkit-pics-key-lines.txt", 8)]) notable.extend([f"- SteamDB: `{line}`" for line in filtered_first(reports / "steamdb-key-lines.txt", 5)]) notable.extend([f"- SteamTracking: `{line}`" for line in filtered_first(reports / "steamtracking-pairing-focus.txt", 5)]) + notable.extend([f"- Steam client manifests: `{line}`" for line in filtered_first(reports / "steamtracking-client-manifests-key-lines.txt", 8)]) notable.extend([f"- SteamVR depots: `{line}`" for line in filtered_first(reports / "steamvr-depots-key-lines.txt", 5)]) notable.extend([f"- SteamOS mirror: `{line}`" for line in filtered_first(reports / "steamos-mirror-key-lines.txt", 5)]) notable.extend([f"- Valve: `{line}`" for line in filtered_first(reports / "valve-key-lines.txt", 5)]) diff --git a/status/current.md b/status/current.md index da2d40b..4b64a4b 100644 --- a/status/current.md +++ b/status/current.md @@ -1,6 +1,6 @@ # Steam Hardware Watch Status -Last updated: `2026-05-22` +Last updated: `2026-05-23` ## Best Current Answer @@ -12,8 +12,8 @@ Last updated: `2026-05-22` ### Komodo -- Komodo was available again on `2026-05-22` through the dedicated browser fallback after the `2026-05-19` waiting-room block. -- Product modified timestamps captured in this run: +- Komodo was available again on `2026-05-23` through the dedicated browser fallback after the automated path initially blocked. +- Product modified timestamps captured in this run remain unchanged versus `2026-05-22`: - Controller: `2026-05-22T15:28:27` - Machine: `2026-04-24T14:32:54` - Frame: `2026-04-24T14:33:36` @@ -24,7 +24,7 @@ Last updated: `2026-05-22` ### SteamKit / PICS - SteamKit/PICS is the primary direct Steam metadata source for watched app and package movement. -- Current changenumbers from the `2026-05-22` run: +- Current changenumbers from the `2026-05-23` run: - Controller app `4165870`: `35731145` - Frame app `4165890`: `35675573` - Machine app `4165910`: `35675573` @@ -34,30 +34,35 @@ Last updated: `2026-05-22` - Machine package `1629458`: `35842860` - Machine package `1629460`: `35842863` - Frame packages `1629484`, `1629486`: `35672606` -- No watched SteamKit/PICS changenumbers moved on `2026-05-22`. +- No watched SteamKit/PICS changenumbers moved on `2026-05-23`. - The latest Controller package signal remains the `2026-05-17` private PICS change on package `1558609`, where `ignorereservationifstockavailable=1` was removed from the package `extended` fields. Public Valve `appdetails` / `packagedetails` still did not change. - The latest material Machine signal remains the `2026-05-14` follow-up bump across all four watched Steam Machine package IDs, especially because the two watched Steam Frame package IDs did not move. - Manual package-history context remains important: Steam Controller package `1558609` reportedly had a clustered change pattern plus one later follow-up change roughly two days before Valve's public purchase-timing update appeared. The Machine set now has both the initial multi-package cluster and the later follow-up bump. Treat this as a stronger imminent-preorder heuristic, not confirmation. - Machine and Frame apps/packages currently require private PICS metadata tokens, but changenumbers are visible and suitable for movement monitoring. -- Raw snapshot: `/Users/sean/Coding/steam-hardware-watch/runs/2026-05-22/api/steamkit/pics-product-info.json` -- Human-readable detail: `/Users/sean/Coding/steam-hardware-watch/runs/2026-05-22/reports/steamkit-pics-detail.md` +- Raw snapshot: `/Users/sean/Coding/steam-hardware-watch/runs/2026-05-23/api/steamkit/pics-product-info.json` +- Human-readable detail: `/Users/sean/Coding/steam-hardware-watch/runs/2026-05-23/reports/steamkit-pics-detail.md` ### SteamDB -- Automated SteamDB access remained blocked on `2026-05-22`. +- Automated SteamDB access remained blocked on `2026-05-23`. - The package report is still a structural baseline, not a content baseline: all watched SteamDB package rows are `missing_or_blocked`. - SteamDB remains useful as corroborating/human-readable metadata once a trusted browser session can pass the challenge, but SteamKit/PICS now covers primary package movement. ### SteamTracking / GameTracking -- Fresh SteamTracking content at commit `28f5287` (`2026-05-22T04:56:58Z`) still contains the known Triton/Ibex controller pairing surface: +- Fresh SteamTracking content at commit `5f58a47` (`2026-05-23T04:32:36Z`) still contains the known Triton/Ibex controller pairing surface: - `ibex_internal` - `ibex_external` - `PairDongleTritonConnected` - `PairDongleTritonDocked` - `ShouldTritonPairInOobe` - Known reservation package-code baseline remains: Machine package IDs `1629446`, `1629447`, `1629458`, `1629460` and Frame package IDs `1629484`, `1629486` first appeared in SteamTracking commit `334bd31a28a0` at `2026-04-28T23:46:34Z`. -- No new price or exact availability signal was found in this run. +- New high-signal client manifest watch target: `steam_client_beta_linuxarm64` first appeared in the local SteamTracking baseline at commit `28f5287` (`2026-05-22T04:56:58Z`) with version `1779139477`. +- Track `steam_client_beta_linuxarm64` and `steam_client_publicbeta_linuxarm64` every run, especially `bins_hardware_linuxarm64`, `bins_linuxarm64`, `steam_linuxarm64`, `runtime_steamrt_linuxarm64`, and `bins_steamrt_linuxarm64`. +- Current ARM64 client manifest baseline in the `2026-05-23` report: + - `steam_client_beta_linuxarm64`: version `1779139477`; `bins_hardware_linuxarm64.zip.cc71be587407299a6125bfa9e889b97bf8df7591`; size `7590487`. + - `steam_client_publicbeta_linuxarm64`: version `1779479049`; `bins_hardware_linuxarm64.zip.da8814f3cc3788fd3789ce233dd86f107b2b244a`; size `10039405`. +- The updated SteamTracking checkout did not add a new Machine/Frame reservation package, price, exact availability, or product-publication signal. ### SteamVR Depots @@ -84,8 +89,9 @@ Last updated: `2026-05-22` ### Customs / Regulatory -- Customs status on `2026-05-22`: partial. ImportInfo automated fetches were blocked, but the ImportGenius importer page fetched and parsed successfully. +- Customs status on `2026-05-23`: partial. ImportInfo automated fetches were blocked, but the ImportGenius importer page fetched and parsed successfully. - ImportGenius now lists `10` relevant `GAME CONSOLE` rows for `INGRAM MICRO C/O VALVE CORPORATION` from `2026-03-27` through `2026-05-18`. +- No newer customs rows appeared versus the `2026-05-22` ImportGenius baseline. - Newer rows since the old `2026-04-23` baseline include: - `SNHBSHACHI265020`, arrived `2026-05-18`, `42 PKG`, `14353 Kgs`. - `SNHBSHACHI264140`, arrived `2026-05-18`, `42 PKG`, `14533 Kgs`. diff --git a/status/evidence.jsonl b/status/evidence.jsonl index 11c703c..8bbd561 100644 --- a/status/evidence.jsonl +++ b/status/evidence.jsonl @@ -43,3 +43,4 @@ {"date_checked": "2026-05-14", "source": "steamkit-pics", "entity": "steam-machine", "claim": "SteamKit/PICS shows a second follow-up changenumber bump across all four watched Steam Machine reservation package IDs.", "evidence_type": "steam_product_info_followup_changenumber_delta", "confidence": "high", "ref": "/Users/sean/Coding/steam-hardware-watch/runs/2026-05-14/reports/steamkit-pics-detail.md", "notes": "Machine packages 1629446, 1629447, 1629458, and 1629460 moved from 35819604/35819607/35819602/35819593 on 2026-05-12 to 35842876/35842851/35842860/35842863 on 2026-05-14. Frame packages 1629484 and 1629486 stayed at 35672606, and public Valve appdetails/packagedetails still expose no Machine packages, package groups, price, or exact timing."} {"date_checked": "2026-05-17", "source": "steamkit-pics", "entity": "steam-controller", "claim": "SteamKit/PICS shows Steam Controller package 1558609 moved and removed an ignore-reservation-if-stock-available flag.", "evidence_type": "steam_product_info_package_field_delta", "confidence": "high", "ref": "/Users/sean/Coding/steam-hardware-watch/runs/2026-05-17/reports/steamkit-pics-detail.md", "notes": "Controller package 1558609 moved from changenumber 35745078 to 35893035 and changed SHA from 02235CA28137E71E7AFA02A0F45743DBEBA925EF to CE75692F2679EF8A91C3C9CBB58D09456350EC64. The available PICS KeyValues diff shows extended field ignorereservationifstockavailable=1 was removed. Public Valve appdetails/packagedetails were unchanged, and watched Machine and Frame package changenumbers did not move."} {"date_checked": "2026-05-22", "source": "importgenius-customs", "entity": "steam-machine,steam-frame", "claim": "ImportGenius shows continued US-bound GAME CONSOLE shipments to Ingram Micro C/O Valve Corporation through May 18, 2026.", "evidence_type": "customs_import_record", "confidence": "medium", "ref": "/Users/sean/Coding/steam-hardware-watch/runs/2026-05-22/reports/customs-shipments.md", "notes": "Parsed 10 relevant ImportGenius rows for INGRAM MICRO C/O VALVE CORPORATION / TECH-FRONT (CHONGQING) COMPUTER CO. Newer rows since the April 23 baseline include May 18 BOLs SNHBSHACHI265020 and SNHBSHACHI264140 plus May 8 BOL SNHBSHACHI264031. Customs rows say GAME CONSOLE but do not identify the specific Valve hardware SKU."} +{"date_checked": "2026-05-23", "source": "steamtracking-client-manifest", "entity": "steam-machine", "claim": "SteamTracking now exposes a dedicated steam_client_beta_linuxarm64 client manifest suitable for ARM64 Steam hardware monitoring.", "evidence_type": "client_manifest_baseline", "confidence": "medium", "ref": "/Users/sean/Coding/steam-hardware-watch/runs/2026-05-23/reports/steamtracking-client-manifests.md", "notes": "Manifest steam_client_beta_linuxarm64 first appears in the local SteamTracking history at commit 28f5287 on 2026-05-22T04:56:58Z with version 1779139477. The watcher now tracks beta/publicbeta linuxarm64 manifests and key blocks including bins_hardware_linuxarm64, bins_linuxarm64, steam_linuxarm64, runtime_steamrt_linuxarm64, and bins_steamrt_linuxarm64. This is a high-signal ARM64/Fremont readiness heuristic, not product identity or launch confirmation."} diff --git a/status/runs/2026-05-23.md b/status/runs/2026-05-23.md new file mode 100644 index 0000000..e8f5360 --- /dev/null +++ b/status/runs/2026-05-23.md @@ -0,0 +1,102 @@ +# Run Note: 2026-05-23 + +## Summary + +- Full skill run completed with artifacts under `/Users/sean/Coding/steam-hardware-watch/runs/2026-05-23`. +- No watched SteamKit/PICS changenumbers moved versus the `2026-05-22` report. +- Valve public APIs still do not expose Steam Machine or Steam Frame package groups, public package details, price, exact release timing, or purchase/reservation readiness. +- Komodo initially blocked on the automated path, then recovered through the dedicated browser fallback. Product timestamps and section baselines are unchanged versus `2026-05-22`. +- SteamTracking was updated to commit `5f58a47` (`2026-05-23T04:32:36Z`). Known Triton/Ibex pairing strings remain present, but no new Machine/Frame launch signal was found. +- Customs remains a partial source: ImportInfo blocked, ImportGenius fetched successfully, and the latest relevant `GAME CONSOLE` rows remain the `2026-05-18` shipments. + +## Source Checks + +### Komodo + +- Dedicated browser fallback recovered Controller, Machine, and Frame product/section data. +- Product modified timestamps: + - Controller: `2026-05-22T15:28:27` + - Machine: `2026-04-24T14:32:54` + - Frame: `2026-04-24T14:33:36` +- No new Machine or Frame sections appeared. Machine and Frame still expose the old wishlist section baseline. +- Visual assets: `141` discovered, `136` retrieved, `5` blocked known Komodo URLs. + +### SteamKit / PICS + +- SteamKit/PICS completed successfully. +- No watched app or package changenumbers moved versus `2026-05-22`. +- Controller package `1558609` stayed at `35893035`. +- Machine packages stayed unchanged: + - `1629446`: `35842876` + - `1629447`: `35842851` + - `1629458`: `35842860` + - `1629460`: `35842863` +- Frame packages stayed unchanged: + - `1629484`: `35672606` + - `1629486`: `35672606` +- Interpretation: today's run does not add a new Controller, Machine, or Frame PICS signal. The latest material Machine signal remains the `2026-05-14` follow-up bump across all four watched Machine package IDs. + +### SteamDB + +- Automated SteamDB access remained blocked. +- Reservation package rows remain `missing_or_blocked`, so SteamDB is still not a human-readable corroborating baseline for recent package-history movement. + +### SteamTracking / GameTracking + +- Updated `/tmp/SteamTracking-master` from `28f5287` to `5f58a47`. +- The latest commit summary is `8 files | steam_client_osx, steam_client_ubuntu12, steam_client_win64, steam_cmd_linux, steam_cmd_osx, steam_cmd_win64, steamchina_win64, steamdeck_stable`. +- Known Triton/Ibex pairing surfaces remain present. +- Added focused Steam client manifest monitoring to the normal watcher. +- `steam_client_beta_linuxarm64` is now tracked as a high-signal ARM64/Fremont watch target. Baseline: + - version `1779139477` + - `bins_hardware_linuxarm64.zip.cc71be587407299a6125bfa9e889b97bf8df7591` + - `bins_linuxarm64.zip.37968ebfba6404c03b92ebe8a4c6083bff4b6ff0` + - `steam_linuxarm64.zip.406e533ed3218787b6d548ecf9e316bca01494ce` + - `runtime_steamrt_linuxarm64.zip.b41880f37f2c30fe064f21db62a0c7985964fc3c` +- `steam_client_publicbeta_linuxarm64` is tracked beside it for beta-to-publicbeta promotion context. Baseline version is `1779479049`. +- Diff checks did not find a new watched package ID, Machine/Frame price, reservation, or release-date signal. + +### SteamVR Depots + +- SteamVR news metadata was saved. +- SteamDB SteamVR depot metadata remained blocked. +- No fresh depot manifest/build comparison was collected. + +### SteamOS Package Mirror + +- Public mirror remained reachable. +- `fremont-hw-support 20260506.1-1` remains visible in `holo-3.8` and `holo-main`. +- No direct Steam Machine, Steam Frame, Deckard, Roy, ARM/Snapdragon, or new product-specific namespace surfaced in this pass. + +### Valve Support / CDN + +- Valve public endpoints were reachable. +- Controller remains public with package `1558609`, package group present, and `$99.00`. +- Frame app `4165890` remains `Coming soon`, with no public packages, no package groups, and no price. +- Machine app `4165910` remains `Coming soon`, with no public packages, no package groups, and no price. +- Machine packages `1629446`, `1629447`, `1629458`, `1629460` still return `packagedetails success:false`. +- Frame packages `1629484`, `1629486` still return `packagedetails success:false`. +- The comparison report's Valve endpoint add/remove lines are path/line-number noise from regenerated artifacts; the normalized reservation package API table is unchanged versus `2026-05-22`. + +### Customs / Regulatory + +- ImportInfo automated customs fetches were blocked. +- ImportGenius fetched successfully and still parsed `10` relevant `GAME CONSOLE` rows for `INGRAM MICRO C/O VALVE CORPORATION` / `TECH-FRONT (CHONGQING) COMPUTER CO`. +- No newer row appeared beyond the two `2026-05-18` shipments: + - `SNHBSHACHI265020`, `42 PKG`, `14353 Kgs`. + - `SNHBSHACHI264140`, `42 PKG`, `14533 Kgs`. +- Interpretation: customs remains meaningful logistics corroboration, but it does not identify whether the goods are Steam Machine, Steam Frame, or another Valve hardware SKU. + +## Effect On Key Questions + +- Price: unchanged. Only Steam Controller has a confirmed price. +- Release date: unchanged. Only Steam Controller has a confirmed exact date. +- Same-time launch: unchanged. Full same-day launch remains ruled out. +- Product furthest along: Steam Controller is already public/purchasable. Among unreleased hardware, Steam Machine still has the strongest recent backend-prep signal because of the `2026-05-12` and `2026-05-14` package movement, plus continued May `GAME CONSOLE` logistics corroboration. There was no additional Machine or Frame PICS or public API movement today. + +## Next Checks + +- Continue focused SteamKit/PICS checks for watched package IDs. +- Watch Valve public `appdetails` / `packagedetails` for Machine package exposure, package groups, price, reservation text, or purchase eligibility. +- Complete a trusted-browser SteamDB package-history pass for Machine packages `1629446`, `1629447`, `1629458`, and `1629460`. +- Keep ImportGenius in the normal customs monitor and treat ImportInfo as best-effort while it blocks. diff --git a/tests/test_steamtracking_client_manifests.py b/tests/test_steamtracking_client_manifests.py new file mode 100644 index 0000000..2053ebd --- /dev/null +++ b/tests/test_steamtracking_client_manifests.py @@ -0,0 +1,197 @@ +import csv +import os +import stat +import subprocess +import textwrap +import unittest +from pathlib import Path +from tempfile import TemporaryDirectory + + +ROOT = Path(__file__).resolve().parents[1] + + +def write_executable(path, content): + path.write_text(textwrap.dedent(content).lstrip(), encoding="utf-8") + path.chmod(path.stat().st_mode | stat.S_IXUSR) + + +def manifest(version, hardware_file="bins_hardware_linuxarm64.zip.old", steam_file="steam_linuxarm64.zip.old"): + return textwrap.dedent( + f""" + "linuxarm64" + {{ + "version" "{version}" + "bins_hardware_linuxarm64" + {{ + "file" "{hardware_file}" + "size" "7590487" + "sha2" "hardware-sha" + }} + "steam_linuxarm64" + {{ + "file" "{steam_file}" + "size" "4345869" + "sha2" "steam-sha" + }} + "runtime_steamrt_linuxarm64" + {{ + "file" "runtime_steamrt_linuxarm64.zip.same" + "size" "123973554" + "sha2" "runtime-sha" + }} + }} + """ + ).lstrip() + + +def read_rows(path): + return list(csv.DictReader(path.read_text(encoding="utf-8").splitlines(), delimiter="\t")) + + +class SteamTrackingClientManifestTests(unittest.TestCase): + def test_manifest_report_flags_linuxarm64_beta_version_and_block_changes(self): + with TemporaryDirectory() as tmp: + tmp_path = Path(tmp) + tracking = tmp_path / "tracking" + manifests = tracking / "ClientManifest" + manifests.mkdir(parents=True) + (manifests / "steam_client_beta_linuxarm64").write_text( + manifest( + "1779139477", + hardware_file="bins_hardware_linuxarm64.zip.new", + steam_file="steam_linuxarm64.zip.new", + ), + encoding="utf-8", + ) + run_dir = tmp_path / "runs" / "2026-05-23" + previous_reports = tmp_path / "runs" / "2026-05-22" / "reports" + previous_reports.mkdir(parents=True) + previous_reports.joinpath("steamtracking-client-manifests.tsv").write_text( + "\n".join( + [ + "manifest\tarch\tversion\tblock\tfile\tsize\tsha2\tchanged_since_previous\tprevious_version\tprevious_file\tprevious_size\tprevious_sha2", + "steam_client_beta_linuxarm64\tlinuxarm64\t1779000000\t__manifest__\t\t\t\tno\t\t\t\t", + "steam_client_beta_linuxarm64\tlinuxarm64\t1779000000\tbins_hardware_linuxarm64\tbins_hardware_linuxarm64.zip.old\t7590487\thardware-sha\tno\t\t\t\t", + "steam_client_beta_linuxarm64\tlinuxarm64\t1779000000\tsteam_linuxarm64\tsteam_linuxarm64.zip.old\t4345869\tsteam-sha\tno\t\t\t\t", + ] + ) + + "\n", + encoding="utf-8", + ) + + result = subprocess.run( + [ + "python3", + str(ROOT / "scripts" / "parse_steamtracking_client_manifests.py"), + "--run-dir", + str(run_dir), + "--tracking-dir", + str(tracking), + ], + cwd=ROOT, + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=False, + ) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode) + rows = read_rows(run_dir / "reports" / "steamtracking-client-manifests.tsv") + manifest_row = next( + row for row in rows if row["manifest"] == "steam_client_beta_linuxarm64" and row["block"] == "__manifest__" + ) + hardware_row = next( + row for row in rows if row["manifest"] == "steam_client_beta_linuxarm64" and row["block"] == "bins_hardware_linuxarm64" + ) + self.assertEqual("1779139477", manifest_row["version"]) + self.assertEqual("yes", manifest_row["changed_since_previous"]) + self.assertEqual("yes", hardware_row["changed_since_previous"]) + self.assertEqual("bins_hardware_linuxarm64.zip.old", hardware_row["previous_file"]) + + key_lines = (run_dir / "reports" / "steamtracking-client-manifests-key-lines.txt").read_text( + encoding="utf-8" + ) + self.assertIn("steam_client_beta_linuxarm64", key_lines) + self.assertIn("bins_hardware_linuxarm64", key_lines) + self.assertIn("changed=yes", key_lines) + + def test_check_steamtracking_writes_client_manifest_report(self): + with TemporaryDirectory() as tmp: + tmp_path = Path(tmp) + tracking = tmp_path / "tracking" + manifests = tracking / "ClientManifest" + manifests.mkdir(parents=True) + (manifests / "steam_client_beta_linuxarm64").write_text( + manifest("1779139477", hardware_file="bins_hardware_linuxarm64.zip.new"), + encoding="utf-8", + ) + (tracking / "ProtobufsWebui").mkdir() + (tracking / "ProtobufsWebui" / "service_steaminputmanager.proto").write_text( + "message CSteamInputService_ShouldTritonPairInOobe_Request {}\n", + encoding="utf-8", + ) + run_dir = tmp_path / "runs" / "2026-05-23" + + result = subprocess.run( + [str(ROOT / "scripts" / "check_steamtracking.sh"), str(run_dir), str(tracking)], + cwd=ROOT, + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=False, + ) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode) + self.assertTrue((run_dir / "reports" / "steamtracking-client-manifests.tsv").exists()) + key_lines = (run_dir / "reports" / "steamtracking-client-manifests-key-lines.txt").read_text( + encoding="utf-8" + ) + self.assertIn("steam_client_beta_linuxarm64", key_lines) + + def test_compare_runs_includes_client_manifest_key_line_deltas(self): + with TemporaryDirectory() as tmp: + tmp_path = Path(tmp) + previous = tmp_path / "2026-05-22" + current = tmp_path / "2026-05-23" + (previous / "reports").mkdir(parents=True) + (current / "reports").mkdir(parents=True) + (previous / "reports" / "steamtracking-client-manifests-key-lines.txt").write_text( + "steam_client_beta_linuxarm64 version=1779000000 arch=linuxarm64 changed=no previous=\n", + encoding="utf-8", + ) + (current / "reports" / "steamtracking-client-manifests-key-lines.txt").write_text( + "steam_client_beta_linuxarm64 version=1779139477 arch=linuxarm64 changed=yes previous=1779000000\n", + encoding="utf-8", + ) + output = tmp_path / "compare.md" + + result = subprocess.run( + [ + "python3", + str(ROOT / "scripts" / "compare_runs.py"), + "--previous", + str(previous), + "--current", + str(current), + "--output", + str(output), + ], + cwd=ROOT, + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=False, + ) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode) + compare = output.read_text(encoding="utf-8") + self.assertIn("Steam client manifests added line", compare) + self.assertIn("1779139477", compare) + + +if __name__ == "__main__": + unittest.main()