From 6cfe01672fd66b5b598cf73eb4502456ec333b35 Mon Sep 17 00:00:00 2001 From: Jacob Metoyer <150724801+Jacob-Met@users.noreply.github.com> Date: Thu, 8 Oct 2026 07:52:57 -0700 Subject: [PATCH 1/3] Reopen saved analysis on the merged scope controls Compose the accepted history reader and native controls with the actual 3e3 parent. Preserve normalized package/scope hooks, and reserve controls from scheduled thread start through unchanged cleanup. Keep the original 14/19 acceptance pinned to 37443 on 72c15; add the bounded 24-check real-current scope/history journey, its concrete startup control, exact source manifests and current-format limits. Authored source: estate-401c5d17da79/production_discovery, 495b8d45b0b9aa2231bccb315bd68e762a240143. Independent original receiving: estate-401c5d17da79/estate_coordination. Current composition, bounded busy repair and scope/history receiving: estate-401c5d17da79/integration_discovery. Original commits remain preserved in the genuine authored-ancestry bundle. Precision note: the authored result-reset helper is the only _start_job difference from canonical main; the current worker lifecycle and cleanup remain preserved. --- README.md | 8 +- desktop/capture_desktop/analysis_history.py | 164 +++ desktop/capture_desktop/screen_analysis.py | 46 +- .../widgets_analysis_history.py | 220 ++++ docs/design/research/PROGRESS.md | 40 + .../analysis-history-401c5d17da79/README.md | 108 ++ .../artifact-manifest.json | 130 +++ .../author/author-correction-process.json | 17 + .../author/author-correction.log | 10 + .../author/author-focused-2.log | 10 + .../author/baseline-history.py | 63 ++ .../author/baseline-receipt.json | 34 + .../author/candidate-correction-freeze.json | 28 + .../author/candidate-source-freeze.json | 26 + .../author/harness-observations.json | 23 + .../author/thread-event-loop.log | 10 + .../author/thread-isolated.log | 99 ++ .../current-numeric/README.md | 72 ++ .../current-numeric/check_numeric_gallery.py | 90 ++ .../numeric-run/numeric-history-gap.png | Bin 0 -> 85925 bytes .../current-numeric/numeric-run/receipt.json | 214 ++++ .../current-numeric/numeric.stderr.log | 1 + .../current-numeric/numeric.stdout.log | 1 + .../current-numeric/process.json | 17 + .../current-numeric/source-inputs.json | 994 ++++++++++++++++++ .../current-qc/README.md | 70 ++ .../current-qc/check_current_qc_history.py | 159 +++ .../current-qc/current-run/artifacts/qc.html | 60 ++ .../current-qc/current-run/artifacts/qc.json | 65 ++ .../current-qc/current-run/receipt.json | 105 ++ .../current-qc/current.stderr.log | 1 + .../current-qc/current.stdout.log | 1 + .../current-qc/process.json | 18 + .../current-qc/source-inputs.json | 981 +++++++++++++++++ .../current-scope/README.md | 23 + .../candidate-source-inputs.json | 865 +++++++++++++++ .../current-scope/check_scope_history.py | 272 +++++ .../current-scope/custody.json | 100 ++ .../current-scope/freshness-d43.json | 346 ++++++ .../current-scope/native.stderr.log | 5 + .../check_scope_history.py | 251 +++++ .../receipt-state.json | 10 + .../current-scope/process.json | 19 + .../current-scope/receipt.json | 380 +++++++ .../current-scope/receiving.json | 37 + .../current-scope/scope-history-reopened.png | Bin 0 -> 193004 bytes .../startup-negative/check_scope_history.py | 249 +++++ .../startup-negative/native.stderr.log | 3 + .../startup-negative/native.stdout.log | 1 + .../startup-negative/process.json | 18 + .../startup-negative/receipt.json | 33 + .../startup-negative/screen_analysis.py.txt | 517 +++++++++ .../startup-negative/source-inputs.json | 863 +++++++++++++++ .../independent/37443-candidate.log | 18 + .../37443-manual-stall-receipt.json | 10 + .../independent/baseline-receipt.json | 162 +++ .../independent/baseline.log | 10 + .../independent/c0b5530-candidate.log | 38 + .../c0b5530-eventloop-receipt.json | 74 ++ .../independent/c0b5530-eventloop.log | 7 + .../independent/c0b5530-failure-receipt.json | 345 ++++++ .../independent/methods/receive_history.py | 437 ++++++++ .../methods/receive_history_native.py | 239 +++++ .../methods/receive_qt_eventloop.py | 155 +++ .../independent/native-candidate-receipt.json | 653 ++++++++++++ .../independent/native-candidate.log | 23 + .../publication-composition.json | 469 +++++++++ .../publication-license-check.json | 11 + .../publication-method-adjustments.json | 20 + .../visual/details-log.png | Bin 0 -> 35244 bytes .../visual/details-parameters.png | Bin 0 -> 37469 bytes .../visual/details-visual-receipt.json | 13 + .../visual/details-visual.py | 97 ++ .../visual/native-reopened-b.png | Bin 0 -> 218488 bytes docs/operator/README.md | 27 + tests/ui/test_analysis_history.py | 263 +++++ 76 files changed, 10942 insertions(+), 6 deletions(-) create mode 100644 desktop/capture_desktop/analysis_history.py create mode 100644 desktop/capture_desktop/widgets_analysis_history.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/README.md create mode 100644 docs/evidence/analysis-history-401c5d17da79/artifact-manifest.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/author-correction-process.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/author-correction.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/author-focused-2.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/baseline-history.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/baseline-receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/candidate-correction-freeze.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/candidate-source-freeze.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/harness-observations.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/thread-event-loop.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/author/thread-isolated.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-numeric/README.md create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-numeric/check_numeric_gallery.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric-run/numeric-history-gap.png create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric-run/receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric.stderr.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric.stdout.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-numeric/process.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-numeric/source-inputs.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/README.md create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/check_current_qc_history.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/artifacts/qc.html create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/artifacts/qc.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/current.stderr.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/current.stdout.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/process.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-qc/source-inputs.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/README.md create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/candidate-source-inputs.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/check_scope_history.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/custody.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/freshness-d43.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/native.stderr.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/nonaccepting-continuation/check_scope_history.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/nonaccepting-continuation/receipt-state.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/process.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/receiving.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/scope-history-reopened.png create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/check_scope_history.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/native.stderr.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/native.stdout.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/process.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/screen_analysis.py.txt create mode 100644 docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/source-inputs.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/37443-candidate.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/37443-manual-stall-receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/baseline-receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/baseline.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-candidate.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-eventloop-receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-eventloop.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-failure-receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_history.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_history_native.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_qt_eventloop.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/native-candidate-receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/independent/native-candidate.log create mode 100644 docs/evidence/analysis-history-401c5d17da79/publication-composition.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/publication-license-check.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/publication-method-adjustments.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/visual/details-log.png create mode 100644 docs/evidence/analysis-history-401c5d17da79/visual/details-parameters.png create mode 100644 docs/evidence/analysis-history-401c5d17da79/visual/details-visual-receipt.json create mode 100644 docs/evidence/analysis-history-401c5d17da79/visual/details-visual.py create mode 100644 docs/evidence/analysis-history-401c5d17da79/visual/native-reopened-b.png create mode 100644 tests/ui/test_analysis_history.py diff --git a/README.md b/README.md index 14bae7a2..f532e69a 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,8 @@ capture path for every device. - **Plugins** — drop in a `plugin.json` + worker executable (C++ or Python SDK) - **Sim** — develop and demo without hardware - **LSL bridge** — record any Lab Streaming Layer outlet with zero vendor code -- **Analysis** — QC, features, pose/kinematics, ML bundle jobs on sealed packages +- **Analysis** — QC, features, pose/kinematics, ML bundle jobs on sealed packages; + reopen saved results with their parameters, logs and output inventory ## Architecture (sketch) @@ -58,6 +59,11 @@ existing output directory, and preserves failure output for diagnosis. It does not establish hardware performance, clinical validity, or full product readiness. Tests: `tests/analysis/test_offline_demo.py`. +To inspect that saved job in the desktop, select its `.mmsession` package in +**Analysis**, choose `demo-qc` under **Saved analysis**, then **Open saved result**. +The [operator guide](docs/operator/README.md#open-saved-analysis) describes the +gallery, inspector and read-only result details. + ## Simulation walkthrough (after build prerequisites) ```powershell diff --git a/desktop/capture_desktop/analysis_history.py b/desktop/capture_desktop/analysis_history.py new file mode 100644 index 00000000..1b8fd23a --- /dev/null +++ b/desktop/capture_desktop/analysis_history.py @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""Read saved analysis jobs from the selected package without changing them.""" + +from __future__ import annotations + +import json +from dataclasses import dataclass +from pathlib import Path, PureWindowsPath +from typing import Any + +_JSON_LIMIT = 4 * 1024 * 1024 +_LOG_LIMIT = 256 * 1024 +_STATUSES = {"completed", "completed_with_warnings", "failed"} + + +@dataclass(frozen=True) +class SavedJob: + job_id: str + directory: Path + status: str = "" + created_utc: str = "" + problem: str = "" + + +@dataclass(frozen=True) +class SavedJobDetails: + job: SavedJob + manifest: dict[str, Any] + params_text: str + log_text: str + + +def _direct_path(path: Path) -> None: + if path.is_symlink() or path.is_junction(): + raise ValueError(f"Saved analysis paths must stay inside this package: {path}") + + +def _jobs_root(package: str | Path) -> Path: + if not package: + raise ValueError("Select a package before opening saved analysis.") + root = Path(package).resolve() + if not root.is_dir(): + raise ValueError(f"Package is unavailable: {root}") + for path in (root / "processing", root / "processing" / "jobs"): + _direct_path(path) + if path.exists() and not path.is_dir(): + raise ValueError(f"Analysis job location is not a directory: {path}") + return root / "processing" / "jobs" + + +def _job_directory(package: str | Path, job_id: str) -> Path: + if ( + not isinstance(job_id, str) + or not job_id + or job_id.startswith(".") + or job_id.endswith((".", " ")) + or any(char in '<>:"/\\|?*' or ord(char) < 32 for char in job_id) + or PureWindowsPath(job_id).is_reserved() + ): + raise ValueError("Select a visible analysis job from this package.") + path = _jobs_root(package) / job_id + _direct_path(path) + if not path.is_dir(): + raise ValueError(f"Saved analysis job is unavailable: {job_id}") + return path + + +def job_belongs_to_package(package: str | Path, job_dir: str | Path) -> bool: + """Check the directory itself; recorded packagePath can predate a package copy.""" + if not package or not job_dir: + return False + try: + candidate = Path(job_dir).absolute() + return _job_directory(package, candidate.name) == candidate + except (OSError, ValueError): + return False + + +def _read_json(path: Path) -> dict[str, Any]: + _direct_path(path) + if not path.is_file(): + raise ValueError(f"Saved file is unavailable: {path.name}") + with path.open("rb") as stream: + raw = stream.read(_JSON_LIMIT + 1) + if len(raw) > _JSON_LIMIT: + raise ValueError(f"{path.name} exceeds the 4 MiB viewer limit.") + doc = json.loads(raw) + if not isinstance(doc, dict): + raise ValueError(f"{path.name} must contain a JSON object.") + return doc + + +def _package_session_id(package: str | Path) -> str: + manifest = _read_json(Path(package).resolve() / "manifest.json") + identity = manifest.get("identity") or {} + if not isinstance(identity, dict): + raise ValueError("Package identity is malformed.") + # Only an explicit identity is stable when a package directory is copied. + return str(manifest.get("sessionId") or identity.get("sessionId") or "") + + +def _read_job( + package: str | Path, job_id: str, *, session_id: str +) -> tuple[SavedJob, dict[str, Any]]: + path = _job_directory(package, job_id) + manifest = _read_json(path / "job_manifest.json") + if manifest.get("schemaId") != "capture.analysis_job/1": + raise ValueError("This saved job uses an unsupported manifest schema.") + if manifest.get("jobId") != job_id: + raise ValueError("Saved manifest identity does not match its job directory.") + if session_id and manifest.get("sessionId") != session_id: + raise ValueError("Saved job belongs to a different session.") + status = manifest.get("status") + if not isinstance(status, str) or status not in _STATUSES: + raise ValueError("This job has no completed or failed result to inspect yet.") + outputs = manifest.get("outputs", []) + if not isinstance(outputs, list) or any(not isinstance(row, dict) for row in outputs): + raise ValueError("Saved manifest output inventory is malformed.") + return SavedJob(job_id, path, status, str(manifest.get("createdUtc") or "")), manifest + + +def list_saved_jobs(package: str | Path) -> list[SavedJob]: + """Visible jobs, including explicit unavailable rows; hidden attempts stay hidden.""" + jobs = _jobs_root(package) + if not jobs.exists(): + return [] + session_id = _package_session_id(package) + result = [] + for child in sorted(jobs.iterdir(), key=lambda p: p.name, reverse=True): + if child.name.startswith(".") or not child.is_dir(): + continue + try: + job, _ = _read_job(package, child.name, session_id=session_id) + except (OSError, ValueError, UnicodeError) as exc: + job = SavedJob(child.name, child, problem=str(exc)) + result.append(job) + return result + + +def load_saved_job(package: str | Path, job_id: str) -> SavedJobDetails: + """Re-read the selected job at Open time; no cached catalog row authorizes a path.""" + job, manifest = _read_job(package, job_id, session_id=_package_session_id(package)) + try: + params = _read_json(job.directory / "params.json") + params_text = json.dumps(params, ensure_ascii=False, indent=2, sort_keys=True) + except (OSError, ValueError, UnicodeError) as exc: + params_text = f"Parameters unavailable: {exc}" + try: + logs = job.directory / "logs" + _direct_path(logs) + log = logs / "job.log" + _direct_path(log) + if not log.is_file(): + raise ValueError("No saved job.log file.") + with log.open("rb") as stream: + # Show the end of long logs, where completion/failure diagnostics live. + size = stream.seek(0, 2) + stream.seek(max(0, size - _LOG_LIMIT)) + log_text = stream.read(_LOG_LIMIT).decode("utf-8", errors="replace") + if size > _LOG_LIMIT: + log_text = f"Showing the final {_LOG_LIMIT:,} bytes of {size:,}.\n\n{log_text}" + except (OSError, ValueError) as exc: + log_text = f"Log unavailable: {exc}" + return SavedJobDetails(job, manifest, params_text, log_text) diff --git a/desktop/capture_desktop/screen_analysis.py b/desktop/capture_desktop/screen_analysis.py index 78905bbd..6893f119 100644 --- a/desktop/capture_desktop/screen_analysis.py +++ b/desktop/capture_desktop/screen_analysis.py @@ -24,8 +24,10 @@ ) from . import theme +from .analysis_history import SavedJobDetails, job_belongs_to_package, load_saved_job from .persistence import DesktopPersistence from .state import CaptureState, fmt_time +from .widgets_analysis_history import AnalysisHistory from .widgets_analysis_jobs import AnalysisJobExtras, peek_ml_bundle_summary from .widgets_analysis_plots import FigureGallery, JobInspector from .widgets_analysis_scope import WINDOW_COMMANDS, ScopeSelection @@ -126,6 +128,11 @@ def __init__( self._scope_note.setObjectName("Dim") root.addWidget(self._scope_note) + self._history = AnalysisHistory() + self._history.job_loaded.connect(self._show_saved_job) + self._history.view_cleared.connect(self._clear_result_view) + root.addWidget(self._history) + splitter = QSplitter() splitter.setChildrenCollapsible(False) root.addWidget(splitter, 1) @@ -301,6 +308,7 @@ def set_package(self, package_path: str) -> None: self._scope = ScopeSelection() self._package = resolved self._path.setText(resolved) + self._history.set_package(resolved) self._extras.set_package(resolved) self._refresh_summary() self._sync_enabled() @@ -320,7 +328,7 @@ def _recording_locked(self) -> bool: ) def _sync_enabled(self) -> None: - busy = self._thread is not None and self._thread.isRunning() + busy = self._thread is not None locked = self._recording_locked() has_pkg = self._summary is not None scope_error = self._scope_error() @@ -333,6 +341,7 @@ def _sync_enabled(self) -> None: self._btn_use_open.setEnabled(not busy and bool(self._state.package_path)) self._command.setEnabled(not busy) self._gap_policy.setEnabled(not busy) + self._history.set_busy(busy) if locked: self._banner.setText( "Analysis is disabled while the session is arming or recording." @@ -400,8 +409,7 @@ def _start_job(self) -> None: return extra = self._extras.build_extra(command) self._log.clear() - self._gallery.clear() - self._inspector.clear() + self._clear_result_view() self._append_log(f"Starting {command} on {self._package}") self._append_log(f"scope={self._scope.describe()}") if extra: @@ -440,10 +448,37 @@ def _on_finished(self, result: object) -> None: job_dir = str(getattr(result, "job_dir", "") or "") status = str(getattr(result, "status", "") or "") job_id = str(getattr(result, "job_id", "") or "") - self._last_job_dir = job_dir - self._progress.setValue(100) self._append_log(f"Done status={status} job_id={job_id}") self._append_log(f"dir={job_dir}") + if not job_belongs_to_package(self._package, job_dir): + self._append_log( + "Result saved for the previous package; select that package to inspect it." + ) + return + self._progress.setValue(100) + self._history.refresh(preferred_job_id=job_id) + try: + details = load_saved_job(self._package, Path(job_dir).name) + except (OSError, ValueError, UnicodeError) as exc: + self._append_log(f"Result saved, but the viewer could not load it: {exc}") + return + self._show_saved_job(details) + + def _clear_result_view(self) -> None: + self._last_job_dir = "" + self._btn_open_job.setEnabled(False) + self._btn_open_report.setEnabled(False) + self._gallery.clear() + self._inspector.clear() + self._history.clear_loaded() + + @Slot(object) + def _show_saved_job(self, details: SavedJobDetails) -> None: + if not job_belongs_to_package(self._package, details.job.directory): + return + job_dir = str(details.job.directory) + self._last_job_dir = job_dir + self._history.show_loaded(details) self._btn_open_job.setEnabled(bool(job_dir)) report = Path(job_dir) / "reports" / "qc.html" if job_dir else Path() self._btn_open_report.setEnabled(report.is_file()) @@ -463,6 +498,7 @@ def _on_finished(self, result: object) -> None: @Slot(str) def _on_failed(self, message: str) -> None: self._append_log(f"FAIL: {message}") + self._history.refresh() if message.split("\n", 1)[0] != "cancelled": QMessageBox.warning(self, "Analysis failed", message) diff --git a/desktop/capture_desktop/widgets_analysis_history.py b/desktop/capture_desktop/widgets_analysis_history.py new file mode 100644 index 00000000..8798627c --- /dev/null +++ b/desktop/capture_desktop/widgets_analysis_history.py @@ -0,0 +1,220 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""Native saved-result picker and read-only analysis details.""" + +from __future__ import annotations + +import json +from pathlib import Path + +from PySide6.QtCore import Qt, Signal +from PySide6.QtWidgets import ( + QComboBox, + QDialog, + QDialogButtonBox, + QHBoxLayout, + QLabel, + QPlainTextEdit, + QPushButton, + QTabWidget, + QVBoxLayout, + QWidget, +) + +from . import theme +from .analysis_history import SavedJob, SavedJobDetails, list_saved_jobs, load_saved_job + + +class AnalysisHistory(QWidget): + """Explicitly open a saved result; choosing one never starts or edits a job.""" + + job_loaded = Signal(object) # SavedJobDetails + view_cleared = Signal() + + def __init__(self, parent: QWidget | None = None) -> None: + super().__init__(parent) + self._package = "" + self._busy = False + self._loaded: SavedJobDetails | None = None + self._dialog: QDialog | None = None + root = QVBoxLayout(self) + root.setContentsMargins(0, 0, 0, 0) + root.setSpacing(4) + row = QHBoxLayout() + label = QLabel("Saved analysis") + label.setFont(theme.ui(9, bold=True)) + row.addWidget(label) + self._jobs = QComboBox() + self._jobs.setObjectName("analysisHistoryJob") + self._jobs.setAccessibleName("Saved analysis job") + self._jobs.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) + self._jobs.setMinimumContentsLength(24) + self._jobs.currentIndexChanged.connect(self._selection_changed) + row.addWidget(self._jobs, 1) + self._refresh = QPushButton("Refresh") + self._refresh.setObjectName("analysisHistoryRefresh") + self._refresh.clicked.connect(lambda: self.refresh()) + row.addWidget(self._refresh) + self._open = QPushButton("Open saved result") + self._open.setObjectName("analysisHistoryOpen") + self._open.clicked.connect(self._open_selected) + row.addWidget(self._open) + self._details = QPushButton("Result details…") + self._details.setObjectName("analysisHistoryDetails") + self._details.clicked.connect(self._show_details) + row.addWidget(self._details) + root.addLayout(row) + self._status = QLabel("Select a package to browse its saved analysis.") + self._status.setObjectName("Dim") + self._status.setTextFormat(Qt.TextFormat.PlainText) + self._status.setWordWrap(True) + self._status.setFont(theme.ui(8)) + root.addWidget(self._status) + self._sync_enabled() + + @property + def package(self) -> str: + return self._package + + @property + def loaded_job_id(self) -> str: + return self._loaded.job.job_id if self._loaded else "" + + def set_package(self, package: str) -> None: + identity = str(Path(package).resolve()) if package else "" + if identity == self._package: + return + self._package = identity + self.clear_loaded() + self.view_cleared.emit() + self.refresh() + + def set_busy(self, busy: bool) -> None: + self._busy = busy + self._sync_enabled() + + def clear_loaded(self) -> None: + self._loaded = None + if self._dialog is not None: + self._dialog.close() + self._dialog = None + self._sync_enabled() + + def _selected(self) -> SavedJob | None: + value = self._jobs.currentData() + return value if isinstance(value, SavedJob) else None + + def _sync_enabled(self, *_args) -> None: + row = self._selected() + self._jobs.setEnabled(bool(self._package) and not self._busy) + self._refresh.setEnabled(bool(self._package) and not self._busy) + self._open.setEnabled(row is not None and not row.problem and not self._busy) + self._details.setEnabled(self._loaded is not None and not self._busy) + if row is not None and row.problem: + self._status.setText(f"{row.job_id}: {row.problem}") + + def _selection_changed(self, *_args) -> None: + row = self._selected() + if row is not None and not row.problem: + self._status.setText( + f"Selected {row.job_id} · {row.status}. Open to inspect this result." + ) + self._sync_enabled() + + def refresh(self, preferred_job_id: str | None = None) -> None: + selected = self._selected() + preferred = preferred_job_id or (selected.job_id if selected else "") + self._jobs.blockSignals(True) + self._jobs.clear() + try: + jobs = list_saved_jobs(self._package) if self._package else [] + except (OSError, ValueError) as exc: + jobs = [] + message = f"Could not read saved analysis: {exc}" + else: + usable = sum(not job.problem for job in jobs) + message = ( + f"{usable} saved result(s). Select a job and open it in the gallery and inspector." + if usable else "No readable saved analysis results in this package." + ) + unavailable = len(jobs) - usable + if unavailable: + message += f" {unavailable} unavailable job(s) are listed with their reason." + found = -1 + for job in jobs: + text = f"{job.job_id} · {job.status if not job.problem else 'unavailable'}" + self._jobs.addItem(text, job) + if job.job_id == preferred: + found = self._jobs.count() - 1 + if found >= 0: + self._jobs.setCurrentIndex(found) + self._jobs.blockSignals(False) + if self._loaded and not any( + job.job_id == self._loaded.job.job_id and not job.problem for job in jobs + ): + self.clear_loaded() + self.view_cleared.emit() + if self._loaded is not None: + self.show_loaded(self._loaded) + else: + self._status.setText(message) + self._sync_enabled() + + def show_loaded(self, details: SavedJobDetails) -> None: + self._loaded = details + job = details.job + when = f" · {job.created_utc}" if job.created_utc else "" + self._status.setText(f"Viewing {job.job_id} · {job.status}{when}") + self._sync_enabled() + + def _open_selected(self) -> None: + selected = self._selected() + if self._busy or selected is None or selected.problem: + return + try: + details = load_saved_job(self._package, selected.job_id) + except (OSError, ValueError, UnicodeError) as exc: + self._status.setText(f"Could not open {selected.job_id}: {exc}. Refresh the job list.") + return + self.show_loaded(details) + self.job_loaded.emit(details) + + def _show_details(self) -> None: + if self._loaded is None or self._busy: + return + if self._dialog is not None: + self._dialog.close() + details = self._loaded + dialog = QDialog(self) + dialog.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose) + dialog.setObjectName("analysisHistoryDetailsDialog") + dialog.setWindowTitle(f"Analysis result — {details.job.job_id}") + dialog.resize(780, 560) + layout = QVBoxLayout(dialog) + location = QLabel(str(details.job.directory)) + location.setTextFormat(Qt.TextFormat.PlainText) + location.setWordWrap(True) + location.setTextInteractionFlags(Qt.TextInteractionFlag.TextSelectableByMouse) + layout.addWidget(location) + tabs = QTabWidget() + for title, text in ( + ("Parameters", details.params_text), + ("Log", details.log_text), + ("Manifest", json.dumps(details.manifest, ensure_ascii=False, indent=2, + sort_keys=True)), + ): + editor = QPlainTextEdit() + editor.setObjectName(f"analysisHistory{title}") + editor.setReadOnly(True) + editor.setFont(theme.mono(9)) + editor.setPlainText(text) + tabs.addTab(editor, title) + layout.addWidget(tabs, 1) + buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Close) + buttons.rejected.connect(dialog.close) + layout.addWidget(buttons) + dialog.finished.connect(self._details_closed) + self._dialog = dialog + dialog.show() + + def _details_closed(self, _result: int) -> None: + self._dialog = None diff --git a/docs/design/research/PROGRESS.md b/docs/design/research/PROGRESS.md index 99c812ac..81b3294d 100644 --- a/docs/design/research/PROGRESS.md +++ b/docs/design/research/PROGRESS.md @@ -1,3 +1,43 @@ +## 2026-10-08 — Compose saved analysis with the merged scope controls + +Worker `estate-401c5d17da79`, issue #55: receiving on main `3e3ecc5` +preserves the merged #53/#58 scope controls and normalized package identity +while adding saved-result history. The current screen treats its retained +thread handle as busy from scheduled start through the existing cleanup. +One actual QApplication/QTimer journey passes 24 checks with two real +numeric-feature jobs: saved exact ranges, disabled/restored controls, +read-only reopening, same-package scope retention, and refusal to repaint +a different package after a queued completion. The original 14/19 results +below keep their original inputs; Windows CI and the separately owned +nested-numeric gallery repair remain distinct. Exact source, the startup +negative control and current receipts are in +[current scope receiving](../../evidence/analysis-history-401c5d17da79/current-scope/README.md). + +## 2026-10-08 — Reopen saved analysis in the native workbench + +Worker `estate-401c5d17da79`, issue #55: the Analysis tab now lists retained +completed and failed jobs from its selected package. Explicit Open loads the +existing gallery and inspector; native read-only Parameters, Log and Manifest +tabs expose saved diagnostics. Refresh does not rerun analysis. Package changes +clear the old view, and late results remain attached to their original package. +Unavailable/malformed/foreign jobs remain visible with a refusal reason. + +Authored source `37443f0` passes all 14 focused and retained native UI tests, +including actual successful and failed analysis QThreads. Independent receiving +passes 19 checks through the real QApplication event loop: retained real figures, +same-name jobs in different sessions, stale selection refusal, late completion +and exact saved/raw byte preservation. The original worker, signal wiring, +thread cleanup, gallery, inspector and job formats are preserved. The separately +owned #53/#54 scope controls and #46 provenance writer are outside this change. + +Earlier manual-event-pump crashes/stalls and an empty receipt caused by transient +filesystem exhaustion are retained as non-accepting harness outcomes. The same +first candidate passed its genuine application-event-loop control; no native +cleanup defect is inferred from those manual-pump observations. Qualification is +native Linux Qt/Python 3.12, not a Windows CI, full-product or hardware claim. +Exact source pins, raw logs, independent methods and reviewed native frames are +in [the receiving evidence](../../evidence/analysis-history-401c5d17da79/README.md). + ## 2026-10-08 — Windows atomic writer reserves owned temporary files Contributor `estate-6267db2cfc6e` prepared the repair for issue51/PR52. Windows diff --git a/docs/evidence/analysis-history-401c5d17da79/README.md b/docs/evidence/analysis-history-401c5d17da79/README.md new file mode 100644 index 00000000..68d7d6ce --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/README.md @@ -0,0 +1,108 @@ +# Saved analysis history — issue 55 + +Researchers can reopen analysis already saved inside a selected `.mmsession` +package, inspect its original parameters and log, and move between packages +without leaving figures from the previous package on screen. This completes the +saved-result history and details portion of the existing workbench plan. + +## Source and scope + +Author: `estate-401c5d17da79 / production_discovery`. +Independent native receiver: `estate-401c5d17da79 / estate_coordination`. +Coordination: [CaptureSuite #55](https://github.com/Jacob-Met/CaptureSuite/issues/55). + +The genuine authored parent is +`72c15d6b623e217291a824e4e4808a385df896a9` (tree +`221cf5c7bb3c3392a7c4186ba0bcf5a8664135d1`). The first feature commit is +`c0b5530c03cce3e42a0430e5411cddf1df716e19`; the accepted runtime successor is +`37443f0d4d5ffa684b5423d58501856cadbe0655` (tree +`3b3184b931a2aaf91beec36c953bff909a77f2f5`). Subsequent documentation and +current-parent composition commits retain these runtime file hashes. + +Production changes comprise a read-only `analysis_history.py` reader, a native +`widgets_analysis_history.py` picker/details window, and small screen hooks. +The existing worker class, signal wiring and thread cleanup remain unchanged; +gallery/inspector implementations, analysis handlers and job-writing formats +remain unchanged. History refreshes during successful or failed result delivery. +Package-bound result selection and a fresh manifest read at Open prevent a +cached selection from opening a disappeared or foreign result. + +The time/source/checkpoint UI in #53, preceding-section resolver in #54 and job +provenance writer in #46 retain their separate owners. Existing #48 destination, +replacement and failure-note behavior is preserved. + +## What ran + +| Qualification | Result | Exact evidence | +| --- | --- | --- | +| Canonical original source | A retained real QC job exists, but reopening its package exposes no history control; the existing inspector can read it when called directly | `author/baseline-receipt.json` | +| Original package lifetime control | Real A figures remain visible after selecting B; an actual late A QC completion binds under B | `independent/baseline-receipt.json` | +| Authored native tests plus retained UI tests | **14 passed**, no skips, 3.21 seconds | `author/author-correction.log` | +| Independent full native receiving | **19 checks passed**, exit 0, 0.914 seconds | `independent/native-candidate-receipt.json` | +| Native details visual check | Parameters/log tabs are readable; selected current-QC/2 package bytes unchanged and no worker started | `visual/details-visual-receipt.json` | + +The eight new tests use real completed and failed jobs, copied packages, malformed +and foreign manifests, missing/long saved details, explicit refresh/open actions, +and genuine successful and failed QThreads. The six retained tests cover the +existing workbench, linked plot output and failure-note/cancellation behavior. +Ruff and source whitespace checks pass for all changed production/test files. + +The independent receiver generates actual EMG/IMU protobuf MCAP and saved native +figures. It reopens two real PNG and two linked plots, switches between distinct +sessions with the same job name, refuses unavailable/foreign results, revalidates +a manifest removed after selection, and delays delivery of a genuinely completed +QC job while switching packages. Its native `QApplication.exec()` and `QTimer` +state machine confirms that saved/raw/source bytes stay unchanged during viewing +and late delivery. Exact methods and helpers are retained under +`independent/methods/`; they preserve their original bounded workspace paths for +audit. The receiver also preserves its complete fixture packet separately. + +## Retained unsuccessful attempts + +Manual `processEvents()` / `QTest.qWait()` pumping is not used as the accepting +worker-lifecycle gate. The first authored polling test timed out during a cold +import and aborted while its fixture deleted a running worker. The independent +first candidate similarly crashed after 15 manual-pump checks; a genuine +application-event-loop control of the same runtime passed five checks. A later +manual-pump run stalled and was stopped with exit 130. These outcomes and raw +traces remain in `author/harness-observations.json` and `independent/`; they do +not establish a native application defect. The accepted full receiving uses the +application event loop. No further worker-lifecycle workaround was introduced. + +A transient shared-filesystem exhaustion left one attempted author's stdout, +XML and process receipt empty. No test result is claimed for that attempt, and +no other worker's files were removed. The subsequent retained logs identify the +successful exact runs. + +## Replay and boundaries + +With the project's Python 3.12 desktop/analysis dependencies already installed, +run from the repository root with an isolated Qt platform and application state: + +```sh +QT_QPA_PLATFORM=offscreen python -m pytest \ + tests/ui/test_analysis_history.py \ + tests/ui/test_analysis_workbench.py \ + tests/ui/test_analysis_failure_notes.py -q -ra +``` + +Qualification used Python 3.12.14 and PySide6 6.11.2 on native Linux with the +offscreen Qt platform. It covers this offline UI flow, not Windows CI, the full +desktop/daemon product, physical hardware or clinical validity. The Mac copy is +source/evidence custody only. Current-main QC/2 composition is independently +qualified in the receiving successor and does not replace the authored pins. + +`artifact-manifest.json` records the exact retained file hashes. The details and +gallery captures are actual reviewed native frames: + +The unchanged repository license gate required SPDX headers on the copied +author baseline and visual scripts. `publication-method-adjustments.json` +records their original and publication hashes; only the leading license comment +was added. The exact originally executed bytes remain in commit `1ce96118` and +its immutable source/evidence packet. Runtime and test files did not change. + +![Reopened saved analysis](visual/native-reopened-b.png) + +![Original saved parameters](visual/details-parameters.png) + +![Original saved log](visual/details-log.png) diff --git a/docs/evidence/analysis-history-401c5d17da79/artifact-manifest.json b/docs/evidence/analysis-history-401c5d17da79/artifact-manifest.json new file mode 100644 index 00000000..eb608ae2 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/artifact-manifest.json @@ -0,0 +1,130 @@ +{ + "files": { + "README.md": { + "bytes": 6192, + "sha256": "343657c7042415e70fdfbdad52816092e351a515dd3c4b5a80a9c88b643558b0" + }, + "author/author-correction-process.json": { + "bytes": 416, + "sha256": "9918f9d7ab8934d215b3146655bce2d9e7eb9474c33891b6d5201cf21c0c5efd" + }, + "author/author-correction.log": { + "bytes": 901, + "sha256": "e08a988c2851e4544838a15637ec18b1b51da3cd644a4cef3b4ad15405ecd892" + }, + "author/author-focused-2.log": { + "bytes": 900, + "sha256": "eacab3f72f2cea5c3abce75976fe9344c0122304d361d75520caa07f136c99e8" + }, + "author/baseline-history.py": { + "bytes": 3012, + "sha256": "ae3d803367e60939f9b777f2196bd4e59e0e2ed169929b1260ec391279f66538" + }, + "author/baseline-receipt.json": { + "bytes": 2105, + "sha256": "2c1097ab9d8a92e7537d5c5cbe4782c249ce0d1a465ca47d7fa595a2d14c1325" + }, + "author/candidate-correction-freeze.json": { + "bytes": 1389, + "sha256": "93f0356c8d3760a6ca3bdee545c98ca015801478d3841798a8148c3bb26a59d4" + }, + "author/candidate-source-freeze.json": { + "bytes": 1151, + "sha256": "0293af5bd506da3b3d96dc5a932c3354b883b52b971ae28ac6e101160b550556" + }, + "author/harness-observations.json": { + "bytes": 1496, + "sha256": "6b6c5ac27f1a1a3646ef6c29eb9478e7215ee26a29d5f77844119c492e55fbef" + }, + "author/thread-event-loop.log": { + "bytes": 882, + "sha256": "fe86b9402d632b49719899d9482047ee0849e2969067e80f79e727a178057b46" + }, + "author/thread-isolated.log": { + "bytes": 10427, + "sha256": "dfffed04778b3b2845938ab83b959916ca0aa4310ab4006cd31d4b76f10f3a96" + }, + "independent/37443-candidate.log": { + "bytes": 1270, + "sha256": "3e4b3290f4d02af0cf1a6461560532dffcfb8cea4c5d5349da1d49113ba48e30" + }, + "independent/37443-manual-stall-receipt.json": { + "bytes": 780, + "sha256": "93854de2dba53424a7ed661724d1b2391a35491522a748d1dc6427f396e7ecb0" + }, + "independent/baseline-receipt.json": { + "bytes": 7323, + "sha256": "a6a5ed459c4f488fffe7808afa5a9471e5a4a86ed49baeb27e07c6e24ea3e508" + }, + "independent/baseline.log": { + "bytes": 675, + "sha256": "7bb3bcd44d35b3f2bc593d4092cad3b2cad89dce25dcf16a04e81890c810b1c7" + }, + "independent/c0b5530-candidate.log": { + "bytes": 4375, + "sha256": "6aae6bbe36f9f7070a42910ecbbf2297a3dd222d5834cbeabbd816e4003f39b4" + }, + "independent/c0b5530-eventloop-receipt.json": { + "bytes": 2679, + "sha256": "17a363b7ffee224a1f65f1eea6a61c4e83d47e8b30ae68aab07ccb2298c425d1" + }, + "independent/c0b5530-eventloop.log": { + "bytes": 375, + "sha256": "42724fb02c89311d1a34d82672cbc9c9034c7ac9a376ec365c4f6c53bc01ed52" + }, + "independent/c0b5530-failure-receipt.json": { + "bytes": 16780, + "sha256": "541c872437bf641d315a3c9f36b0d1e3c660d3ae3adc2b2c7ec6ec1c570aad40" + }, + "independent/methods/receive_history.py": { + "bytes": 23741, + "sha256": "b46094d3d823145aa07aa088371c6a63343ee7c5d8a06b254c6a4669f8c52da8" + }, + "independent/methods/receive_history_native.py": { + "bytes": 11292, + "sha256": "cb2e6486fc13e6e180fc6e8f83d690f3b3cab84faffce6a7c7b0e3fde791a3cd" + }, + "independent/methods/receive_qt_eventloop.py": { + "bytes": 6194, + "sha256": "f05476354e1d1e40478bcc4ed3e5e753bb3baa99fe1a822e3f12e15018236d7d" + }, + "independent/native-candidate-receipt.json": { + "bytes": 30728, + "sha256": "a555ed445c88a575aff3345222e182d06e3e3d2e535d027a40fa4d90056b6f2f" + }, + "independent/native-candidate.log": { + "bytes": 1543, + "sha256": "4136b7357f0cdba48032573a8f10fc2452b307db28ede09be8230835383e30ae" + }, + "publication-license-check.json": { + "bytes": 396, + "sha256": "e79c616da0229b52eae48a50ac286cf844f4e4e57f25310ac59e77cdacf625ad" + }, + "publication-method-adjustments.json": { + "bytes": 1135, + "sha256": "2dc41a21bb18101c40d8964f3ead9821462b701890b5e042d2bab3097a51b41a" + }, + "visual/details-log.png": { + "bytes": 35244, + "sha256": "b33e93d0026b163744737283234116d9332c4790dffc3cfd0caecad2d4935686" + }, + "visual/details-parameters.png": { + "bytes": 37469, + "sha256": "b5bb8407c06e29a89f47739358c8492d211be803a20e2ef164b00b70e3953484" + }, + "visual/details-visual-receipt.json": { + "bytes": 631, + "sha256": "f25badedc5c82769b9448fefa5521abd2135b907aee66cc025da90d147d416e8" + }, + "visual/details-visual.py": { + "bytes": 3668, + "sha256": "c747bcb5bf519b765186e93b4689666148f6bae1b4c45014adda424371c694ab" + }, + "visual/native-reopened-b.png": { + "bytes": 218488, + "sha256": "810766243e7848e2aa966a588c1c4e2245ad74526870a810232ce89db56635e8" + } + }, + "runtime_commit": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "source_base": "72c15d6b623e217291a824e4e4808a385df896a9" +} diff --git a/docs/evidence/analysis-history-401c5d17da79/author/author-correction-process.json b/docs/evidence/analysis-history-401c5d17da79/author/author-correction-process.json new file mode 100644 index 00000000..82b5908a --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/author-correction-process.json @@ -0,0 +1,17 @@ +{ + "exit": 0, + "elapsed": 4.036, + "command": [ + "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "-m", + "pytest", + "tests/ui/test_analysis_history.py", + "tests/ui/test_analysis_workbench.py", + "tests/ui/test_analysis_failure_notes.py", + "-q", + "-ra", + "-p", + "no:cacheprovider", + "--basetemp=/dev/shm/capturesuite-history-401c5d17da79/tmp/author-correction" + ] +} diff --git a/docs/evidence/analysis-history-401c5d17da79/author/author-correction.log b/docs/evidence/analysis-history-401c5d17da79/author/author-correction.log new file mode 100644 index 00000000..25b37635 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/author-correction.log @@ -0,0 +1,10 @@ +.............. [100%] +=============================== warnings summary =============================== +tests/ui/test_analysis_history.py::test_native_open_and_details_leave_the_package_unchanged + :488: DeprecationWarning: Type google._upb._message.MessageMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14. + +tests/ui/test_analysis_history.py::test_native_open_and_details_leave_the_package_unchanged + :488: DeprecationWarning: Type google._upb._message.ScalarMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14. + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +14 passed, 2 warnings in 3.21s diff --git a/docs/evidence/analysis-history-401c5d17da79/author/author-focused-2.log b/docs/evidence/analysis-history-401c5d17da79/author/author-focused-2.log new file mode 100644 index 00000000..62361817 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/author-focused-2.log @@ -0,0 +1,10 @@ +....... [100%] +=============================== warnings summary =============================== +tests/ui/test_analysis_history.py::test_native_open_and_details_leave_the_package_unchanged + :488: DeprecationWarning: Type google._upb._message.MessageMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14. + +tests/ui/test_analysis_history.py::test_native_open_and_details_leave_the_package_unchanged + :488: DeprecationWarning: Type google._upb._message.ScalarMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14. + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +7 passed, 2 warnings in 2.61s diff --git a/docs/evidence/analysis-history-401c5d17da79/author/baseline-history.py b/docs/evidence/analysis-history-401c5d17da79/author/baseline-history.py new file mode 100644 index 00000000..8cf22dbc --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/baseline-history.py @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""Existing-interface baseline: retained job is readable but not offered by Analysis.""" +import hashlib +import json +import os +from pathlib import Path +import shutil +import sys + +ROOT = Path(__file__).resolve().parents[1] +SOURCE = ROOT / 'source' +for package in ('capture_analysis', 'capture_session', 'capture_protocol'): + sys.path.insert(0, str(SOURCE / 'libs/python' / package)) +sys.path.insert(0, str(SOURCE / 'desktop')) +os.environ['QT_QPA_PLATFORM'] = 'offscreen' +for key, suffix in [('LOCALAPPDATA', 'local'), ('APPDATA', 'roaming'), ('XDG_CONFIG_HOME', 'config'), + ('XDG_DATA_HOME', 'data'), ('XDG_CACHE_HOME', 'cache'), ('MPLCONFIGDIR', 'mpl')]: + path = ROOT / 'tmp' / suffix + path.mkdir(exist_ok=True) + os.environ[key] = str(path) + +from capture_analysis import JobParams, run +from capture_desktop.screen_analysis import AnalysisScreen +from capture_desktop.state import CaptureState +from capture_desktop import theme +from PySide6.QtWidgets import QApplication, QPushButton + +package = ROOT / 'evidence/baseline-saved.mmsession' +shutil.copytree(SOURCE / 'tests/fixtures/mini_session', package) +def raw_hashes(): + return {p.relative_to(package).as_posix():hashlib.sha256(p.read_bytes()).hexdigest() + for p in sorted(package.rglob('*')) if p.is_file() and 'processing' not in p.relative_to(package).parts} +before = raw_hashes() +result = run(package, JobParams(command='qc', overwrite_job_id='retained-qc')) +assert before == raw_hashes() +app = QApplication([]) +theme.apply_theme(app, setting='dark') +screen = AnalysisScreen(CaptureState()) +screen.set_package(str(package)) +screen.resize(1220, 850) +screen.show() +app.processEvents() +assert not screen._last_job_dir +assert screen._inspector._meta.text() == 'No job loaded' +assert not screen._btn_open_job.isEnabled() +assert not hasattr(screen, '_history') +buttons = [b.text() for b in screen.findChildren(QPushButton)] +assert not any('saved' in b.casefold() or 'history' in b.casefold() for b in buttons) +screen.grab().save(str(ROOT/'evidence/baseline-no-history.png')) +# The existing reader already understands the retained job, isolating the UI gap. +screen._inspector.load_job_dir(result.job_dir) +assert 'job_id=retained-qc' in screen._inspector._meta.text() +assert before == raw_hashes() +receipt = {'source_commit':'72c15d6b623e217291a824e4e4808a385df896a9', + 'source_tree':'221cf5c7bb3c3392a7c4186ba0bcf5a8664135d1', + 'python':sys.version,'qt_platform':app.platformName(), + 'actual_job_status':result.status,'retained_job':str(result.job_dir), + 'baseline':'feature absent: reopening a package leaves gallery/inspector unbound', + 'existing_inspector_manual_control':True,'raw_unchanged':True, + 'buttons':buttons,'raw_sha256':before} +(ROOT/'evidence/baseline-receipt.json').write_text(json.dumps(receipt,indent=2)+'\n') +print(json.dumps({k:v for k,v in receipt.items() if k!='raw_sha256'},indent=2)) +screen.close() diff --git a/docs/evidence/analysis-history-401c5d17da79/author/baseline-receipt.json b/docs/evidence/analysis-history-401c5d17da79/author/baseline-receipt.json new file mode 100644 index 00000000..37f48433 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/baseline-receipt.json @@ -0,0 +1,34 @@ +{ + "source_commit": "72c15d6b623e217291a824e4e4808a385df896a9", + "source_tree": "221cf5c7bb3c3392a7c4186ba0bcf5a8664135d1", + "python": "3.12.14 (main, Aug 25 2026, 14:00:49) [Clang 22.1.3 ]", + "qt_platform": "offscreen", + "actual_job_status": "completed", + "retained_job": "/dev/shm/capturesuite-history-401c5d17da79/evidence/baseline-saved.mmsession/processing/jobs/retained-qc", + "baseline": "feature absent: reopening a package leaves gallery/inspector unbound", + "existing_inspector_manual_control": true, + "raw_unchanged": true, + "buttons": [ + "Use open session", + "Browse\u2026", + "Run", + "Cancel", + "Open job folder", + "Open QC report (HTML)", + "Save mapping preset" + ], + "raw_sha256": { + "events/annotations.json": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "events/checkpoints.json": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "events/sync_anchors.json": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "integrity.json": "af5d9bacd3eace7e831d48dee83eb5d9f578f4f4819d92218c4b55b0cb3ed556", + "manifest.json": "c5254d3e4c0bc6a0ecaef124dc12d88117d647928a8e1725b71429097438d380", + "sources/sim.emg.main/health/gaps.jsonl": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "sources/sim.emg.main/source.json": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10", + "sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649", + "sources/sim.emg.main/streams/sim.emg.main.batch/stream.json": "8f8c02b89fd93e55643151e5222488e1174dd97a6b7a74f3ae5da8215b4d68e1", + "sources/sim.imu.upper/source.json": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8", + "sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649", + "sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d" + } +} diff --git a/docs/evidence/analysis-history-401c5d17da79/author/candidate-correction-freeze.json b/docs/evidence/analysis-history-401c5d17da79/author/candidate-correction-freeze.json new file mode 100644 index 00000000..f8377a4b --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/candidate-correction-freeze.json @@ -0,0 +1,28 @@ +{ + "baseline": "72c15d6b623e217291a824e4e4808a385df896a9", + "previous_candidate": "c0b5530c03cce3e42a0430e5411cddf1df716e19", + "commit": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "tree": "3b3184b931a2aaf91beec36c953bff909a77f2f5", + "inputs": { + "desktop/capture_desktop/analysis_history.py": { + "sha256": "2e0db8cee59ef268d3c91ea0beac7d761d83a3003862841cc9d7f1782fd3543c", + "bytes": 6375 + }, + "desktop/capture_desktop/widgets_analysis_history.py": { + "sha256": "a3b77c87483c1412b50de7ddde1498f6bfd3968002fc3ac3bfa474a2477d9bc4", + "bytes": 8458 + }, + "desktop/capture_desktop/screen_analysis.py": { + "sha256": "98a704e31b14497e012fe5618ad47cc8a772bd2d59775826d71a5bdf41533211", + "bytes": 16407 + }, + "tests/ui/test_analysis_history.py": { + "sha256": "48175547922125c308fa49bbb84149e3dac8903902e7cc64fa7c15b4ca40eccd", + "bytes": 10465 + } + }, + "runtime": "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "focused_and_retained_tests": "14 passed in3.21s; no skips", + "worker_and_thread_cleanup_ast_identical_to_baseline": true, + "correction": "Refresh failed retained jobs in the failure slot; successful completion already refreshes there. Restore original thread-finished cleanup, eliminating added filesystem work after releasing worker references. Native worker and signal wiring are unchanged." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/author/candidate-source-freeze.json b/docs/evidence/analysis-history-401c5d17da79/author/candidate-source-freeze.json new file mode 100644 index 00000000..dd9c7fcb --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/candidate-source-freeze.json @@ -0,0 +1,26 @@ +{ + "baseline": "72c15d6b623e217291a824e4e4808a385df896a9", + "commit": "c0b5530c03cce3e42a0430e5411cddf1df716e19", + "tree": "c384c9553757fb1614405d124a5026ae49b4be71", + "inputs": { + "desktop/capture_desktop/analysis_history.py": { + "sha256": "2e0db8cee59ef268d3c91ea0beac7d761d83a3003862841cc9d7f1782fd3543c", + "bytes": 6375 + }, + "desktop/capture_desktop/widgets_analysis_history.py": { + "sha256": "a3b77c87483c1412b50de7ddde1498f6bfd3968002fc3ac3bfa474a2477d9bc4", + "bytes": 8458 + }, + "desktop/capture_desktop/screen_analysis.py": { + "sha256": "4a2e3eaee50fba5236b5567be993582a557de6fe2c62cc0bf3f424483beefb2b", + "bytes": 16407 + }, + "tests/ui/test_analysis_history.py": { + "sha256": "eabe6a4e663307965ce00a1f9032325bfc7be6357b7a3a91b79820cafc4c0a97", + "bytes": 9023 + } + }, + "runtime": "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "focused_tests": "7 passed in 2.61s; no skips", + "harness_notes": "Replaced QTest.qWait polling with QEventLoop plus settling cleanup after a timeout/unsafe teardown; production worker and signal wiring remain baseline bytes." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/author/harness-observations.json b/docs/evidence/analysis-history-401c5d17da79/author/harness-observations.json new file mode 100644 index 00000000..bbb9bec3 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/harness-observations.json @@ -0,0 +1,23 @@ +{ + "schema": "capturesuite.history.harness-observations.v1", + "first_author_combined": { + "outcome": "Six focused cases completed, then process exited139 under manual processEvents/QTest.qWait; original output was retained in tool transcript only. No raw-file pass is claimed." + }, + "isolated_author_manual": { + "outcome": "Child exited-6. Pytest fixture teardown ran while first-time pandas import was still active in the worker after the15-second polling deadline.", + "raw_log": "thread-isolated.log" + }, + "author_native_loop": { + "outcome": "Unchanged production bytes passed the isolated real worker through QEventLoop in2.19s and all seven original focused cases in2.61s.", + "raw_logs": [ + "thread-event-loop.log", + "author-focused-2.log" + ] + }, + "transient_enospc": { + "outcome": "Shared tmpfs filled during an attempted combined run/receipt write; stdout/XML/process files were zero-length. No retained test result exists for that attempt. No files outside this lane were removed or changed." + }, + "independent_manual_and_native": { + "outcome": "See independent exact raw logs: c0b5530 manual pumping exited139 after15 checks, whereas its genuine QApplication.exec control passed5 checks. Corrected37443 manual pumping stalled after15 checks and was stopped(exit130); its full QApplication.exec/QTimer state machine passed19 checks. The manual outcomes are harness limitations and are not treated as proof of a native application defect." + } +} diff --git a/docs/evidence/analysis-history-401c5d17da79/author/thread-event-loop.log b/docs/evidence/analysis-history-401c5d17da79/author/thread-event-loop.log new file mode 100644 index 00000000..46c92add --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/thread-event-loop.log @@ -0,0 +1,10 @@ +. [100%] +=============================== warnings summary =============================== +tests/ui/test_analysis_history.py::test_real_threaded_completion_populates_history + :488: DeprecationWarning: Type google._upb._message.MessageMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14. + +tests/ui/test_analysis_history.py::test_real_threaded_completion_populates_history + :488: DeprecationWarning: Type google._upb._message.ScalarMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14. + +-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +1 passed, 2 warnings in 2.19s diff --git a/docs/evidence/analysis-history-401c5d17da79/author/thread-isolated.log b/docs/evidence/analysis-history-401c5d17da79/author/thread-isolated.log new file mode 100644 index 00000000..897576ca --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/author/thread-isolated.log @@ -0,0 +1,99 @@ +FFatal Python error: Aborted + +Thread 0x00007fed030eb6c0 (most recent call first): + File "", line 1191 in get_data + File "", line 1091 in get_code + File "", line 995 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pandas/core/groupby/generic.py", line 64 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pandas/core/groupby/__init__.py", line 1 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pandas/core/api.py", line 46 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pandas/__init__.py", line 46 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/features/emg.py", line 7 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/plugins/handlers.py", line 14 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/pipeline.py", line 16 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/jobs.py", line 22 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/__init__.py", line 5 in + File "", line 488 in _call_with_frames_removed + File "", line 999 in exec_module + File "", line 935 in _load_unlocked + File "", line 1331 in _find_and_load_unlocked + File "", line 1360 in _find_and_load + File "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/screen_analysis.py", line 61 in run + +Current thread 0x00007fed24ed9740 (most recent call first): + File "/dev/shm/capturesuite-history-401c5d17da79/source/tests/conftest.py", line 54 in qapp + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/fixtures.py", line 1014 in _teardown_yield_fixture + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/fixtures.py", line 1156 in finish + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/runner.py", line 568 in teardown_exact + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/runner.py", line 199 in pytest_runtest_teardown + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_callers.py", line 121 in _multicall + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_hooks.py", line 512 in __call__ + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/runner.py", line 250 in + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/runner.py", line 361 in from_call + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/runner.py", line 249 in call_and_report + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/runner.py", line 144 in runtestprotocol + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/runner.py", line 118 in pytest_runtest_protocol + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_callers.py", line 121 in _multicall + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_hooks.py", line 512 in __call__ + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/main.py", line 408 in pytest_runtestloop + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_callers.py", line 121 in _multicall + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_hooks.py", line 512 in __call__ + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/main.py", line 384 in _main + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/main.py", line 330 in wrap_session + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/main.py", line 377 in pytest_cmdline_main + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_callers.py", line 121 in _multicall + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_manager.py", line 120 in _hookexec + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pluggy/_hooks.py", line 512 in __call__ + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/config/__init__.py", line 229 in _main + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/_pytest/config/__init__.py", line 253 in _console_main + File "/workspace/scratch/234cae4aee53/capturesuite-venv/lib/python3.12/site-packages/pytest/__main__.py", line 9 in + File "", line 88 in _run_code + File "", line 198 in _run_module_as_main + +Extension modules: shiboken6.Shiboken, PySide6.QtCore, PySide6.QtGui, PySide6.QtWidgets, google._upb._message, numpy._core._multiarray_umath, numpy.linalg._umath_linalg, PySide6.QtSvg, PySide6.QtOpenGLWidgets, PySide6.QtTest, PySide6.QtOpenGL, PIL._imaging, kiwisolver._cext, pyarrow.lib, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._pcg64, numpy.random._generator, numpy.random._mt19937, numpy.random._philox, numpy.random._sfc64, numpy.random.mtrand, _cyutility, pandas._libs._cyutility, pandas._libs.tslibs.ccalendar, pandas._libs.tslibs.np_datetime, pandas._libs.tslibs.dtypes, pandas._libs.tslibs.base, pandas._libs.tslibs.nattype, pandas._libs.tslibs.timezones, pandas._libs.properties, pandas._libs.tslibs.fields, pandas._libs.tslibs.timedeltas, pandas._libs.tslibs.tzconversion, pandas._libs.tslibs.timestamps, pandas._libs.tslibs.offsets, pandas._libs.tslibs.strptime, pandas._libs.tslibs.parsing, pandas._libs.tslibs.conversion, pandas._libs.tslibs.period, pandas._libs.tslibs.vectorized, pandas._libs.ops_dispatch, pandas._libs.missing, pandas._libs.hashtable, pandas._libs.algos, pandas._libs.interval, pandas._libs.lib, pyarrow._compute, pandas._libs.ops, pandas._libs.hashing, pandas._libs.arrays, pandas._libs.tslib, pandas._libs.sparse, pandas._libs.internals (total: 55) diff --git a/docs/evidence/analysis-history-401c5d17da79/current-numeric/README.md b/docs/evidence/analysis-history-401c5d17da79/current-numeric/README.md new file mode 100644 index 00000000..d3168f44 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-numeric/README.md @@ -0,0 +1,72 @@ +# Current numeric output: retained gallery limitation + +During the final current-parent check, main advanced to +`0ed1ccaa023a5327495565d59e1dd0b28b2ee5bd` (tree +`b8990a709744eab58b25b875596c79d0865cce4a`) by accepting numeric analysis +[PR #49](https://github.com/Jacob-Met/CaptureSuite/pull/49), owned by +`estate-e82707f2bc62` under issue #43. The six accepted numeric production +files remain unchanged in this history publication. + +Those handlers write channel figures below +`figures/numeric/source-…/stream-…/channel_*.png`. The existing +`FigureGallery.load_job_dir` enumerates only `figures/*.png`. Its exact +unchanged source is: + +- Path: `desktop/capture_desktop/widgets_analysis_plots.py` +- Git blob: `bb6c3033b5e4ed96a2e08857d38715b836926bf5` +- SHA-256: `85c73f881ee7d60ef2f868f7ff73fc57c0a4ef99a717f7f5015534db23e1ab86` + +## One native reproduction + +Runtime tree `210832e8a07ccc6dff8ead12e9bf45dde3b31652` combines that +actual main with the unchanged, accepted history runtime `37443f0d`. +The receiver uses the current accepted numeric test's small MCAP/protobuf +fixture helpers, then invokes the real `run(..., JobParams(command="all"))`. +It does not run the numeric owner's test suite or change its implementation. + +The actual job writes two valid channel PNGs. Opening the retained job through +the native history selects the correct job and manifest in the inspector, +but the gallery contains only its **Sync** tab. Directly loading the same +job into a standalone instance of the unchanged gallery produces the same +missing channel tabs. This locates the gap in the pre-existing current-main +gallery reader rather than in saved-history selection. + +The process exits 1 with **six positive checks and one failed presentation +check**, no exceptions. All 141 frozen source/fixture files and every generated +package/job byte remain unchanged while viewing; history starts no computation +thread. The only stderr is the standard offscreen `propagateSizeHints` warning. +The current history hooks, job identities and read-only behavior remain intact. + +The snapshot `numeric-run/numeric-history-gap.png` is the first event-callback +frame before later paint/layout settling. Its visible Sync-only tab state is +supporting evidence; the exact widget tab counts and two valid on-disk PNGs in +`numeric-run/receipt.json` are the receiving proof. This frame is not a visual +layout qualification. + +## Publication boundary + +This history PR preserves its three-file production scope and the existing +gallery source. Nested numeric channel figures remain listed in the job's +saved output inventory and accessible in its job folder; the Sync result can +be selected, while individual nested channel tabs await a separately +coordinated gallery repair. This publication does not claim all current +numeric figures are displayed in the gallery. + +The e43 QC/2 success remains separately pinned under `../current-qc/`. +Neither that success nor this current-main finding replaces the author's +14-test receipt or the independent 19-check native history receipt. + +## Exact pins + +| Artifact | SHA-256 | +| --- | --- | +| `check_numeric_gallery.py` | `c6d9c3aaf73e1cfef62c86dc36491440d3d6c6001996f149e2b978c97e2959d8` | +| `numeric-run/receipt.json` | `8e9f7cb7a8ce219b4fea8090cff5e1c602b6d4fb100a6d011983594206e3ef29` | +| `numeric.stdout.log` | `9d5c3d3907cd95f62cf380cc2b5196c33f183bfdeb5665ad0c3af42f2855eeaa` | +| `numeric.stderr.log` | `caeb11f6473c6c7125dd27478e588b85ffd6b31784e9adb1371a60f1661eb00f` | + +The source manifest records the complete 141-file projection, including the +unchanged accepted fixture helper. `process.json` retains the exact command +and 4.471-second execution. Replaying `check_numeric_gallery.py` uses the same +`--source`, `--inputs`, and new private `--output` directory contract as the +current-QC companion. Its output must be outside the verified source. diff --git a/docs/evidence/analysis-history-401c5d17da79/current-numeric/check_numeric_gallery.py b/docs/evidence/analysis-history-401c5d17da79/current-numeric/check_numeric_gallery.py new file mode 100644 index 00000000..ab472b81 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-numeric/check_numeric_gallery.py @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""Observe current numeric artifacts through history and the unchanged gallery.""" +from pathlib import Path +import argparse +import hashlib +import importlib.util +import json +import os +import sys +import traceback + + +def hashes(root): + return {p.relative_to(root).as_posix():hashlib.sha256(p.read_bytes()).hexdigest() + for p in sorted(root.rglob('*')) if p.is_file()} + + +def main(): + parser=argparse.ArgumentParser(description=__doc__) + parser.add_argument('--source',type=Path,required=True) + parser.add_argument('--inputs',type=Path,required=True) + parser.add_argument('--output',type=Path,required=True) + args=parser.parse_args();source=args.source.resolve();out=args.output.resolve() + assert not out.exists() and source not in out.parents and out!=source + manifest=json.loads(args.inputs.read_text());expected={r['path']:r['sha256'] for r in manifest['files']} + assert hashes(source)==expected + out.mkdir(parents=True,exist_ok=False) + for key,leaf in [('LOCALAPPDATA','local'),('APPDATA','roaming'),('XDG_CONFIG_HOME','config'),('XDG_DATA_HOME','data'),('XDG_CACHE_HOME','cache'),('MPLCONFIGDIR','mpl')]: + p=out/'state'/leaf;p.mkdir(parents=True);os.environ[key]=str(p) + os.environ['QT_QPA_PLATFORM']='offscreen';sys.dont_write_bytecode=True + for rel in reversed(['desktop','libs/python/capture_analysis','libs/python/capture_session','libs/python/capture_protocol','libs/python/capture_protocol/capture_protocol/generated','libs/python/capture_worker']): + sys.path.insert(0,str(source/rel)) + report={'canonical_main':manifest['canonical_parent'],'author_source':manifest['author_source'],'runtime_tree':manifest['composition_tree'],'checks':[],'errors':[],'method_sha256':hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),'source_inputs_sha256':hashlib.sha256(args.inputs.read_bytes()).hexdigest()} + def check(name,value):report['checks'].append({'name':name,'passed':bool(value)}) + status=1 + try: + import PySide6 + from PySide6.QtCore import QTimer,QCoreApplication,QEvent + from PySide6.QtWidgets import QApplication + from capture_analysis import run,JobParams + from capture_desktop import theme + from capture_desktop.screen_analysis import AnalysisScreen + from capture_desktop.state import CaptureState + from capture_desktop.widgets_analysis_plots import FigureGallery + fixture_path=source/'tests/analysis/test_numeric_batch_pipeline.py' + spec=importlib.util.spec_from_file_location('accepted_numeric_fixture',fixture_path) + helper=importlib.util.module_from_spec(spec);spec.loader.exec_module(helper) + package=out/'numeric.mmsession';package.mkdir() + (package/'manifest.json').write_text(json.dumps({'sessionId':'history.numeric.current','state':'sealed'})+'\n') + stream=package/'sources/lsl/streams/numeric';stream.mkdir(parents=True) + helper._write_mcap(stream/'segments/000000.mcap',[(1_000_000_000,helper._batch())]) + (stream/'stream.json').write_text(json.dumps({'sourceId':'lsl','streamId':'numeric.stream','modality':'eeg','dataSchemaId':'generic.numeric_batch/1','nominalRateHz':2.0,'units':'V','dimensions':[2]})+'\n') + result=run(package,JobParams(command='all',overwrite_job_id='retained-numeric')) + job=result.job_dir + pngs=sorted(p for p in (job/'figures').rglob('*.png') if p.name!='sync_dashboard.png') + report['figure_paths']=[p.relative_to(job).as_posix() for p in pngs] + report['job_manifest']=json.loads((job/'job_manifest.json').read_text()) + check('current accepted numeric pipeline creates two real channel figures',len(pngs)==2 and all(p.read_bytes().startswith(b'\x89PNG\r\n\x1a\n') for p in pngs)) + before=hashes(package) + app=QApplication([]);theme.apply_theme(app,setting='dark');screen=AnalysisScreen(CaptureState());screen.resize(1280,820) + direct=FigureGallery();direct.resize(900,620) + def receive(): + try: + screen.set_package(str(package));screen.show();screen._history._open.click() + check('history explicitly selects the retained numeric job',screen._history.loaded_job_id=='retained-numeric' and screen._last_job_dir==str(job)) + check('inspector receives that saved manifest', 'job_id=retained-numeric' in screen._inspector._meta.text()) + history_tabs=[screen._gallery._tabs.tabText(i) for i in range(screen._gallery._tabs.count())] + report['history_gallery_tabs']=history_tabs + check('history gallery presents both existing numeric channel figures',screen._gallery._tabs.count()-1==len(pngs)) + direct.load_job_dir(job) + report['direct_gallery_tabs']=[direct._tabs.tabText(i) for i in range(direct._tabs.count())] + check('unchanged direct gallery reproduces the same omitted numeric figures',direct._tabs.count()==1 and report['direct_gallery_tabs']==history_tabs and len(pngs)==2) + check('native history browsing starts no computation thread',screen._thread is None) + check('native viewing preserves every generated and captured byte',hashes(package)==before) + screen.grab().save(str(out/'numeric-history-gap.png')) + except BaseException:report['errors'].append(traceback.format_exc()) + finally:screen.close();direct.close();app.quit() + QTimer.singleShot(0,receive);loop_code=app.exec() + screen.deleteLater();direct.deleteLater();QCoreApplication.sendPostedEvents(None,QEvent.Type.DeferredDelete);app.processEvents() + report.update({'event_loop_exit':loop_code,'pyside6':PySide6.__version__,'python':sys.version,'package_hashes':before,'fixture_helper_sha256':hashlib.sha256(fixture_path.read_bytes()).hexdigest()}) + status=0 if not report['errors'] and all(c['passed'] for c in report['checks']) else 1 + except BaseException:report['errors'].append(traceback.format_exc()) + report['source_unchanged']=hashes(source)==expected + report['exit_code']=status;report['passed']=sum(c['passed'] for c in report['checks']);report['failed']=sum(not c['passed'] for c in report['checks']) + (out/'receipt.json').write_text(json.dumps(report,indent=2)+'\n') + print(json.dumps({k:report[k] for k in ['passed','failed','source_unchanged','exit_code']})) + return status + + +if __name__=='__main__':raise SystemExit(main()) diff --git a/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric-run/numeric-history-gap.png b/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric-run/numeric-history-gap.png new file mode 100644 index 0000000000000000000000000000000000000000..478f1af250552ccbe6e0459e596bf5ba00ac2aa2 GIT binary patch literal 85925 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 literal 0 HcmV?d00001 diff --git a/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric-run/receipt.json b/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric-run/receipt.json new file mode 100644 index 00000000..bae5c434 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric-run/receipt.json @@ -0,0 +1,214 @@ +{ + "canonical_main": "0ed1ccaa023a5327495565d59e1dd0b28b2ee5bd", + "author_source": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "runtime_tree": "210832e8a07ccc6dff8ead12e9bf45dde3b31652", + "checks": [ + { + "name": "current accepted numeric pipeline creates two real channel figures", + "passed": true + }, + { + "name": "history explicitly selects the retained numeric job", + "passed": true + }, + { + "name": "inspector receives that saved manifest", + "passed": true + }, + { + "name": "history gallery presents both existing numeric channel figures", + "passed": false + }, + { + "name": "unchanged direct gallery reproduces the same omitted numeric figures", + "passed": true + }, + { + "name": "native history browsing starts no computation thread", + "passed": true + }, + { + "name": "native viewing preserves every generated and captured byte", + "passed": true + } + ], + "errors": [], + "method_sha256": "c6d9c3aaf73e1cfef62c86dc36491440d3d6c6001996f149e2b978c97e2959d8", + "source_inputs_sha256": "2c9e35a372b29e6f4d93e5dd7a844b09fe49129fbf89a5c6e569f984aedaee6b", + "figure_paths": [ + "figures/numeric/source-6c736c/stream-6e756d657269632e73747265616d/channel_0.png", + "figures/numeric/source-6c736c/stream-6e756d657269632e73747265616d/channel_1.png" + ], + "job_manifest": { + "analysisGrids": [], + "captureAnalysisVersion": "0.1.0", + "createdUtc": "2026-10-08T13:22:43Z", + "errors": [], + "evalWindowCount": null, + "featureTables": [ + { + "featureSchemaVersion": 1, + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.parquet", + "rows": 3 + } + ], + "gapPolicy": "mask", + "gapSummary": { + "closed": 0, + "maskedNs": 0, + "open": 0, + "validFraction": null + }, + "jobId": "retained-numeric", + "kinematicsRows": null, + "manifestSha256": "399b408a7bcb1cbee8062a926f52b2ceff553fdbf4504d92a629b83898eb4b60", + "mlBundleWindowCount": null, + "modalities": [ + "eeg" + ], + "outputs": [ + { + "bytes": 254, + "kind": "params", + "relativePath": "params.json", + "sha256": "962d5067fb396fca7a5d207bae2aeff4ea16f3218396824de0da670f16b67dc3" + }, + { + "bytes": 1127, + "kind": "qc_json", + "relativePath": "reports/qc.json", + "sha256": "6a7e1c4191f43ce87c04344f81d4b4ffa61b2fa383de413650bdcc02a21b3ba2" + }, + { + "bytes": 2214, + "kind": "qc_html", + "relativePath": "reports/qc.html", + "sha256": "43b9cfbc29c185464e85873ac6c4bfd45a0fa3d45f259d7ea59dcae9464625e5" + }, + { + "bytes": 5358, + "kind": "feature_parquet", + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.parquet", + "sha256": "b25e995662e343e5660be848fac61eac15dd63d904ea1fa8d4b58fe66dc68b84" + }, + { + "bytes": 307, + "kind": "feature_csv", + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.csv", + "sha256": "9cae194fe5eabbdd3d804b734e609ea732d05f9b5885f6e51dcea9f5840230fe" + }, + { + "bytes": 38048, + "kind": "figure", + "relativePath": "figures/numeric/source-6c736c/stream-6e756d657269632e73747265616d/channel_0.png", + "sha256": "255a352977baf12c5714f71c327cac9ec6fe96377378e7d789433de6335bc73a" + }, + { + "bytes": 38330, + "kind": "figure", + "relativePath": "figures/numeric/source-6c736c/stream-6e756d657269632e73747265616d/channel_1.png", + "sha256": "ae7fd0d484e1dd7756a3a0c599de8aea09ede34d0ad1644775c0b95bce3f6195" + }, + { + "bytes": 2691, + "kind": "feature_schema", + "relativePath": "features/_schema.json", + "sha256": "ea7b96fa667e83b0379515745ee23e659bd640497378b04c267da593d584e264" + }, + { + "bytes": 32213, + "kind": "figure", + "relativePath": "figures/sync_dashboard.png", + "sha256": "e801135335d3a6e50353d82b039a14217f7fe6f931a1f9daa1f37de3ab0e6b02" + }, + { + "bytes": 540, + "kind": "sync_series", + "relativePath": "figures/sync_dashboard_series.json", + "sha256": "1bc0a860646508a6001aed0d312d42338f8b2e9c93592cf5adc7dbeab2277554" + }, + { + "bytes": 4166, + "kind": "manifest", + "relativePath": "job_manifest.json", + "sha256": "a3fa5a3115667361cbaa2ad0b701b50f37a9096b8f5391f9bd7f846bce2447ae" + } + ], + "packagePath": "/dev/shm/hamon-401c5d17da79-capture-history-pr/latest-boundary/numeric-run/numeric.mmsession", + "packageState": "sealed", + "paramsDigest": "fbbd87f4d0bdf05be752987d8e20dfb29df32e3da588706e698f21aa5567f604", + "pluginIds": [ + "emg.envelope.v1", + "imu.kinematics.v1", + "radar.rd_energy.v1", + "radar_doppler.mag.v1", + "video.timing_qc.v1", + "numeric.basic.v1", + "test.dummy.feature.v1" + ], + "pluginManifestVersion": "1.0.0", + "poseJobId": null, + "poseModelId": null, + "poseTables": [], + "schemaId": "capture.analysis_job/1", + "sessionId": "history.numeric.current", + "sourcesSelected": [ + "lsl" + ], + "status": "completed_with_warnings", + "syncAnchorsApplied": { + "anchors": [], + "applied": false + }, + "timeRange": { + "checkpointIds": [], + "endSessionNs": 4611686018427387903, + "mode": "full", + "startSessionNs": -4611686018427387903 + }, + "tooling": { + "captureAnalysis": "0.1.0", + "matplotlib": "3.11.2", + "numpy": "2.5.3", + "pandas": "3.0.6", + "platform": "Linux-6.18.44-x86_64-with-glibc2.39", + "python": "3.12.14", + "scipy": "1.18.1" + }, + "warnings": [ + "package state is 'sealed' (prefer finalized)", + "package duration_ns is unknown/zero \u2014 analysis uses an open time window (integrity entries lack endSessionTimeNs)" + ] + }, + "history_gallery_tabs": [ + "Sync" + ], + "direct_gallery_tabs": [ + "Sync" + ], + "event_loop_exit": 0, + "pyside6": "6.11.2", + "python": "3.12.14 (main, Aug 25 2026, 14:00:49) [Clang 22.1.3 ]", + "package_hashes": { + "manifest.json": "399b408a7bcb1cbee8062a926f52b2ceff553fdbf4504d92a629b83898eb4b60", + "processing/jobs/retained-numeric/features/_schema.json": "ea7b96fa667e83b0379515745ee23e659bd640497378b04c267da593d584e264", + "processing/jobs/retained-numeric/features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.csv": "9cae194fe5eabbdd3d804b734e609ea732d05f9b5885f6e51dcea9f5840230fe", + "processing/jobs/retained-numeric/features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.parquet": "b25e995662e343e5660be848fac61eac15dd63d904ea1fa8d4b58fe66dc68b84", + "processing/jobs/retained-numeric/figures/numeric/source-6c736c/stream-6e756d657269632e73747265616d/channel_0.png": "255a352977baf12c5714f71c327cac9ec6fe96377378e7d789433de6335bc73a", + "processing/jobs/retained-numeric/figures/numeric/source-6c736c/stream-6e756d657269632e73747265616d/channel_1.png": "ae7fd0d484e1dd7756a3a0c599de8aea09ede34d0ad1644775c0b95bce3f6195", + "processing/jobs/retained-numeric/figures/sync_dashboard.png": "e801135335d3a6e50353d82b039a14217f7fe6f931a1f9daa1f37de3ab0e6b02", + "processing/jobs/retained-numeric/figures/sync_dashboard_series.json": "1bc0a860646508a6001aed0d312d42338f8b2e9c93592cf5adc7dbeab2277554", + "processing/jobs/retained-numeric/job_manifest.json": "32dd2883bc55717ef813f36930eed5598124f27fa2a9a7a9817e750cd59bcb6d", + "processing/jobs/retained-numeric/logs/job.log": "7edc38094b8619545017aa8f12c4d0179ab43474343e25d483918f32d48b778a", + "processing/jobs/retained-numeric/params.json": "962d5067fb396fca7a5d207bae2aeff4ea16f3218396824de0da670f16b67dc3", + "processing/jobs/retained-numeric/reports/qc.html": "43b9cfbc29c185464e85873ac6c4bfd45a0fa3d45f259d7ea59dcae9464625e5", + "processing/jobs/retained-numeric/reports/qc.json": "6a7e1c4191f43ce87c04344f81d4b4ffa61b2fa383de413650bdcc02a21b3ba2", + "sources/lsl/streams/numeric/segments/000000.mcap": "f3df8e3cc95f76462c502935aad5abafd4392ed3224c239775650c5b49bcd18f", + "sources/lsl/streams/numeric/stream.json": "1adfb22cb81843c0e5bef319c9c2268ea2746e930232f6d89e154d133e0fa885" + }, + "fixture_helper_sha256": "43369bd0fea48d2c8b7dee1d8128b3bb131b508b7b0a14512fc457fcfdb0ba3c", + "source_unchanged": true, + "exit_code": 1, + "passed": 6, + "failed": 1 +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric.stderr.log b/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric.stderr.log new file mode 100644 index 00000000..09ad4161 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric.stderr.log @@ -0,0 +1 @@ +This plugin does not support propagateSizeHints() diff --git a/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric.stdout.log b/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric.stdout.log new file mode 100644 index 00000000..cb5b3493 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-numeric/numeric.stdout.log @@ -0,0 +1 @@ +{"passed": 6, "failed": 1, "source_unchanged": true, "exit_code": 1} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-numeric/process.json b/docs/evidence/analysis-history-401c5d17da79/current-numeric/process.json new file mode 100644 index 00000000..035a9ec6 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-numeric/process.json @@ -0,0 +1,17 @@ +{ + "command": [ + "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "-B", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/latest-boundary/check_numeric_gallery.py", + "--source", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/latest-boundary/source", + "--inputs", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/latest-boundary/source-inputs.json", + "--output", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/latest-boundary/numeric-run" + ], + "exit_code": 1, + "seconds": 4.471, + "stdout_sha256": "9d5c3d3907cd95f62cf380cc2b5196c33f183bfdeb5665ad0c3af42f2855eeaa", + "stderr_sha256": "caeb11f6473c6c7125dd27478e588b85ffd6b31784e9adb1371a60f1661eb00f" +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-numeric/source-inputs.json b/docs/evidence/analysis-history-401c5d17da79/current-numeric/source-inputs.json new file mode 100644 index 00000000..10d5bd06 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-numeric/source-inputs.json @@ -0,0 +1,994 @@ +{ + "canonical_parent": "0ed1ccaa023a5327495565d59e1dd0b28b2ee5bd", + "author_source": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "composition_tree": "210832e8a07ccc6dff8ead12e9bf45dde3b31652", + "files": [ + { + "path": "desktop/capture_desktop/__init__.py", + "mode": "100644", + "git_blob": "48777bd04b62e3b3b877e12311f7257819ab3a07", + "sha256": "8426c94323c4cca0879b8612345e3577d0a75f6239237a28d79d94a42004c3b5", + "bytes": 119 + }, + { + "path": "desktop/capture_desktop/__main__.py", + "mode": "100644", + "git_blob": "f78ccce984b725bf7263407d5b4b2d4c56131433", + "sha256": "8dbad73a7373565a3513ccbb613f11bffdd13a05861c3e8e07392b8d51008aa2", + "bytes": 723 + }, + { + "path": "desktop/capture_desktop/analysis_history.py", + "mode": "100644", + "git_blob": "1b8fd23aee632cc3af19990b9d7685c6a3ed1b5e", + "sha256": "2e0db8cee59ef268d3c91ea0beac7d761d83a3003862841cc9d7f1782fd3543c", + "bytes": 6375 + }, + { + "path": "desktop/capture_desktop/app.py", + "mode": "100644", + "git_blob": "3e6f0d9f31032eb51ddd0ac7deedc3d00d0d386e", + "sha256": "52a6b8d9844d8e0f9f9f1e07f516bf234cf104fdeb85dd5ea5acaa69970235f2", + "bytes": 46414 + }, + { + "path": "desktop/capture_desktop/daemon_link.py", + "mode": "100644", + "git_blob": "620e5a753fbd8448c3a57fcfa6a8b8540ac0bcd0", + "sha256": "ab76628bbe0231c7e5e4d570f2abed01100dddd6a24bb62020b670a6b62427dd", + "bytes": 10899 + }, + { + "path": "desktop/capture_desktop/export_wizard.py", + "mode": "100644", + "git_blob": "b22d0098eb9af3860c654591e411dbab68a0f05d", + "sha256": "fb957ff184109bcb4e379dde30414048e855c93ec390f9b50c7ab603c3cd4e30", + "bytes": 6734 + }, + { + "path": "desktop/capture_desktop/main.py", + "mode": "100644", + "git_blob": "90ad2adebae1f52ffabb889efe43a31dca1b6454", + "sha256": "e61c29a1925f8d85b24438f087dec360a4481a32e0dc2bd8ed8feb6629026e84", + "bytes": 1059 + }, + { + "path": "desktop/capture_desktop/persistence.py", + "mode": "100644", + "git_blob": "2f2da2bfda654009baa0e723465c82c1690a0676", + "sha256": "cdb1fa0094fec72543d5051435850e51d78d79d4bde8d5c83520fa072a2c74c4", + "bytes": 3379 + }, + { + "path": "desktop/capture_desktop/schema_form.py", + "mode": "100644", + "git_blob": "2d5fa62b1448e168e639e3e8879989a3461e1053", + "sha256": "7d825b5dc7566d630f31775df6fcc9def1e916eaff5be17a552bf89f28b3418b", + "bytes": 12206 + }, + { + "path": "desktop/capture_desktop/screen_analysis.py", + "mode": "100644", + "git_blob": "966f89f8cfad679a4a461900569365c50476581b", + "sha256": "98a704e31b14497e012fe5618ad47cc8a772bd2d59775826d71a5bdf41533211", + "bytes": 16407 + }, + { + "path": "desktop/capture_desktop/screen_capture.py", + "mode": "100644", + "git_blob": "b2d3cf05d57484f5efdbb0df85e5f0a065dab3d9", + "sha256": "4e101ddeeaed7f7f2b4ec2ab2e4b1f4f55ebb86f73b394d25cfd2b904cd2572e", + "bytes": 34181 + }, + { + "path": "desktop/capture_desktop/screen_presets.py", + "mode": "100644", + "git_blob": "c143fb87629fb90f656a7a3b4b9f3c136b03f596", + "sha256": "b62d6f4bef6c1f0fc04b9eaf6a8afd1b2eeb17f6ce14946a06b0495ba33d402c", + "bytes": 5230 + }, + { + "path": "desktop/capture_desktop/screen_review.py", + "mode": "100644", + "git_blob": "88a902ca7699faa2964f3fc22ec3348a339905a4", + "sha256": "e5aff59de4b194123ca4c4518b34e7b6103326fbd6b0280e2122d984d01072ec", + "bytes": 7003 + }, + { + "path": "desktop/capture_desktop/screen_settings.py", + "mode": "100644", + "git_blob": "fe6d1e8884b7300e4cb5039b8e86679339e43b4d", + "sha256": "519436946827fac53d0be68270c2929bd1ce615a58b2372e9e3fc10619a7ba6e", + "bytes": 4581 + }, + { + "path": "desktop/capture_desktop/screen_setup.py", + "mode": "100644", + "git_blob": "1df45aac30d63d6ab2e8ddc7efe0db394c513ab1", + "sha256": "01eb01ffffe835fcf5d26120d508800cc3cdac1e91ffaa3d0d2fa669c6326182", + "bytes": 11452 + }, + { + "path": "desktop/capture_desktop/state.py", + "mode": "100644", + "git_blob": "95046ba5ef7f7bbf5685a54b7ae8fd400814148c", + "sha256": "97fc98498f4553fc7f052d0dc4db992cf2fc136ba7c4405cd275bd156c74e314", + "bytes": 17906 + }, + { + "path": "desktop/capture_desktop/theme.py", + "mode": "100644", + "git_blob": "e309ce92bf66f65ca7c111698e1f536f05e4dca9", + "sha256": "c77f24e1afeb06400385bd0d535800f13dc15d972891e1ff8af504cbe5c818f3", + "bytes": 12072 + }, + { + "path": "desktop/capture_desktop/widgets_analysis_history.py", + "mode": "100644", + "git_blob": "8798627cd7d694c5a09c3c402a739a4ec45b6574", + "sha256": "a3b77c87483c1412b50de7ddde1498f6bfd3968002fc3ac3bfa474a2477d9bc4", + "bytes": 8458 + }, + { + "path": "desktop/capture_desktop/widgets_analysis_jobs.py", + "mode": "100644", + "git_blob": "c4d2f4513032d744f1f8066f0c887cda71d9b911", + "sha256": "5cdea6045456e61a58b5525dd224a22a140962d31d2adc5b0102168444468f98", + "bytes": 6304 + }, + { + "path": "desktop/capture_desktop/widgets_analysis_plots.py", + "mode": "100644", + "git_blob": "bb6c3033b5e4ed96a2e08857d38715b836926bf5", + "sha256": "85c73f881ee7d60ef2f868f7ff73fc57c0a4ef99a717f7f5015534db23e1ab86", + "bytes": 9382 + }, + { + "path": "desktop/capture_desktop/widgets_mappings.py", + "mode": "100644", + "git_blob": "62dd1b137ffc54a05aa81f37eb8627dd12e0032a", + "sha256": "89808d37cb0fce476665a24766963c7a509f5b1802d05dedbf9ca44351081f4b", + "bytes": 3658 + }, + { + "path": "desktop/capture_desktop/widgets_modality_expanded.py", + "mode": "100644", + "git_blob": "70d67f7405730707ad67d1da0e71a7e87bf8b68e", + "sha256": "12db25b37e8b2724e5eaabdcb1810aa979633885097b6ec11c33d98a46a83a70", + "bytes": 8566 + }, + { + "path": "desktop/capture_desktop/widgets_preview.py", + "mode": "100644", + "git_blob": "d0a760164a413616ab406a54d81c7b3f9b30d638", + "sha256": "78d79c9af67f7e0cbcee3a3a693a22e72753256ca465bab7edb9c2037822dec4", + "bytes": 27254 + }, + { + "path": "desktop/capture_desktop/widgets_radar_array.py", + "mode": "100644", + "git_blob": "d270e7aa8b36a9a6376cfbd76a46ec6448bb9ae4", + "sha256": "be08874ade0b4d9197ea85cb6ae3b30db75273ddd3c426faaaf28b4f796653a8", + "bytes": 2965 + }, + { + "path": "desktop/capture_desktop/widgets_session_header.py", + "mode": "100644", + "git_blob": "7f3c6e4e78728831fa29c6879cf461ebea5b38ef", + "sha256": "897ad1b241ea6b0582280391c861ae13a5aabe245eb8007283a6f4d5e1fedf27", + "bytes": 3433 + }, + { + "path": "desktop/capture_desktop/widgets_session_timeline.py", + "mode": "100644", + "git_blob": "d85f3c4ea492d587af49ca35c43aa5582806719c", + "sha256": "e7c1c2c679b4d0b0fa338ac0d1a44584d99b321857ab1506bbe2d3b455ded339", + "bytes": 9032 + }, + { + "path": "desktop/pyproject.toml", + "mode": "100644", + "git_blob": "dada23f8692dfda4c7c07fc012608844c7f41ab9", + "sha256": "3646f83dcc0764b3c8cb198b98b03201dc47808bb80bfec4837e329e47bd012f", + "bytes": 552 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/__init__.py", + "mode": "100644", + "git_blob": "67a4fb257b771af771edb4010e573ceeab86a51f", + "sha256": "14cfe6dccd33a0bda74fac3c9339e1a37a3538b2110a8ae6e307801b776eb43a", + "bytes": 497 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/discover.py", + "mode": "100644", + "git_blob": "d5c4fa7e06ac6e9139ebfc78fade90a3df5e451a", + "sha256": "344ee5d7cb0f5e95ac7524a0c1141b0a293bb9445e2bd4789c6736f39cfcb90d", + "bytes": 4023 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/eval/__init__.py", + "mode": "100644", + "git_blob": "140fcb2784c4b73ddf69d21ddccfdcc8191cc0aa", + "sha256": "54661df9ed7d7e0d4b1c2ab5941f107ceb608e4fdfaff810014ef5fad1431fe1", + "bytes": 154 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/eval/job.py", + "mode": "100644", + "git_blob": "95d40a6c28aabcdc311c18e3e195627f29ceb1a7", + "sha256": "a7f2a43c2fc3723c471e42a5532465dc5cfa44d4411c6cf581bba6910603fc57", + "bytes": 3984 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/__init__.py", + "mode": "100644", + "git_blob": "e52dc3839105744e19193f8fc8067b818389a20b", + "sha256": "3cdd6c626b6da12b8df56d8ddf35fca27c0a744865965ec01dd89d47da476fa1", + "bytes": 66 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/emg.py", + "mode": "100644", + "git_blob": "7f7536500a63ddc8b06774b8da65df8d56cd4f2b", + "sha256": "11f8f8350464b7c7c079353ca649b4c4aad2580ef8d355fe741c025c262b168e", + "bytes": 3072 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/imu.py", + "mode": "100644", + "git_blob": "0ee47b3d579e4c3732634958dda21ae724beca9e", + "sha256": "246bfd1cc3ce72afa0680537062b6795e22b8a06ba6301503d7489a4440c6849", + "bytes": 2605 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/io.py", + "mode": "100644", + "git_blob": "b998063a5036b73a67b773f70c193b1f9827c248", + "sha256": "c677d209292cca790ccdf1a64ba834f71a078ccce31ea57452e67ece358822ca", + "bytes": 1409 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/numeric_batch.py", + "mode": "100644", + "git_blob": "77f19ccb048c93c0f4fca460eef0502180b37717", + "sha256": "ecdeb88ca4dd093b973294a53954e9fa0e5d6b4b908225a52d097ef70c7d2154", + "bytes": 4030 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/radar_doppler.py", + "mode": "100644", + "git_blob": "ee20f7314cb1af4512901d6009f73e3dddf9025c", + "sha256": "cffc0ecbb8053fbc2244850c1927469366f4ae93b5439e4d194de2065877fa5c", + "bytes": 2289 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/radar_frame.py", + "mode": "100644", + "git_blob": "e798dee0fb72dd261b504a99ac76f815515dda9e", + "sha256": "f85c5fe5e2db68606f68e36a42a0c8f323086f0b1e7f233c0ddefa24cdccb443", + "bytes": 3323 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/video_qc.py", + "mode": "100644", + "git_blob": "fa73c80d39a0d699f80d7e877b37167cf8b48b6a", + "sha256": "0e25c50e01fc2da47bc7b510d68ba3e72aba33d3e1c79c57b727f5c55c723e27", + "bytes": 1766 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/grids.py", + "mode": "100644", + "git_blob": "2e03f79d9317d2d97b721321130a9a5e6212b111", + "sha256": "936c5404783145f7a2bc4c13df22d3b85612bcb227115bba74f0b78a11c0c483", + "bytes": 1007 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/jobs.py", + "mode": "100644", + "git_blob": "7badee5cdf5a4b30a283e0dcbb2c5d85fb787489", + "sha256": "e7e9dda44eb014d18192563f1e2c0ae78cece850fbc853b0be3919daaf5ee276", + "bytes": 19627 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/__init__.py", + "mode": "100644", + "git_blob": "aaf360b8a0085f89b95cd976857f0933596098a7", + "sha256": "50a0f7fd39648abf269fc549d2c17eb48b1dc9add10ebdb76edc1935d6f80160", + "bytes": 178 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/compute.py", + "mode": "100644", + "git_blob": "928751e9c861e2b0da298214269e57111f492865", + "sha256": "6e3ca19bfda0c02877f5d778f0c1191b5aebad605373732ef182bd714dd7f086", + "bytes": 6899 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/job.py", + "mode": "100644", + "git_blob": "fb8be113d8699427072f6dbcdae222a37738ac18", + "sha256": "d676e84f54aa1ae2b0f998c2cb37c4e02541c1fd0e3464e38e9865c0049a7239", + "bytes": 4523 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/registry.py", + "mode": "100644", + "git_blob": "a28cfd708c90552401fb0b3157c60f713a06e14f", + "sha256": "1e53fb9da4c6a2743bc1a3f0e687d94599cf995d33f2a2555e0ce5ebc3966d48", + "bytes": 1155 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/__init__.py", + "mode": "100644", + "git_blob": "eb6fae21d4bb79055f8d1af1528e846020f21459", + "sha256": "2d51c509baf3c0b5c33360637d12e5ce3c7507a859e4f37030f2c3d711ef0b3d", + "bytes": 361 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/base.py", + "mode": "100644", + "git_blob": "941a6aa3cea6777f90534ea634cccf8fdd319a3f", + "sha256": "696093b31f22d2bef32fc2962c7a11249a590a0b4d776c40cef4edcbc1e48a97", + "bytes": 2461 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/emg.py", + "mode": "100644", + "git_blob": "c35d22af7bdeea570e6ae45a713428627e90894c", + "sha256": "86eb7114be689cdbd2edd76affa2994e7278714916692a35381abd02ba9d599a", + "bytes": 3089 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/imu.py", + "mode": "100644", + "git_blob": "8823f04bd089789ca4cbff6602154bf066d4161d", + "sha256": "5ea4747145bf5588974dfd72c834766436c5a2bc0d58d34ace0f8ef403b310d6", + "bytes": 2773 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/mcap_iter.py", + "mode": "100644", + "git_blob": "b61ca0a914e4d3909790839774327aa5824c1b71", + "sha256": "03a418e7689840e378665aac92c42769dd14ba2c88a821a5cbf0cee80766540c", + "bytes": 1196 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/numeric_batch.py", + "mode": "100644", + "git_blob": "668e5397d6a603d8665fe639b3218128bbda72c2", + "sha256": "7c84c0425c1b9b821df711f4c40ea89ac13f267dbe6472922eb41a9263e4835c", + "bytes": 7139 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/radar_doppler.py", + "mode": "100644", + "git_blob": "fc87bfb7fbbeb98ad8d5d11b3438b2d04882de6c", + "sha256": "4942d08eb47229839e339ce7f2f8a64aee7e5fab44bac77029fcd7a3e3e490c1", + "bytes": 1539 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/radar_frame.py", + "mode": "100644", + "git_blob": "a44af5392ba2b5b8b64de685f42772b141f1b8b1", + "sha256": "d071f9d95b371798974698fd0caa1fc4c865a85fb772232fd43e7227b15fad2b", + "bytes": 1828 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/video.py", + "mode": "100644", + "git_blob": "6a192cd5999b45df08c666b9dad21dc29cf91824", + "sha256": "3c3e873ab641904a39ca649dac39072f11948031d068cc21ee459e996d1fc185", + "bytes": 2200 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/ml_bundle/__init__.py", + "mode": "100644", + "git_blob": "619d634ebf6fcc82a7871ad9c463660a24fd65ae", + "sha256": "e785a2e3bf65852018d811b38ecbaf6ff9c479648025789145218809dd50d8a1", + "bytes": 179 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/ml_bundle/job.py", + "mode": "100644", + "git_blob": "59c2e4df46aa041e48aaf7184a3dd0ba345aff6d", + "sha256": "c14c74760e20c818ce5e2428d0b03a8a949899b0bba6c46e37fa8fd797631c75", + "bytes": 9419 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pipeline.py", + "mode": "100644", + "git_blob": "8113ab4cb51678a122bbb702a23f2200c9333233", + "sha256": "e8c0152040ba5b5f3f37ac53fb5188bac9dd9aaf0d5816d6a718be505c20898c", + "bytes": 5262 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/modality.py", + "mode": "100644", + "git_blob": "1de343cc2e11e663501ba190441325d5637d1492", + "sha256": "bc3aa15ee79d50280a6c9d6aa144fe0519f85dd2c74a0cfa99323f7d57ecd28d", + "bytes": 2419 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/style.py", + "mode": "100644", + "git_blob": "3725e840e5eb046accea79d4b6376f902392dac8", + "sha256": "231e7b1c998f4349d5859295007235ffd41848f12fbb7819193bec9630cd3942", + "bytes": 1249 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/sync_dashboard.py", + "mode": "100644", + "git_blob": "828204e998a46b9571b3a2b3ba08acd9fc6caa31", + "sha256": "6f9e0c64193688eb841565729b9d1e9a64136779e892419acabdc81591afd3d5", + "bytes": 1149 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/__init__.py", + "mode": "100644", + "git_blob": "39c9c93eab1f5abf65ea73299c34b05ec184dd63", + "sha256": "c511d4b9cd1cda042b781b06fbb02d2d99004de214735d6daeb459d6e41381fe", + "bytes": 225 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/dummy.py", + "mode": "100644", + "git_blob": "0152651c271234bf38252bed51efda3a3fc19c0f", + "sha256": "facf059d247bca44f2697383e12cc1296b1d1d12bede1196f4a52a1352d60495", + "bytes": 1618 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/handlers.py", + "mode": "100644", + "git_blob": "03c8589064dfc4c6cfec6e4d00b7f46b10014414", + "sha256": "9be2e1820529b94e54d06790d53aa94cf658f982efb4063c6b64f9d07acc4b2e", + "bytes": 10646 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/manifest.yaml", + "mode": "100644", + "git_blob": "0628968ee3965170b486306f974c81dd4eb84a53", + "sha256": "1efe3ee2d9eeeeac03c2c03c582edf0119c9abd6d214dfdca3d827fa10a5c048", + "bytes": 3876 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/numeric.py", + "mode": "100644", + "git_blob": "d8adbc1d90dbfdeac0cd9179c95f027532c1a5d4", + "sha256": "75b55cb453095ad5470ce2532b65d3dce771e6a2f8ad1e46a538b4291fa4cf93", + "bytes": 3390 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/registry.py", + "mode": "100644", + "git_blob": "3c582e1ab0de2b22956ac47fb628227eacdd1faf", + "sha256": "33a4d07600db8b116fbd46b67492f62129df513df5b66a2c455dced0b2a9dc69", + "bytes": 5389 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pose/__init__.py", + "mode": "100644", + "git_blob": "108be2956adfed6328f397d88a3b61ebada0ac48", + "sha256": "d58a03cae86259b2cb0ecd0a5ce2347c6824f14cfea6871c94d76acc3541a380", + "bytes": 156 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pose/job.py", + "mode": "100644", + "git_blob": "1a1a3f2436b0ac8decc551f84e76fa6c4c6e602d", + "sha256": "1f4c44f443c07e22e8c9ca877232c6780c4b1da7834d5565b82cf547b2f4c439", + "bytes": 6262 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/qc.py", + "mode": "100644", + "git_blob": "530b86af1247599c127e2d0c3fa5e4d7d12169f6", + "sha256": "f24e0593a3723311d41054aef40b56c4bb46d4f3ba5ef4b01afcae3a6cc4440a", + "bytes": 9187 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/report_html.py", + "mode": "100644", + "git_blob": "bb8032024cfce30c6fe9a2bd2c13b0d2cbc2d102", + "sha256": "f2c89c7faf6e4edc265540140272396b4195eb5aed9edf05c4912aac74286f03", + "bytes": 4716 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/types.py", + "mode": "100644", + "git_blob": "2adf26816e0ef9e84e6763cf8bbff69d64697949", + "sha256": "e7996d02483f69265a2ef2ec0b28078c86f4f479daa53e38faf8b4a62645d02c", + "bytes": 3428 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/version.py", + "mode": "100644", + "git_blob": "d04b8cc1dd9271ca3ccf836d97436d9a961417c6", + "sha256": "9e25143344b110699f68b6acdbef49576fc91c2cbda34956d7e2cb85bbbc4ae3", + "bytes": 62 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/windows.py", + "mode": "100644", + "git_blob": "80bea6bd69365a48c5b204c26d054b8ae179437a", + "sha256": "af40235d55341d2a6b11d7f67a0195779676301fa822b2bd05240d138ee28c50", + "bytes": 5618 + }, + { + "path": "libs/python/capture_analysis/pyproject.toml", + "mode": "100644", + "git_blob": "6db8b1158b14da660128d7ac0ceacb45b8eb9924", + "sha256": "84cd96465e48439bdd81f5fa126fea5da11ee7587b488bfaaa67a4cd8f760c75", + "bytes": 677 + }, + { + "path": "libs/python/capture_protocol/LICENSE", + "mode": "100644", + "git_blob": "d645695673349e3947e8e5ae42332d0ac3164cd7", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "bytes": 11358 + }, + { + "path": "libs/python/capture_protocol/NOTICE", + "mode": "100644", + "git_blob": "7f9ac0678aa56452f06e6e5f3badc9a873e2008a", + "sha256": "3efb470f58c900a58deaef889527e074206274b0fd5fb0e2e62613c093064307", + "bytes": 124 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/__init__.py", + "mode": "100644", + "git_blob": "0e7ab2cf8689d3adbc689c283e8a23d12607b2d0", + "sha256": "556f474a3d740adc03c40426acde432ab7a394b947f8268bd90eecc7832dff8a", + "bytes": 698 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/codec.py", + "mode": "100644", + "git_blob": "3034065efca2c52e34c3e67e147bdda526d2c8db", + "sha256": "f6c09246a7b165358835e51b99b1508e68d840f4bdbd54b5fb72db33d4912712", + "bytes": 7011 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/config_schema.py", + "mode": "100644", + "git_blob": "c9b4a694e620e5597d338230fcb0f25ea3a757f6", + "sha256": "00d855895faec7d674cdb8e4da1ddc687888c9e9863f91d4950d24d9fb815e6e", + "bytes": 8444 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/constants.py", + "mode": "100644", + "git_blob": "2542cda6bdb6a83d4334336f34d92f80040bc4a0", + "sha256": "7f187edf873cd13f55bc09ff7972785797eb488d74dd5befcb395fc928a71d72", + "bytes": 486 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/control_client.py", + "mode": "100644", + "git_blob": "45e1c4b535ece8d7178cd6b32ab1affcc9e73e92", + "sha256": "68de412465b2eaa04886a2bb4566aa0595c898df7d7e782b3031b8ba919db7fa", + "bytes": 20823 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/framing.py", + "mode": "100644", + "git_blob": "9dd5021b815b31ab02eaaa814210525ebb543862", + "sha256": "3ff7c7284d9907a2ad516c83fab383a4151996da3f2d5a1d27e24d7c7575d92e", + "bytes": 2884 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/__init__.py", + "mode": "100644", + "git_blob": "16ae7d90a122b4973139c563ac0f72efa061b1de", + "sha256": "1fac8216894ce1a1b5362de3b59398fbd78f005a59636aea9f074951bed5c1d7", + "bytes": 90 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/__init__.py", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/__init__.py", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/arrays_pb2.py", + "mode": "100644", + "git_blob": "a29ed506c4dd33f697ba74d13b6e8a9c945c6b6d", + "sha256": "6355750076724275e49f9a5faec383b2be92c0336ed58805a88954964bd13b86", + "bytes": 2876 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/common_pb2.py", + "mode": "100644", + "git_blob": "66031212a0da44800dcc671b0d4bf0cd39e71f06", + "sha256": "6736e3b86b3c8749d34065794da1c880772ce69e2f248fdd2febd003f083bbd3", + "bytes": 9746 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/control_pb2.py", + "mode": "100644", + "git_blob": "0597489cf8609a76e2094270965039da9b739ca3", + "sha256": "f2eea386aebf830ec47fa7379e6fb0493e0a199efecc7b90974bc8bb8c8b96b6", + "bytes": 20028 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/__init__.py", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/emg_batch_pb2.py", + "mode": "100644", + "git_blob": "d8495ebeb8ab140824eaa5412be0779cf929ec6a", + "sha256": "1db5ef51143a546072e34cc7be7b263db996fa5f4d0d71606b230cb75b531a14", + "bytes": 1624 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/imu_frame_pb2.py", + "mode": "100644", + "git_blob": "54bbf93dc638cdab95f49744ea7e0b43fefad374", + "sha256": "4a2048d2a737362bf26b99166e95c457d1492fcfba8848c894fe4d2748ff9f51", + "bytes": 2222 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/numeric_batch_pb2.py", + "mode": "100644", + "git_blob": "beedaaae054bfb083af3642c96ca7c64af14cc8d", + "sha256": "a087cc019b9849f4ef47bcdf4c789a7da90d443240b7bef97c832bb23c1d4e24", + "bytes": 1454 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/radar_doppler_pb2.py", + "mode": "100644", + "git_blob": "ad8fe84317d2f4049682f70bead19f90c6932457", + "sha256": "d1b85358aba0c2f4fc1745218463e9951224322604b18b068a2195359dcf790e", + "bytes": 1773 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/radar_frame_pb2.py", + "mode": "100644", + "git_blob": "cef636d7b030b037b23331eec9a86f3b152bc358", + "sha256": "995ddbbb0aa614afb15088cf039c741421c33ea3e3e963ef1a7361b24754b862", + "bytes": 1729 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/video_timing_pb2.py", + "mode": "100644", + "git_blob": "17937a141a9a2d81858cf52d74bc4705afc940b7", + "sha256": "002a79858ccd2d7763769a1fe1be6a16a7f6b8727d15f952d191bcd2240ba5ef", + "bytes": 1722 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/events_pb2.py", + "mode": "100644", + "git_blob": "030bd4a90be609403e7709605607d8d5b993776e", + "sha256": "72951a468b0480e7fefc4fd3f9b4caac5fda0abdadf4ffcca92d4f19286429ce", + "bytes": 5480 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/health_pb2.py", + "mode": "100644", + "git_blob": "b27bd32ec488168871ca2342062eb576d56a9e8e", + "sha256": "e1e0baa7073a9886e4d982d4f00020b490bfd46c32b1b4df129fd0477c1f5e61", + "bytes": 5898 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/presets_pb2.py", + "mode": "100644", + "git_blob": "d20925410185e5cf52bbc56e438534c1c5ff1102", + "sha256": "d27336594b548f2e6e7ae212fe6de198e6e699c62a5f27752f691d7928ccb27b", + "bytes": 2066 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/preview_pb2.py", + "mode": "100644", + "git_blob": "cb04387df1614a8b9d9755a702129bbbb8d6374e", + "sha256": "c992e91b9aef0aa0ec8d595eba2f7079889264d9e4de120b623afd1d8702c695", + "bytes": 5333 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/project_pb2.py", + "mode": "100644", + "git_blob": "a8e71f0a426858cc679cb87ce31d1379e70a2817", + "sha256": "983bc5715147297cdcecca343b9a450f2095fcc1e895859cc3c52a3213d933f5", + "bytes": 3355 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/source_pb2.py", + "mode": "100644", + "git_blob": "b72752efedc743d236713e51283dce923a526f55", + "sha256": "d15b443f27c910c0e809af19fed81d9c1a75f7112501df85877bf4bf9bc4f7a8", + "bytes": 8053 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/storage_pb2.py", + "mode": "100644", + "git_blob": "4dd1b48ab16900c5c3e88d9788cebf83ee93cc5a", + "sha256": "f7a7b8903af9bfc2d2a419622c86cc057aed2a898949e4261475a7ac61222474", + "bytes": 5487 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/worker_pb2.py", + "mode": "100644", + "git_blob": "7f3a4fc372384523638853f4bd458f49b664ba70", + "sha256": "112e832172913024c6fad128a9a9559bbcd14b18de06b1f2a3161ac380258dc0", + "bytes": 11165 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/handshake.py", + "mode": "100644", + "git_blob": "9386e73b3c1eecb683d9d0ca98ad415268e307af", + "sha256": "63f740c992edf8812f666b79f9cd866d9ea33e65e5b310a5ebda2f5ef98ac115", + "bytes": 4763 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/structured_log.py", + "mode": "100644", + "git_blob": "fc9c97b288280f4473c6b3c5b5e6ff07332fad49", + "sha256": "3d7883833286ecc004248294badcc0c66e44a57ecb7844ef281828d797b3c4fc", + "bytes": 4657 + }, + { + "path": "libs/python/capture_protocol/pyproject.toml", + "mode": "100644", + "git_blob": "fa71ca45874d34076208507180c69c7a0e38fa76", + "sha256": "61b2e33b2de2a153fb994144f532402c1b6b8ed02afb627ba0a15239e726ca71", + "bytes": 355 + }, + { + "path": "libs/python/capture_session/capture_session/__init__.py", + "mode": "100644", + "git_blob": "894e3c152a98b6e804de90122572afbcd929b3da", + "sha256": "da530f86c0d1d584862868ddba9f7087ccf5dfbddd64dd1e577337ecfd776419", + "bytes": 2412 + }, + { + "path": "libs/python/capture_session/capture_session/app_paths.py", + "mode": "100644", + "git_blob": "46332cea7c62dd44247b219937ae6c8fbc747017", + "sha256": "363e4522240e2356cac7492589cb207a798bc1af6031139bd1fa94890f1c4bfd", + "bytes": 561 + }, + { + "path": "libs/python/capture_session/capture_session/package_reader.py", + "mode": "100644", + "git_blob": "91fbf913c5af8489968425d7ceac51c04233d3e0", + "sha256": "9a1d9e6e7d24341a083cee602af9538413e948f3369b22660e484356e3d34eb1", + "bytes": 6331 + }, + { + "path": "libs/python/capture_session/capture_session/registry.py", + "mode": "100644", + "git_blob": "c1d7799e1d2099424221b2f4af216a43a972c67a", + "sha256": "809b26ce8d8efc0559a3854cf85ea74b4e486fcd77d253ebfa76bade64b0a8d1", + "bytes": 13989 + }, + { + "path": "libs/python/capture_session/capture_session/settings_store.py", + "mode": "100644", + "git_blob": "41b99cdaa78011d3d9b753c3131f32c72af9699f", + "sha256": "7719524a1f106cc54befcd21088810f9ec28f0160c8e88f60c374e1545fdb98d", + "bytes": 4622 + }, + { + "path": "libs/python/capture_session/pyproject.toml", + "mode": "100644", + "git_blob": "c83450d780e97e5bd90feb48cef140917b6e47ff", + "sha256": "3484887da96d4a2f32de8471b537d849f077b195c729ff0cc29307681e8d4895", + "bytes": 389 + }, + { + "path": "libs/python/capture_worker/LICENSE", + "mode": "100644", + "git_blob": "d645695673349e3947e8e5ae42332d0ac3164cd7", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "bytes": 11358 + }, + { + "path": "libs/python/capture_worker/NOTICE", + "mode": "100644", + "git_blob": "d74f1cbf89d4c89f70b3e75ab71cfadea8b7128f", + "sha256": "2a7e69c4c7cd4e93a5cc9e9f984873a2d1276f465b91b10c71b951ebcfb2c588", + "bytes": 142 + }, + { + "path": "libs/python/capture_worker/capture_worker/__init__.py", + "mode": "100644", + "git_blob": "4bf1fc6b13bc4f5daab79d937ea89cf6c120cce3", + "sha256": "c7ba88e956df8460002637eb3d8678a4c7217e680a388f833a22f073dc80f8fd", + "bytes": 503 + }, + { + "path": "libs/python/capture_worker/capture_worker/__main__.py", + "mode": "100644", + "git_blob": "a1047121f4173802074eeb66e5dcaf6c542c29c1", + "sha256": "216422b76731bc985daa5fb0efe55a9d5ce600aa7e6081fa3df0c03afb6a893e", + "bytes": 150 + }, + { + "path": "libs/python/capture_worker/capture_worker/cli.py", + "mode": "100644", + "git_blob": "eb2d869f951f0205085b074d067282990657b5a0", + "sha256": "8a16c4cae0ffd11d4f9cd5d168f6abf1c6f9a4b5100e8edd18a29ce7d44d3f03", + "bytes": 1818 + }, + { + "path": "libs/python/capture_worker/capture_worker/preview.py", + "mode": "100644", + "git_blob": "c47abe8a118ea022931843bde802132548194eef", + "sha256": "38b483dc06c9215b73e4c56c222fe563957180a5be58761a2c6dd4ea200b8e31", + "bytes": 3202 + }, + { + "path": "libs/python/capture_worker/capture_worker/transport.py", + "mode": "100644", + "git_blob": "2e5e159bee3a0b5aa69bf90f62906feeffe23c8c", + "sha256": "020414c74bd08ec510e88da8c2f8b9ec5091a19cb585b4c54d2656b4bf300d35", + "bytes": 5033 + }, + { + "path": "libs/python/capture_worker/capture_worker/worker.py", + "mode": "100644", + "git_blob": "d5ed2999fbb958116d73a8fa6319356d8b7d751a", + "sha256": "19a0dfd16a65479de884d4359a3d65f1bc127d8a6d4b44b93c6251757510de68", + "bytes": 23439 + }, + { + "path": "libs/python/capture_worker/capture_worker/writer.py", + "mode": "100644", + "git_blob": "b3d194cc71dfa0d21884936a6ed5f7bdc95b3eb4", + "sha256": "b9e3b21ac26f2160da582a3f566a278dc4088c5a8b121d9b4e74f8d8c16cf96f", + "bytes": 6196 + }, + { + "path": "libs/python/capture_worker/pyproject.toml", + "mode": "100644", + "git_blob": "5d79642edc9c1809fda636d5dcd78ad33e67abcc", + "sha256": "0cba218b59a756185fedf72fb3a3307d1d9cb9218b6189ea92972d3cec139a46", + "bytes": 487 + }, + { + "path": "pyproject.toml", + "mode": "100644", + "git_blob": "52491c6beebc4b17983fc66bb8765154c33cf6d8", + "sha256": "0cb8de1ab3dfbfed84ff16b35f3c89c6440180183ee5851d5d80da83622e53d0", + "bytes": 1233 + }, + { + "path": "tests/analysis/test_numeric_batch_pipeline.py", + "mode": "100644", + "git_blob": "9485adb27d02ab88e65d87576a06b86869a0360b", + "sha256": "43369bd0fea48d2c8b7dee1d8128b3bb131b508b7b0a14512fc457fcfdb0ba3c", + "bytes": 19230 + }, + { + "path": "tests/conftest.py", + "mode": "100644", + "git_blob": "ad9b61fd8e9c1c3d74f91710d4e82dd7d899e6b4", + "sha256": "f669618fad17e906c91df7a1e9393fc7a54f458c6d62a4385436ba2622beca0e", + "bytes": 1773 + }, + { + "path": "tests/fixtures/mini_session/events/annotations.json", + "mode": "100644", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "bytes": 3 + }, + { + "path": "tests/fixtures/mini_session/events/checkpoints.json", + "mode": "100644", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "bytes": 3 + }, + { + "path": "tests/fixtures/mini_session/events/sync_anchors.json", + "mode": "100644", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "bytes": 3 + }, + { + "path": "tests/fixtures/mini_session/integrity.json", + "mode": "100644", + "git_blob": "d10093b866427fcaed78a85e60e600d8657a86a7", + "sha256": "af5d9bacd3eace7e831d48dee83eb5d9f578f4f4819d92218c4b55b0cb3ed556", + "bytes": 227 + }, + { + "path": "tests/fixtures/mini_session/manifest.json", + "mode": "100644", + "git_blob": "800dab5b41774bc043ebdee4714195770e75229b", + "sha256": "c5254d3e4c0bc6a0ecaef124dc12d88117d647928a8e1725b71429097438d380", + "bytes": 235 + }, + { + "path": "tests/fixtures/mini_session/processing/.gitkeep", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/health/gaps.jsonl", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/source.json", + "mode": "100644", + "git_blob": "9528c95289b4b1b49d11d412b5ab2e3d019b4066", + "sha256": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10", + "bytes": 112 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap", + "mode": "100644", + "git_blob": "320ce3607fadf57d05cf506987d045cf5b62ad9f", + "sha256": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649", + "bytes": 28 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/streams/sim.emg.main.batch/stream.json", + "mode": "100644", + "git_blob": "12c4db8831572fc4ab3db9ba5f784fa236078e5f", + "sha256": "8f8c02b89fd93e55643151e5222488e1174dd97a6b7a74f3ae5da8215b4d68e1", + "bytes": 216 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/source.json", + "mode": "100644", + "git_blob": "fcc248c52b8319f5e7fd0067763b74640f0040dd", + "sha256": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8", + "bytes": 118 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap", + "mode": "100644", + "git_blob": "320ce3607fadf57d05cf506987d045cf5b62ad9f", + "sha256": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649", + "bytes": 28 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json", + "mode": "100644", + "git_blob": "9c634d4af594372063fcc612331ba338ae95f8c9", + "sha256": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d", + "bytes": 219 + }, + { + "path": "tests/ui/test_analysis_history.py", + "mode": "100644", + "git_blob": "f013473f750b515a8305e2f7f8426b6520e26a65", + "sha256": "48175547922125c308fa49bbb84149e3dac8903902e7cc64fa7c15b4ca40eccd", + "bytes": 10465 + }, + { + "path": "workers/python_host/capture_sim/__init__.py", + "mode": "100644", + "git_blob": "2646a1792544ac97cba76fd7d7246c313604351e", + "sha256": "a3c8506a26d20b0b10cd55f00b019b7ddc1e2d4cb5cffd5c155d70ef338d21ae", + "bytes": 259 + }, + { + "path": "workers/python_host/capture_sim/advertise.py", + "mode": "100644", + "git_blob": "c93044ce53b7a38d2e7db9fcbad83174b394ffd2", + "sha256": "6a41dafed67d08d4e3829c053dc5a2767ae28293d63733b4b4ae187a8d4a94b9", + "bytes": 15205 + } + ] +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/README.md b/docs/evidence/analysis-history-401c5d17da79/current-qc/README.md new file mode 100644 index 00000000..014afddc --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/README.md @@ -0,0 +1,70 @@ +# Current QC output and saved-history receiving + +The author's runtime `37443f0d4d5ffa684b5423d58501856cadbe0655` +was qualified on canonical `72c15d6b623e217291a824e4e4808a385df896a9`. +Current main `e43da3b855475c8aacf815c201fa03eddaeec0f1` changes no +desktop or session-reader source, but its accepted QC producer now writes +`capture.analysis_qc/2` and HTML with recorded gap rows. This packet closes that +specific changed-input boundary. + +Git's actual three-way merge, using the observed canonical base, produced +runtime tree `ba5b4b925b00ecb17895a8c8ad29410e787f97dc`. It changes only +the three history/runtime files and one focused test relative to current main; +779 unrelated current leaves and their modes remain exact. The publication +adds documentation and evidence after this runtime tree without changing its +Python or fixture bytes. + +## Result + +One real `QApplication.exec` event-loop scenario passed 14 assertions, exit 0, +in 3.471 seconds using the existing Python/PySide6 environment. A private copy +of the existing mini-session fixture receives one authored recorded gap, +then the unchanged current producer creates the retained QC result. + +The receiver confirms the QC/2 schema, exact gap duration of 1,000,000,002 ns +and reported loss count of 3, plus the current HTML gap row. It opens that job +through the actual history controls, existing inspector and read-only Details +dialog; the existing report action is available and no computation thread is +started. All 18 retained package/job files and all 139 frozen source/fixture +files remain unchanged while browsing. + +`current.stderr.log` retains Qt's standard offscreen +`This plugin does not support propagateSizeHints()` message. It contains no +other diagnostic. This is one current-dependency receiving scenario, separate +from the author's 14 tests and the independent receiver's 19 native checks. +It is not a full Windows, daemon, hardware or installed-release qualification. + +## Exact receipts + +| File | SHA-256 | +| --- | --- | +| `check_current_qc_history.py` | `469b3e3fd0403e420c847e1e4c11525b968055447aa2ecdd1024714e2c12039e` | +| `source-inputs.json` | `c41b5857ca1cca774d85298827c8f63a85dada025e2e326b51ce96de08e0ab0e` | +| `current-run/receipt.json` | `e12a6c87e4786a87b2adf5a295e1184d12e4a3ecebad6e4ca6e3b24beb1bd4ec` | +| `current.stdout.log` | `34b2748419db7460c2abff30184db5e7f12b075c1808667abcb065177dfd5025` | +| `current.stderr.log` | `caeb11f6473c6c7125dd27478e588b85ffd6b31784e9adb1371a60f1661eb00f` | + +`process.json` retains the exact command, duration and process result. The +source manifest lists every input's Git blob, mode, byte length and SHA-256. +The fixture mutations are confined to the receiver's newly created directory; +the authored and canonical checkouts are never used as output directories. + +## Replay + +Use an existing Python 3.12 environment with CaptureSuite's dependencies. From +the composed checkout, materialize exactly the files listed by +`source-inputs.json` into a new source projection and verify their hashes. +Preserve their relative paths. Keep output outside that source and choose a +path that does not exist: + +```sh +python -B check_current_qc_history.py \ + --source /absolute/path/to/verified-source-projection \ + --inputs /absolute/path/to/source-inputs.json \ + --output /absolute/path/to/new-private-output +``` + +The companion performs no dependency installation, uses private application +state directories and rejects changed or extra projected source files before +opening a widget. It uses the existing mini-session fixture and current +producer. diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/check_current_qc_history.py b/docs/evidence/analysis-history-401c5d17da79/current-qc/check_current_qc_history.py new file mode 100644 index 00000000..7813a9a1 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/check_current_qc_history.py @@ -0,0 +1,159 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""Receive one current QC/2 artifact through the saved native result workflow.""" +from __future__ import annotations + +import argparse +import hashlib +import json +import os +import platform +import shutil +import sys +import traceback +from pathlib import Path + + +def hashes(root: Path) -> dict[str, str]: + return {p.relative_to(root).as_posix(): hashlib.sha256(p.read_bytes()).hexdigest() + for p in sorted(root.rglob('*')) if p.is_file()} + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--source', type=Path, required=True) + parser.add_argument('--inputs', type=Path, required=True) + parser.add_argument('--output', type=Path, required=True) + args = parser.parse_args() + source, output = args.source.resolve(), args.output.resolve() + if output == source or source in output.parents or output.exists(): + raise ValueError('Output must be a new private directory outside the source.') + manifest = json.loads(args.inputs.read_text()) + expected = {x['path']: x['sha256'] for x in manifest['files']} + assert hashes(source) == expected, 'Input projection must match all frozen files.' + output.mkdir(parents=True, exist_ok=False) + for key, name in [('LOCALAPPDATA', 'local'), ('APPDATA', 'roaming'), + ('XDG_CONFIG_HOME', 'config'), ('XDG_DATA_HOME', 'data'), + ('XDG_CACHE_HOME', 'cache'), ('MPLCONFIGDIR', 'matplotlib')]: + folder = output / 'private-state' / name + folder.mkdir(parents=True) + os.environ[key] = str(folder) + os.environ['QT_QPA_PLATFORM'] = 'offscreen' + os.environ['PYTHONDONTWRITEBYTECODE'] = '1' + sys.dont_write_bytecode = True + for relative in reversed(['desktop', 'libs/python/capture_analysis', + 'libs/python/capture_session', 'libs/python/capture_protocol', + 'libs/python/capture_protocol/capture_protocol/generated', + 'libs/python/capture_worker', 'workers/python_host']): + sys.path.insert(0, str(source / relative)) + + report = {'canonical_main': manifest['canonical_parent'], + 'author_source': manifest['author_source'], + 'composition_tree': manifest['composition_tree'], + 'source_inputs_sha256': hashlib.sha256(args.inputs.read_bytes()).hexdigest(), + 'runner_sha256': hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), + 'python': sys.version, 'platform': platform.platform(), + 'checks': [], 'scope': 'One current-QC/2 to saved-history reader boundary; no worker-thread, Windows, daemon or hardware acceptance.'} + + def check(name: str, value: bool) -> None: + report['checks'].append({'name': name, 'passed': bool(value)}) + assert value, name + + status = 1 + try: + import PySide6 + from PySide6.QtCore import QCoreApplication, QEvent, QTimer + from PySide6.QtWidgets import QApplication, QPlainTextEdit + import capture_analysis.qc as qc_module + import capture_analysis.report_html as html_module + from capture_analysis import JobParams, run + from capture_desktop import theme + from capture_desktop.screen_analysis import AnalysisScreen + from capture_desktop.state import CaptureState + + report['pyside6'] = PySide6.__version__ + check('current QC producer loaded from pinned source', + Path(qc_module.__file__).resolve() == source / 'libs/python/capture_analysis/capture_analysis/qc.py') + check('current HTML producer loaded from pinned source', + Path(html_module.__file__).resolve() == source / 'libs/python/capture_analysis/capture_analysis/report_html.py') + package = output / 'current QC saved.mmsession' + shutil.copytree(source / 'tests/fixtures/mini_session', package) + gap_dir = package / 'sources/sim.emg.main/health' + gap_dir.mkdir(parents=True, exist_ok=True) + (gap_dir / 'gaps.jsonl').write_text(json.dumps({ + 'sourceId': 'sim.emg.main', 'streamId': 'sim.emg.main.batch', + 'cause': 'transport_loss', 'startSessionTimeNs': '1000000001', + 'endSessionTimeNs': '2000000003', 'closed': True, 'estimatedLostCount': '3' + }) + '\n', encoding='utf-8') + result = run(package, JobParams(command='qc', overwrite_job_id='current-qc')) + qc_path = result.job_dir / 'reports/qc.json' + html_path = result.job_dir / 'reports/qc.html' + qc = json.loads(qc_path.read_text()) + check('current producer emits capture.analysis_qc/2', qc['schemaId'] == 'capture.analysis_qc/2') + check('native gap precision retained in generated result', + len(qc['gaps']) == 1 and qc['gaps'][0]['durationNs'] == '1000000002' + and qc['gaps'][0]['estimatedLostCount'] == '3') + check('current generated report includes the recorded gap', + 'Recorded gaps' in html_path.read_text() and 'transport_loss' in html_path.read_text()) + before = hashes(package) + app = QApplication([]) + theme.apply_theme(app, setting='dark') + screen = AnalysisScreen(CaptureState()) + callback_status = [1] + + def receive() -> None: + try: + screen.set_package(str(package)) + check('package selection offers saved result without opening it', + screen._history._jobs.count() == 1 and not screen._last_job_dir) + screen._history._open.click() + check('explicit native Open selects the current result', + screen._last_job_dir == str(result.job_dir) + and screen._history.loaded_job_id == 'current-qc') + check('existing inspector receives current result provenance', + 'job_id=current-qc' in screen._inspector._meta.text()) + check('existing report action is available for the retained current report', + screen._btn_open_report.isEnabled()) + screen._history._details.click() + dialog = screen._history._dialog + check('native result details dialog opens', dialog is not None and dialog.isVisible()) + editors = {w.objectName(): w for w in dialog.findChildren(QPlainTextEdit)} + check('saved parameters and provenance remain read-only', + all(w.isReadOnly() for w in editors.values()) + and json.loads(editors['analysisHistoryParameters'].toPlainText())['command'] == 'qc' + and json.loads(editors['analysisHistoryManifest'].toPlainText())['jobId'] == 'current-qc') + check('browsing starts no computation thread', screen._thread is None) + check('all generated package and job bytes stay unchanged while browsing', hashes(package) == before) + dialog.close() + callback_status[0] = 0 + except BaseException: + report['error'] = traceback.format_exc() + finally: + screen.close() + app.exit(callback_status[0]) + + QTimer.singleShot(0, receive) + loop_status = app.exec() + check('actual QApplication event loop returned successfully', loop_status == 0) + screen.deleteLater() + QCoreApplication.sendPostedEvents(None, QEvent.Type.DeferredDelete) + app.processEvents() + report['package_hashes'] = before + report['artifact_schema'] = qc['schemaId'] + report['artifact_gap'] = qc['gaps'][0] + status = callback_status[0] + except BaseException: + report.setdefault('error', traceback.format_exc()) + finally: + report['source_unchanged'] = hashes(source) == expected + if not report['source_unchanged']: + status = 1 + report['exit_code'] = status + report['passed'] = sum(x['passed'] for x in report['checks']) + report['failed'] = sum(not x['passed'] for x in report['checks']) + (output / 'receipt.json').write_text(json.dumps(report, indent=2) + '\n') + print(json.dumps({k: report[k] for k in ['passed', 'failed', 'exit_code', 'source_unchanged']})) + return status + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/artifacts/qc.html b/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/artifacts/qc.html new file mode 100644 index 00000000..3b390046 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/artifacts/qc.html @@ -0,0 +1,60 @@ + + + + +QC — mini-analysis-fixture + + + +

Analysis QC

+

+session mini-analysis-fixture · +state finalized · +streams 2 · +gaps open/closed 0/1 · +checkpoints 0 +

+

package: /dev/shm/hamon-401c5d17da79-capture-history-pr/current-boundary/current-run/current QC saved.mmsession

+

manifest sha256: c5254d3e4c0bc6a0ecaef124dc12d88117d647928a8e1725b71429097438d380

+ +

Sources

+ + + +
sourcelight
sim.emg.mainwarn
sim.imu.upperok
+ +

Recorded gaps

+

Times are seconds relative to session T0, with nanosecond precision. +Each row is one reported gap. Loss counts are reported estimates in source-defined units.

+
+ + + + + +
sourcestreamcausestatestart (session s)end (session s)duration (s)estimated lost count
sim.emg.mainsim.emg.main.batchtransport_lossclosed1.0000000012.0000000031.0000000023
+
+ +

Streams

+ + + + +
sourcestreammodalityschemarate Hzunitsmcap/mkv
sim.emg.mainsim.emg.main.batchemgemg.batch/12000.0mV1/0
sim.imu.uppersim.imu.upper.framesimuimu.frame/160.0a.u.1/0
+ +

Warnings

+
  • sim.emg.main: 1 recorded gap(s); see gap details
+ + diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/artifacts/qc.json b/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/artifacts/qc.json new file mode 100644 index 00000000..b10bccd9 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/artifacts/qc.json @@ -0,0 +1,65 @@ +{ + "annotationCount": 0, + "checkpointCount": 0, + "closedGapCount": 1, + "durationNs": 10000000000, + "gaps": [ + { + "cause": "transport_loss", + "closed": true, + "durationNs": "1000000002", + "durationStatus": "known", + "endSessionTimeNs": "2000000003", + "estimatedLostCount": "3", + "sourceId": "sim.emg.main", + "startSessionTimeNs": "1000000001", + "streamId": "sim.emg.main.batch" + } + ], + "integrityFileCount": 1, + "manifestSha256": "c5254d3e4c0bc6a0ecaef124dc12d88117d647928a8e1725b71429097438d380", + "openGapCount": 0, + "packagePath": "/dev/shm/hamon-401c5d17da79-capture-history-pr/current-boundary/current-run/current QC saved.mmsession", + "packageState": "finalized", + "recoveryReports": [], + "schemaId": "capture.analysis_qc/2", + "sessionId": "mini-analysis-fixture", + "sourceCount": 2, + "streamCount": 2, + "streams": [ + { + "dataSchemaId": "emg.batch/1", + "mcapSegments": 1, + "mkvSegments": 0, + "modality": "emg", + "nominalRateHz": 2000.0, + "rateOk": true, + "sourceId": "sim.emg.main", + "streamId": "sim.emg.main.batch", + "timingSegments": 0, + "units": "mV", + "warnings": [] + }, + { + "dataSchemaId": "imu.frame/1", + "mcapSegments": 1, + "mkvSegments": 0, + "modality": "imu", + "nominalRateHz": 60.0, + "rateOk": true, + "sourceId": "sim.imu.upper", + "streamId": "sim.imu.upper.frames", + "timingSegments": 0, + "units": "a.u.", + "warnings": [] + } + ], + "syncAnchorCount": 0, + "trafficLights": { + "sim.emg.main": "warn", + "sim.imu.upper": "ok" + }, + "warnings": [ + "sim.emg.main: 1 recorded gap(s); see gap details" + ] +} \ No newline at end of file diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/receipt.json b/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/receipt.json new file mode 100644 index 00000000..5a0294c5 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/current-run/receipt.json @@ -0,0 +1,105 @@ +{ + "canonical_main": "e43da3b855475c8aacf815c201fa03eddaeec0f1", + "author_source": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "composition_tree": "ba5b4b925b00ecb17895a8c8ad29410e787f97dc", + "source_inputs_sha256": "c41b5857ca1cca774d85298827c8f63a85dada025e2e326b51ce96de08e0ab0e", + "runner_sha256": "469b3e3fd0403e420c847e1e4c11525b968055447aa2ecdd1024714e2c12039e", + "python": "3.12.14 (main, Aug 25 2026, 14:00:49) [Clang 22.1.3 ]", + "platform": "Linux-6.18.44-x86_64-with-glibc2.39", + "checks": [ + { + "name": "current QC producer loaded from pinned source", + "passed": true + }, + { + "name": "current HTML producer loaded from pinned source", + "passed": true + }, + { + "name": "current producer emits capture.analysis_qc/2", + "passed": true + }, + { + "name": "native gap precision retained in generated result", + "passed": true + }, + { + "name": "current generated report includes the recorded gap", + "passed": true + }, + { + "name": "package selection offers saved result without opening it", + "passed": true + }, + { + "name": "explicit native Open selects the current result", + "passed": true + }, + { + "name": "existing inspector receives current result provenance", + "passed": true + }, + { + "name": "existing report action is available for the retained current report", + "passed": true + }, + { + "name": "native result details dialog opens", + "passed": true + }, + { + "name": "saved parameters and provenance remain read-only", + "passed": true + }, + { + "name": "browsing starts no computation thread", + "passed": true + }, + { + "name": "all generated package and job bytes stay unchanged while browsing", + "passed": true + }, + { + "name": "actual QApplication event loop returned successfully", + "passed": true + } + ], + "scope": "One current-QC/2 to saved-history reader boundary; no worker-thread, Windows, daemon or hardware acceptance.", + "pyside6": "6.11.2", + "package_hashes": { + "events/annotations.json": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "events/checkpoints.json": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "events/sync_anchors.json": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "integrity.json": "af5d9bacd3eace7e831d48dee83eb5d9f578f4f4819d92218c4b55b0cb3ed556", + "manifest.json": "c5254d3e4c0bc6a0ecaef124dc12d88117d647928a8e1725b71429097438d380", + "processing/.gitkeep": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "processing/jobs/current-qc/job_manifest.json": "7c0164de00779c92c16a5b2c31426d94e22abefcced4d16b365967c17be33486", + "processing/jobs/current-qc/logs/job.log": "d23058fcc8ab19137ea84b2c90a830a43f2017e969eb953ca38e210f2fec02b8", + "processing/jobs/current-qc/params.json": "6b1de8a12a547c74d1477f29c2c67df457f1ad54ab7f7865d39ad17199791f35", + "processing/jobs/current-qc/reports/qc.html": "eb41423403c4ea2049d50278c69fced1d37dde4b85aa76482fbe82ffdc7c75e9", + "processing/jobs/current-qc/reports/qc.json": "4bbe314029c3387541b5ad25fdc12268780fc0b31c1e343d5b8690a5e98560d9", + "sources/sim.emg.main/health/gaps.jsonl": "95cece59eed92129190c27703443c363d3b5ec0ff407b406678708dec899e090", + "sources/sim.emg.main/source.json": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10", + "sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649", + "sources/sim.emg.main/streams/sim.emg.main.batch/stream.json": "8f8c02b89fd93e55643151e5222488e1174dd97a6b7a74f3ae5da8215b4d68e1", + "sources/sim.imu.upper/source.json": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8", + "sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649", + "sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d" + }, + "artifact_schema": "capture.analysis_qc/2", + "artifact_gap": { + "cause": "transport_loss", + "closed": true, + "durationNs": "1000000002", + "durationStatus": "known", + "endSessionTimeNs": "2000000003", + "estimatedLostCount": "3", + "sourceId": "sim.emg.main", + "startSessionTimeNs": "1000000001", + "streamId": "sim.emg.main.batch" + }, + "source_unchanged": true, + "exit_code": 0, + "passed": 14, + "failed": 0 +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/current.stderr.log b/docs/evidence/analysis-history-401c5d17da79/current-qc/current.stderr.log new file mode 100644 index 00000000..09ad4161 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/current.stderr.log @@ -0,0 +1 @@ +This plugin does not support propagateSizeHints() diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/current.stdout.log b/docs/evidence/analysis-history-401c5d17da79/current-qc/current.stdout.log new file mode 100644 index 00000000..827c4191 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/current.stdout.log @@ -0,0 +1 @@ +{"passed": 14, "failed": 0, "exit_code": 0, "source_unchanged": true} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/process.json b/docs/evidence/analysis-history-401c5d17da79/current-qc/process.json new file mode 100644 index 00000000..ed07a960 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/process.json @@ -0,0 +1,18 @@ +{ + "command": [ + "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "-B", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/current-boundary/check_current_qc_history.py", + "--source", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/current-boundary/source", + "--inputs", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/current-boundary/source-inputs.json", + "--output", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/current-boundary/current-run" + ], + "exit_code": 0, + "elapsed_seconds": 3.471, + "stdout_sha256": "34b2748419db7460c2abff30184db5e7f12b075c1808667abcb065177dfd5025", + "stderr_sha256": "caeb11f6473c6c7125dd27478e588b85ffd6b31784e9adb1371a60f1661eb00f", + "runner_sha256": "469b3e3fd0403e420c847e1e4c11525b968055447aa2ecdd1024714e2c12039e" +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-qc/source-inputs.json b/docs/evidence/analysis-history-401c5d17da79/current-qc/source-inputs.json new file mode 100644 index 00000000..e63df5c7 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-qc/source-inputs.json @@ -0,0 +1,981 @@ +{ + "canonical_parent": "e43da3b855475c8aacf815c201fa03eddaeec0f1", + "author_source": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "composition_tree": "ba5b4b925b00ecb17895a8c8ad29410e787f97dc", + "scope": "Exact tracked Python runtime and one existing fixture/test; no native build or full repository acceptance is implied.", + "files": [ + { + "path": "desktop/capture_desktop/__init__.py", + "mode": "100644", + "git_blob": "48777bd04b62e3b3b877e12311f7257819ab3a07", + "sha256": "8426c94323c4cca0879b8612345e3577d0a75f6239237a28d79d94a42004c3b5", + "bytes": 119 + }, + { + "path": "desktop/capture_desktop/__main__.py", + "mode": "100644", + "git_blob": "f78ccce984b725bf7263407d5b4b2d4c56131433", + "sha256": "8dbad73a7373565a3513ccbb613f11bffdd13a05861c3e8e07392b8d51008aa2", + "bytes": 723 + }, + { + "path": "desktop/capture_desktop/analysis_history.py", + "mode": "100644", + "git_blob": "1b8fd23aee632cc3af19990b9d7685c6a3ed1b5e", + "sha256": "2e0db8cee59ef268d3c91ea0beac7d761d83a3003862841cc9d7f1782fd3543c", + "bytes": 6375 + }, + { + "path": "desktop/capture_desktop/app.py", + "mode": "100644", + "git_blob": "3e6f0d9f31032eb51ddd0ac7deedc3d00d0d386e", + "sha256": "52a6b8d9844d8e0f9f9f1e07f516bf234cf104fdeb85dd5ea5acaa69970235f2", + "bytes": 46414 + }, + { + "path": "desktop/capture_desktop/daemon_link.py", + "mode": "100644", + "git_blob": "620e5a753fbd8448c3a57fcfa6a8b8540ac0bcd0", + "sha256": "ab76628bbe0231c7e5e4d570f2abed01100dddd6a24bb62020b670a6b62427dd", + "bytes": 10899 + }, + { + "path": "desktop/capture_desktop/export_wizard.py", + "mode": "100644", + "git_blob": "b22d0098eb9af3860c654591e411dbab68a0f05d", + "sha256": "fb957ff184109bcb4e379dde30414048e855c93ec390f9b50c7ab603c3cd4e30", + "bytes": 6734 + }, + { + "path": "desktop/capture_desktop/main.py", + "mode": "100644", + "git_blob": "90ad2adebae1f52ffabb889efe43a31dca1b6454", + "sha256": "e61c29a1925f8d85b24438f087dec360a4481a32e0dc2bd8ed8feb6629026e84", + "bytes": 1059 + }, + { + "path": "desktop/capture_desktop/persistence.py", + "mode": "100644", + "git_blob": "2f2da2bfda654009baa0e723465c82c1690a0676", + "sha256": "cdb1fa0094fec72543d5051435850e51d78d79d4bde8d5c83520fa072a2c74c4", + "bytes": 3379 + }, + { + "path": "desktop/capture_desktop/schema_form.py", + "mode": "100644", + "git_blob": "2d5fa62b1448e168e639e3e8879989a3461e1053", + "sha256": "7d825b5dc7566d630f31775df6fcc9def1e916eaff5be17a552bf89f28b3418b", + "bytes": 12206 + }, + { + "path": "desktop/capture_desktop/screen_analysis.py", + "mode": "100644", + "git_blob": "966f89f8cfad679a4a461900569365c50476581b", + "sha256": "98a704e31b14497e012fe5618ad47cc8a772bd2d59775826d71a5bdf41533211", + "bytes": 16407 + }, + { + "path": "desktop/capture_desktop/screen_capture.py", + "mode": "100644", + "git_blob": "b2d3cf05d57484f5efdbb0df85e5f0a065dab3d9", + "sha256": "4e101ddeeaed7f7f2b4ec2ab2e4b1f4f55ebb86f73b394d25cfd2b904cd2572e", + "bytes": 34181 + }, + { + "path": "desktop/capture_desktop/screen_presets.py", + "mode": "100644", + "git_blob": "c143fb87629fb90f656a7a3b4b9f3c136b03f596", + "sha256": "b62d6f4bef6c1f0fc04b9eaf6a8afd1b2eeb17f6ce14946a06b0495ba33d402c", + "bytes": 5230 + }, + { + "path": "desktop/capture_desktop/screen_review.py", + "mode": "100644", + "git_blob": "88a902ca7699faa2964f3fc22ec3348a339905a4", + "sha256": "e5aff59de4b194123ca4c4518b34e7b6103326fbd6b0280e2122d984d01072ec", + "bytes": 7003 + }, + { + "path": "desktop/capture_desktop/screen_settings.py", + "mode": "100644", + "git_blob": "fe6d1e8884b7300e4cb5039b8e86679339e43b4d", + "sha256": "519436946827fac53d0be68270c2929bd1ce615a58b2372e9e3fc10619a7ba6e", + "bytes": 4581 + }, + { + "path": "desktop/capture_desktop/screen_setup.py", + "mode": "100644", + "git_blob": "1df45aac30d63d6ab2e8ddc7efe0db394c513ab1", + "sha256": "01eb01ffffe835fcf5d26120d508800cc3cdac1e91ffaa3d0d2fa669c6326182", + "bytes": 11452 + }, + { + "path": "desktop/capture_desktop/state.py", + "mode": "100644", + "git_blob": "95046ba5ef7f7bbf5685a54b7ae8fd400814148c", + "sha256": "97fc98498f4553fc7f052d0dc4db992cf2fc136ba7c4405cd275bd156c74e314", + "bytes": 17906 + }, + { + "path": "desktop/capture_desktop/theme.py", + "mode": "100644", + "git_blob": "e309ce92bf66f65ca7c111698e1f536f05e4dca9", + "sha256": "c77f24e1afeb06400385bd0d535800f13dc15d972891e1ff8af504cbe5c818f3", + "bytes": 12072 + }, + { + "path": "desktop/capture_desktop/widgets_analysis_history.py", + "mode": "100644", + "git_blob": "8798627cd7d694c5a09c3c402a739a4ec45b6574", + "sha256": "a3b77c87483c1412b50de7ddde1498f6bfd3968002fc3ac3bfa474a2477d9bc4", + "bytes": 8458 + }, + { + "path": "desktop/capture_desktop/widgets_analysis_jobs.py", + "mode": "100644", + "git_blob": "c4d2f4513032d744f1f8066f0c887cda71d9b911", + "sha256": "5cdea6045456e61a58b5525dd224a22a140962d31d2adc5b0102168444468f98", + "bytes": 6304 + }, + { + "path": "desktop/capture_desktop/widgets_analysis_plots.py", + "mode": "100644", + "git_blob": "bb6c3033b5e4ed96a2e08857d38715b836926bf5", + "sha256": "85c73f881ee7d60ef2f868f7ff73fc57c0a4ef99a717f7f5015534db23e1ab86", + "bytes": 9382 + }, + { + "path": "desktop/capture_desktop/widgets_mappings.py", + "mode": "100644", + "git_blob": "62dd1b137ffc54a05aa81f37eb8627dd12e0032a", + "sha256": "89808d37cb0fce476665a24766963c7a509f5b1802d05dedbf9ca44351081f4b", + "bytes": 3658 + }, + { + "path": "desktop/capture_desktop/widgets_modality_expanded.py", + "mode": "100644", + "git_blob": "70d67f7405730707ad67d1da0e71a7e87bf8b68e", + "sha256": "12db25b37e8b2724e5eaabdcb1810aa979633885097b6ec11c33d98a46a83a70", + "bytes": 8566 + }, + { + "path": "desktop/capture_desktop/widgets_preview.py", + "mode": "100644", + "git_blob": "d0a760164a413616ab406a54d81c7b3f9b30d638", + "sha256": "78d79c9af67f7e0cbcee3a3a693a22e72753256ca465bab7edb9c2037822dec4", + "bytes": 27254 + }, + { + "path": "desktop/capture_desktop/widgets_radar_array.py", + "mode": "100644", + "git_blob": "d270e7aa8b36a9a6376cfbd76a46ec6448bb9ae4", + "sha256": "be08874ade0b4d9197ea85cb6ae3b30db75273ddd3c426faaaf28b4f796653a8", + "bytes": 2965 + }, + { + "path": "desktop/capture_desktop/widgets_session_header.py", + "mode": "100644", + "git_blob": "7f3c6e4e78728831fa29c6879cf461ebea5b38ef", + "sha256": "897ad1b241ea6b0582280391c861ae13a5aabe245eb8007283a6f4d5e1fedf27", + "bytes": 3433 + }, + { + "path": "desktop/capture_desktop/widgets_session_timeline.py", + "mode": "100644", + "git_blob": "d85f3c4ea492d587af49ca35c43aa5582806719c", + "sha256": "e7c1c2c679b4d0b0fa338ac0d1a44584d99b321857ab1506bbe2d3b455ded339", + "bytes": 9032 + }, + { + "path": "desktop/pyproject.toml", + "mode": "100644", + "git_blob": "dada23f8692dfda4c7c07fc012608844c7f41ab9", + "sha256": "3646f83dcc0764b3c8cb198b98b03201dc47808bb80bfec4837e329e47bd012f", + "bytes": 552 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/__init__.py", + "mode": "100644", + "git_blob": "67a4fb257b771af771edb4010e573ceeab86a51f", + "sha256": "14cfe6dccd33a0bda74fac3c9339e1a37a3538b2110a8ae6e307801b776eb43a", + "bytes": 497 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/discover.py", + "mode": "100644", + "git_blob": "d5c4fa7e06ac6e9139ebfc78fade90a3df5e451a", + "sha256": "344ee5d7cb0f5e95ac7524a0c1141b0a293bb9445e2bd4789c6736f39cfcb90d", + "bytes": 4023 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/eval/__init__.py", + "mode": "100644", + "git_blob": "140fcb2784c4b73ddf69d21ddccfdcc8191cc0aa", + "sha256": "54661df9ed7d7e0d4b1c2ab5941f107ceb608e4fdfaff810014ef5fad1431fe1", + "bytes": 154 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/eval/job.py", + "mode": "100644", + "git_blob": "95d40a6c28aabcdc311c18e3e195627f29ceb1a7", + "sha256": "a7f2a43c2fc3723c471e42a5532465dc5cfa44d4411c6cf581bba6910603fc57", + "bytes": 3984 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/__init__.py", + "mode": "100644", + "git_blob": "e52dc3839105744e19193f8fc8067b818389a20b", + "sha256": "3cdd6c626b6da12b8df56d8ddf35fca27c0a744865965ec01dd89d47da476fa1", + "bytes": 66 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/emg.py", + "mode": "100644", + "git_blob": "7f7536500a63ddc8b06774b8da65df8d56cd4f2b", + "sha256": "11f8f8350464b7c7c079353ca649b4c4aad2580ef8d355fe741c025c262b168e", + "bytes": 3072 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/imu.py", + "mode": "100644", + "git_blob": "0ee47b3d579e4c3732634958dda21ae724beca9e", + "sha256": "246bfd1cc3ce72afa0680537062b6795e22b8a06ba6301503d7489a4440c6849", + "bytes": 2605 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/io.py", + "mode": "100644", + "git_blob": "b998063a5036b73a67b773f70c193b1f9827c248", + "sha256": "c677d209292cca790ccdf1a64ba834f71a078ccce31ea57452e67ece358822ca", + "bytes": 1409 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/numeric_batch.py", + "mode": "100644", + "git_blob": "a9a667633f886adf4fe89cfd35eb94eeabad399f", + "sha256": "df48baa8eac38e1bcdb38411758b7f803507ab27b4a97fba18c86042cfd33c76", + "bytes": 2104 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/radar_doppler.py", + "mode": "100644", + "git_blob": "ee20f7314cb1af4512901d6009f73e3dddf9025c", + "sha256": "cffc0ecbb8053fbc2244850c1927469366f4ae93b5439e4d194de2065877fa5c", + "bytes": 2289 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/radar_frame.py", + "mode": "100644", + "git_blob": "e798dee0fb72dd261b504a99ac76f815515dda9e", + "sha256": "f85c5fe5e2db68606f68e36a42a0c8f323086f0b1e7f233c0ddefa24cdccb443", + "bytes": 3323 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/video_qc.py", + "mode": "100644", + "git_blob": "fa73c80d39a0d699f80d7e877b37167cf8b48b6a", + "sha256": "0e25c50e01fc2da47bc7b510d68ba3e72aba33d3e1c79c57b727f5c55c723e27", + "bytes": 1766 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/grids.py", + "mode": "100644", + "git_blob": "2e03f79d9317d2d97b721321130a9a5e6212b111", + "sha256": "936c5404783145f7a2bc4c13df22d3b85612bcb227115bba74f0b78a11c0c483", + "bytes": 1007 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/jobs.py", + "mode": "100644", + "git_blob": "7badee5cdf5a4b30a283e0dcbb2c5d85fb787489", + "sha256": "e7e9dda44eb014d18192563f1e2c0ae78cece850fbc853b0be3919daaf5ee276", + "bytes": 19627 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/__init__.py", + "mode": "100644", + "git_blob": "aaf360b8a0085f89b95cd976857f0933596098a7", + "sha256": "50a0f7fd39648abf269fc549d2c17eb48b1dc9add10ebdb76edc1935d6f80160", + "bytes": 178 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/compute.py", + "mode": "100644", + "git_blob": "928751e9c861e2b0da298214269e57111f492865", + "sha256": "6e3ca19bfda0c02877f5d778f0c1191b5aebad605373732ef182bd714dd7f086", + "bytes": 6899 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/job.py", + "mode": "100644", + "git_blob": "fb8be113d8699427072f6dbcdae222a37738ac18", + "sha256": "d676e84f54aa1ae2b0f998c2cb37c4e02541c1fd0e3464e38e9865c0049a7239", + "bytes": 4523 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/registry.py", + "mode": "100644", + "git_blob": "a28cfd708c90552401fb0b3157c60f713a06e14f", + "sha256": "1e53fb9da4c6a2743bc1a3f0e687d94599cf995d33f2a2555e0ce5ebc3966d48", + "bytes": 1155 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/__init__.py", + "mode": "100644", + "git_blob": "eb6fae21d4bb79055f8d1af1528e846020f21459", + "sha256": "2d51c509baf3c0b5c33360637d12e5ce3c7507a859e4f37030f2c3d711ef0b3d", + "bytes": 361 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/base.py", + "mode": "100644", + "git_blob": "941a6aa3cea6777f90534ea634cccf8fdd319a3f", + "sha256": "696093b31f22d2bef32fc2962c7a11249a590a0b4d776c40cef4edcbc1e48a97", + "bytes": 2461 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/emg.py", + "mode": "100644", + "git_blob": "c35d22af7bdeea570e6ae45a713428627e90894c", + "sha256": "86eb7114be689cdbd2edd76affa2994e7278714916692a35381abd02ba9d599a", + "bytes": 3089 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/imu.py", + "mode": "100644", + "git_blob": "8823f04bd089789ca4cbff6602154bf066d4161d", + "sha256": "5ea4747145bf5588974dfd72c834766436c5a2bc0d58d34ace0f8ef403b310d6", + "bytes": 2773 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/mcap_iter.py", + "mode": "100644", + "git_blob": "b61ca0a914e4d3909790839774327aa5824c1b71", + "sha256": "03a418e7689840e378665aac92c42769dd14ba2c88a821a5cbf0cee80766540c", + "bytes": 1196 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/numeric_batch.py", + "mode": "100644", + "git_blob": "f361d6e1afce8c836a13f2211b8fe8cb7442e30d", + "sha256": "0b6c78bf936e3bade378c6b0061aa94a8f11f536ade52b1d687f156d13780296", + "bytes": 3473 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/radar_doppler.py", + "mode": "100644", + "git_blob": "fc87bfb7fbbeb98ad8d5d11b3438b2d04882de6c", + "sha256": "4942d08eb47229839e339ce7f2f8a64aee7e5fab44bac77029fcd7a3e3e490c1", + "bytes": 1539 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/radar_frame.py", + "mode": "100644", + "git_blob": "a44af5392ba2b5b8b64de685f42772b141f1b8b1", + "sha256": "d071f9d95b371798974698fd0caa1fc4c865a85fb772232fd43e7227b15fad2b", + "bytes": 1828 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/video.py", + "mode": "100644", + "git_blob": "6a192cd5999b45df08c666b9dad21dc29cf91824", + "sha256": "3c3e873ab641904a39ca649dac39072f11948031d068cc21ee459e996d1fc185", + "bytes": 2200 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/ml_bundle/__init__.py", + "mode": "100644", + "git_blob": "619d634ebf6fcc82a7871ad9c463660a24fd65ae", + "sha256": "e785a2e3bf65852018d811b38ecbaf6ff9c479648025789145218809dd50d8a1", + "bytes": 179 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/ml_bundle/job.py", + "mode": "100644", + "git_blob": "59c2e4df46aa041e48aaf7184a3dd0ba345aff6d", + "sha256": "c14c74760e20c818ce5e2428d0b03a8a949899b0bba6c46e37fa8fd797631c75", + "bytes": 9419 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pipeline.py", + "mode": "100644", + "git_blob": "8113ab4cb51678a122bbb702a23f2200c9333233", + "sha256": "e8c0152040ba5b5f3f37ac53fb5188bac9dd9aaf0d5816d6a718be505c20898c", + "bytes": 5262 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/modality.py", + "mode": "100644", + "git_blob": "85073e330e6aaf617864a0730011e689251ecea9", + "sha256": "c9b1159ce1535fbddb4895d1acdf0115f88919aa3cc51ad964e5771d975995dd", + "bytes": 2393 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/style.py", + "mode": "100644", + "git_blob": "3725e840e5eb046accea79d4b6376f902392dac8", + "sha256": "231e7b1c998f4349d5859295007235ffd41848f12fbb7819193bec9630cd3942", + "bytes": 1249 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/sync_dashboard.py", + "mode": "100644", + "git_blob": "828204e998a46b9571b3a2b3ba08acd9fc6caa31", + "sha256": "6f9e0c64193688eb841565729b9d1e9a64136779e892419acabdc81591afd3d5", + "bytes": 1149 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/__init__.py", + "mode": "100644", + "git_blob": "39c9c93eab1f5abf65ea73299c34b05ec184dd63", + "sha256": "c511d4b9cd1cda042b781b06fbb02d2d99004de214735d6daeb459d6e41381fe", + "bytes": 225 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/dummy.py", + "mode": "100644", + "git_blob": "0152651c271234bf38252bed51efda3a3fc19c0f", + "sha256": "facf059d247bca44f2697383e12cc1296b1d1d12bede1196f4a52a1352d60495", + "bytes": 1618 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/handlers.py", + "mode": "100644", + "git_blob": "03c8589064dfc4c6cfec6e4d00b7f46b10014414", + "sha256": "9be2e1820529b94e54d06790d53aa94cf658f982efb4063c6b64f9d07acc4b2e", + "bytes": 10646 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/manifest.yaml", + "mode": "100644", + "git_blob": "e4b1792b4cf9f2f8f5c63bb8375c4d80f6f58818", + "sha256": "365bce8a7193e1407a684d4c3ee5dc1690c296f1b8bcb625076076cd8bea2eb3", + "bytes": 3832 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/registry.py", + "mode": "100644", + "git_blob": "e7334bedfcba51052a7f039f66c74ff288840831", + "sha256": "5ba10f5b58c102a98943d2225903c1d9f874aa5921a50319e159f6bd4d537351", + "bytes": 4834 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pose/__init__.py", + "mode": "100644", + "git_blob": "108be2956adfed6328f397d88a3b61ebada0ac48", + "sha256": "d58a03cae86259b2cb0ecd0a5ce2347c6824f14cfea6871c94d76acc3541a380", + "bytes": 156 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pose/job.py", + "mode": "100644", + "git_blob": "1a1a3f2436b0ac8decc551f84e76fa6c4c6e602d", + "sha256": "1f4c44f443c07e22e8c9ca877232c6780c4b1da7834d5565b82cf547b2f4c439", + "bytes": 6262 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/qc.py", + "mode": "100644", + "git_blob": "530b86af1247599c127e2d0c3fa5e4d7d12169f6", + "sha256": "f24e0593a3723311d41054aef40b56c4bb46d4f3ba5ef4b01afcae3a6cc4440a", + "bytes": 9187 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/report_html.py", + "mode": "100644", + "git_blob": "bb8032024cfce30c6fe9a2bd2c13b0d2cbc2d102", + "sha256": "f2c89c7faf6e4edc265540140272396b4195eb5aed9edf05c4912aac74286f03", + "bytes": 4716 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/types.py", + "mode": "100644", + "git_blob": "2adf26816e0ef9e84e6763cf8bbff69d64697949", + "sha256": "e7996d02483f69265a2ef2ec0b28078c86f4f479daa53e38faf8b4a62645d02c", + "bytes": 3428 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/version.py", + "mode": "100644", + "git_blob": "d04b8cc1dd9271ca3ccf836d97436d9a961417c6", + "sha256": "9e25143344b110699f68b6acdbef49576fc91c2cbda34956d7e2cb85bbbc4ae3", + "bytes": 62 + }, + { + "path": "libs/python/capture_analysis/capture_analysis/windows.py", + "mode": "100644", + "git_blob": "80bea6bd69365a48c5b204c26d054b8ae179437a", + "sha256": "af40235d55341d2a6b11d7f67a0195779676301fa822b2bd05240d138ee28c50", + "bytes": 5618 + }, + { + "path": "libs/python/capture_analysis/pyproject.toml", + "mode": "100644", + "git_blob": "6db8b1158b14da660128d7ac0ceacb45b8eb9924", + "sha256": "84cd96465e48439bdd81f5fa126fea5da11ee7587b488bfaaa67a4cd8f760c75", + "bytes": 677 + }, + { + "path": "libs/python/capture_protocol/LICENSE", + "mode": "100644", + "git_blob": "d645695673349e3947e8e5ae42332d0ac3164cd7", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "bytes": 11358 + }, + { + "path": "libs/python/capture_protocol/NOTICE", + "mode": "100644", + "git_blob": "7f9ac0678aa56452f06e6e5f3badc9a873e2008a", + "sha256": "3efb470f58c900a58deaef889527e074206274b0fd5fb0e2e62613c093064307", + "bytes": 124 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/__init__.py", + "mode": "100644", + "git_blob": "0e7ab2cf8689d3adbc689c283e8a23d12607b2d0", + "sha256": "556f474a3d740adc03c40426acde432ab7a394b947f8268bd90eecc7832dff8a", + "bytes": 698 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/codec.py", + "mode": "100644", + "git_blob": "3034065efca2c52e34c3e67e147bdda526d2c8db", + "sha256": "f6c09246a7b165358835e51b99b1508e68d840f4bdbd54b5fb72db33d4912712", + "bytes": 7011 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/config_schema.py", + "mode": "100644", + "git_blob": "c9b4a694e620e5597d338230fcb0f25ea3a757f6", + "sha256": "00d855895faec7d674cdb8e4da1ddc687888c9e9863f91d4950d24d9fb815e6e", + "bytes": 8444 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/constants.py", + "mode": "100644", + "git_blob": "2542cda6bdb6a83d4334336f34d92f80040bc4a0", + "sha256": "7f187edf873cd13f55bc09ff7972785797eb488d74dd5befcb395fc928a71d72", + "bytes": 486 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/control_client.py", + "mode": "100644", + "git_blob": "45e1c4b535ece8d7178cd6b32ab1affcc9e73e92", + "sha256": "68de412465b2eaa04886a2bb4566aa0595c898df7d7e782b3031b8ba919db7fa", + "bytes": 20823 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/framing.py", + "mode": "100644", + "git_blob": "9dd5021b815b31ab02eaaa814210525ebb543862", + "sha256": "3ff7c7284d9907a2ad516c83fab383a4151996da3f2d5a1d27e24d7c7575d92e", + "bytes": 2884 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/__init__.py", + "mode": "100644", + "git_blob": "16ae7d90a122b4973139c563ac0f72efa061b1de", + "sha256": "1fac8216894ce1a1b5362de3b59398fbd78f005a59636aea9f074951bed5c1d7", + "bytes": 90 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/__init__.py", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/__init__.py", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/arrays_pb2.py", + "mode": "100644", + "git_blob": "a29ed506c4dd33f697ba74d13b6e8a9c945c6b6d", + "sha256": "6355750076724275e49f9a5faec383b2be92c0336ed58805a88954964bd13b86", + "bytes": 2876 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/common_pb2.py", + "mode": "100644", + "git_blob": "66031212a0da44800dcc671b0d4bf0cd39e71f06", + "sha256": "6736e3b86b3c8749d34065794da1c880772ce69e2f248fdd2febd003f083bbd3", + "bytes": 9746 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/control_pb2.py", + "mode": "100644", + "git_blob": "0597489cf8609a76e2094270965039da9b739ca3", + "sha256": "f2eea386aebf830ec47fa7379e6fb0493e0a199efecc7b90974bc8bb8c8b96b6", + "bytes": 20028 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/__init__.py", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/emg_batch_pb2.py", + "mode": "100644", + "git_blob": "d8495ebeb8ab140824eaa5412be0779cf929ec6a", + "sha256": "1db5ef51143a546072e34cc7be7b263db996fa5f4d0d71606b230cb75b531a14", + "bytes": 1624 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/imu_frame_pb2.py", + "mode": "100644", + "git_blob": "54bbf93dc638cdab95f49744ea7e0b43fefad374", + "sha256": "4a2048d2a737362bf26b99166e95c457d1492fcfba8848c894fe4d2748ff9f51", + "bytes": 2222 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/numeric_batch_pb2.py", + "mode": "100644", + "git_blob": "beedaaae054bfb083af3642c96ca7c64af14cc8d", + "sha256": "a087cc019b9849f4ef47bcdf4c789a7da90d443240b7bef97c832bb23c1d4e24", + "bytes": 1454 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/radar_doppler_pb2.py", + "mode": "100644", + "git_blob": "ad8fe84317d2f4049682f70bead19f90c6932457", + "sha256": "d1b85358aba0c2f4fc1745218463e9951224322604b18b068a2195359dcf790e", + "bytes": 1773 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/radar_frame_pb2.py", + "mode": "100644", + "git_blob": "cef636d7b030b037b23331eec9a86f3b152bc358", + "sha256": "995ddbbb0aa614afb15088cf039c741421c33ea3e3e963ef1a7361b24754b862", + "bytes": 1729 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/video_timing_pb2.py", + "mode": "100644", + "git_blob": "17937a141a9a2d81858cf52d74bc4705afc940b7", + "sha256": "002a79858ccd2d7763769a1fe1be6a16a7f6b8727d15f952d191bcd2240ba5ef", + "bytes": 1722 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/events_pb2.py", + "mode": "100644", + "git_blob": "030bd4a90be609403e7709605607d8d5b993776e", + "sha256": "72951a468b0480e7fefc4fd3f9b4caac5fda0abdadf4ffcca92d4f19286429ce", + "bytes": 5480 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/health_pb2.py", + "mode": "100644", + "git_blob": "b27bd32ec488168871ca2342062eb576d56a9e8e", + "sha256": "e1e0baa7073a9886e4d982d4f00020b490bfd46c32b1b4df129fd0477c1f5e61", + "bytes": 5898 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/presets_pb2.py", + "mode": "100644", + "git_blob": "d20925410185e5cf52bbc56e438534c1c5ff1102", + "sha256": "d27336594b548f2e6e7ae212fe6de198e6e699c62a5f27752f691d7928ccb27b", + "bytes": 2066 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/preview_pb2.py", + "mode": "100644", + "git_blob": "cb04387df1614a8b9d9755a702129bbbb8d6374e", + "sha256": "c992e91b9aef0aa0ec8d595eba2f7079889264d9e4de120b623afd1d8702c695", + "bytes": 5333 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/project_pb2.py", + "mode": "100644", + "git_blob": "a8e71f0a426858cc679cb87ce31d1379e70a2817", + "sha256": "983bc5715147297cdcecca343b9a450f2095fcc1e895859cc3c52a3213d933f5", + "bytes": 3355 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/source_pb2.py", + "mode": "100644", + "git_blob": "b72752efedc743d236713e51283dce923a526f55", + "sha256": "d15b443f27c910c0e809af19fed81d9c1a75f7112501df85877bf4bf9bc4f7a8", + "bytes": 8053 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/storage_pb2.py", + "mode": "100644", + "git_blob": "4dd1b48ab16900c5c3e88d9788cebf83ee93cc5a", + "sha256": "f7a7b8903af9bfc2d2a419622c86cc057aed2a898949e4261475a7ac61222474", + "bytes": 5487 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/worker_pb2.py", + "mode": "100644", + "git_blob": "7f3a4fc372384523638853f4bd458f49b664ba70", + "sha256": "112e832172913024c6fad128a9a9559bbcd14b18de06b1f2a3161ac380258dc0", + "bytes": 11165 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/handshake.py", + "mode": "100644", + "git_blob": "9386e73b3c1eecb683d9d0ca98ad415268e307af", + "sha256": "63f740c992edf8812f666b79f9cd866d9ea33e65e5b310a5ebda2f5ef98ac115", + "bytes": 4763 + }, + { + "path": "libs/python/capture_protocol/capture_protocol/structured_log.py", + "mode": "100644", + "git_blob": "fc9c97b288280f4473c6b3c5b5e6ff07332fad49", + "sha256": "3d7883833286ecc004248294badcc0c66e44a57ecb7844ef281828d797b3c4fc", + "bytes": 4657 + }, + { + "path": "libs/python/capture_protocol/pyproject.toml", + "mode": "100644", + "git_blob": "fa71ca45874d34076208507180c69c7a0e38fa76", + "sha256": "61b2e33b2de2a153fb994144f532402c1b6b8ed02afb627ba0a15239e726ca71", + "bytes": 355 + }, + { + "path": "libs/python/capture_session/capture_session/__init__.py", + "mode": "100644", + "git_blob": "894e3c152a98b6e804de90122572afbcd929b3da", + "sha256": "da530f86c0d1d584862868ddba9f7087ccf5dfbddd64dd1e577337ecfd776419", + "bytes": 2412 + }, + { + "path": "libs/python/capture_session/capture_session/app_paths.py", + "mode": "100644", + "git_blob": "46332cea7c62dd44247b219937ae6c8fbc747017", + "sha256": "363e4522240e2356cac7492589cb207a798bc1af6031139bd1fa94890f1c4bfd", + "bytes": 561 + }, + { + "path": "libs/python/capture_session/capture_session/package_reader.py", + "mode": "100644", + "git_blob": "91fbf913c5af8489968425d7ceac51c04233d3e0", + "sha256": "9a1d9e6e7d24341a083cee602af9538413e948f3369b22660e484356e3d34eb1", + "bytes": 6331 + }, + { + "path": "libs/python/capture_session/capture_session/registry.py", + "mode": "100644", + "git_blob": "c1d7799e1d2099424221b2f4af216a43a972c67a", + "sha256": "809b26ce8d8efc0559a3854cf85ea74b4e486fcd77d253ebfa76bade64b0a8d1", + "bytes": 13989 + }, + { + "path": "libs/python/capture_session/capture_session/settings_store.py", + "mode": "100644", + "git_blob": "41b99cdaa78011d3d9b753c3131f32c72af9699f", + "sha256": "7719524a1f106cc54befcd21088810f9ec28f0160c8e88f60c374e1545fdb98d", + "bytes": 4622 + }, + { + "path": "libs/python/capture_session/pyproject.toml", + "mode": "100644", + "git_blob": "c83450d780e97e5bd90feb48cef140917b6e47ff", + "sha256": "3484887da96d4a2f32de8471b537d849f077b195c729ff0cc29307681e8d4895", + "bytes": 389 + }, + { + "path": "libs/python/capture_worker/LICENSE", + "mode": "100644", + "git_blob": "d645695673349e3947e8e5ae42332d0ac3164cd7", + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30", + "bytes": 11358 + }, + { + "path": "libs/python/capture_worker/NOTICE", + "mode": "100644", + "git_blob": "d74f1cbf89d4c89f70b3e75ab71cfadea8b7128f", + "sha256": "2a7e69c4c7cd4e93a5cc9e9f984873a2d1276f465b91b10c71b951ebcfb2c588", + "bytes": 142 + }, + { + "path": "libs/python/capture_worker/capture_worker/__init__.py", + "mode": "100644", + "git_blob": "4bf1fc6b13bc4f5daab79d937ea89cf6c120cce3", + "sha256": "c7ba88e956df8460002637eb3d8678a4c7217e680a388f833a22f073dc80f8fd", + "bytes": 503 + }, + { + "path": "libs/python/capture_worker/capture_worker/__main__.py", + "mode": "100644", + "git_blob": "a1047121f4173802074eeb66e5dcaf6c542c29c1", + "sha256": "216422b76731bc985daa5fb0efe55a9d5ce600aa7e6081fa3df0c03afb6a893e", + "bytes": 150 + }, + { + "path": "libs/python/capture_worker/capture_worker/cli.py", + "mode": "100644", + "git_blob": "eb2d869f951f0205085b074d067282990657b5a0", + "sha256": "8a16c4cae0ffd11d4f9cd5d168f6abf1c6f9a4b5100e8edd18a29ce7d44d3f03", + "bytes": 1818 + }, + { + "path": "libs/python/capture_worker/capture_worker/preview.py", + "mode": "100644", + "git_blob": "c47abe8a118ea022931843bde802132548194eef", + "sha256": "38b483dc06c9215b73e4c56c222fe563957180a5be58761a2c6dd4ea200b8e31", + "bytes": 3202 + }, + { + "path": "libs/python/capture_worker/capture_worker/transport.py", + "mode": "100644", + "git_blob": "2e5e159bee3a0b5aa69bf90f62906feeffe23c8c", + "sha256": "020414c74bd08ec510e88da8c2f8b9ec5091a19cb585b4c54d2656b4bf300d35", + "bytes": 5033 + }, + { + "path": "libs/python/capture_worker/capture_worker/worker.py", + "mode": "100644", + "git_blob": "d5ed2999fbb958116d73a8fa6319356d8b7d751a", + "sha256": "19a0dfd16a65479de884d4359a3d65f1bc127d8a6d4b44b93c6251757510de68", + "bytes": 23439 + }, + { + "path": "libs/python/capture_worker/capture_worker/writer.py", + "mode": "100644", + "git_blob": "b3d194cc71dfa0d21884936a6ed5f7bdc95b3eb4", + "sha256": "b9e3b21ac26f2160da582a3f566a278dc4088c5a8b121d9b4e74f8d8c16cf96f", + "bytes": 6196 + }, + { + "path": "libs/python/capture_worker/pyproject.toml", + "mode": "100644", + "git_blob": "5d79642edc9c1809fda636d5dcd78ad33e67abcc", + "sha256": "0cba218b59a756185fedf72fb3a3307d1d9cb9218b6189ea92972d3cec139a46", + "bytes": 487 + }, + { + "path": "pyproject.toml", + "mode": "100644", + "git_blob": "52491c6beebc4b17983fc66bb8765154c33cf6d8", + "sha256": "0cb8de1ab3dfbfed84ff16b35f3c89c6440180183ee5851d5d80da83622e53d0", + "bytes": 1233 + }, + { + "path": "tests/conftest.py", + "mode": "100644", + "git_blob": "ad9b61fd8e9c1c3d74f91710d4e82dd7d899e6b4", + "sha256": "f669618fad17e906c91df7a1e9393fc7a54f458c6d62a4385436ba2622beca0e", + "bytes": 1773 + }, + { + "path": "tests/fixtures/mini_session/events/annotations.json", + "mode": "100644", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "bytes": 3 + }, + { + "path": "tests/fixtures/mini_session/events/checkpoints.json", + "mode": "100644", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "bytes": 3 + }, + { + "path": "tests/fixtures/mini_session/events/sync_anchors.json", + "mode": "100644", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570", + "bytes": 3 + }, + { + "path": "tests/fixtures/mini_session/integrity.json", + "mode": "100644", + "git_blob": "d10093b866427fcaed78a85e60e600d8657a86a7", + "sha256": "af5d9bacd3eace7e831d48dee83eb5d9f578f4f4819d92218c4b55b0cb3ed556", + "bytes": 227 + }, + { + "path": "tests/fixtures/mini_session/manifest.json", + "mode": "100644", + "git_blob": "800dab5b41774bc043ebdee4714195770e75229b", + "sha256": "c5254d3e4c0bc6a0ecaef124dc12d88117d647928a8e1725b71429097438d380", + "bytes": 235 + }, + { + "path": "tests/fixtures/mini_session/processing/.gitkeep", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/health/gaps.jsonl", + "mode": "100644", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "bytes": 0 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/source.json", + "mode": "100644", + "git_blob": "9528c95289b4b1b49d11d412b5ab2e3d019b4066", + "sha256": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10", + "bytes": 112 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap", + "mode": "100644", + "git_blob": "320ce3607fadf57d05cf506987d045cf5b62ad9f", + "sha256": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649", + "bytes": 28 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/streams/sim.emg.main.batch/stream.json", + "mode": "100644", + "git_blob": "12c4db8831572fc4ab3db9ba5f784fa236078e5f", + "sha256": "8f8c02b89fd93e55643151e5222488e1174dd97a6b7a74f3ae5da8215b4d68e1", + "bytes": 216 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/source.json", + "mode": "100644", + "git_blob": "fcc248c52b8319f5e7fd0067763b74640f0040dd", + "sha256": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8", + "bytes": 118 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap", + "mode": "100644", + "git_blob": "320ce3607fadf57d05cf506987d045cf5b62ad9f", + "sha256": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649", + "bytes": 28 + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json", + "mode": "100644", + "git_blob": "9c634d4af594372063fcc612331ba338ae95f8c9", + "sha256": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d", + "bytes": 219 + }, + { + "path": "tests/ui/test_analysis_history.py", + "mode": "100644", + "git_blob": "f013473f750b515a8305e2f7f8426b6520e26a65", + "sha256": "48175547922125c308fa49bbb84149e3dac8903902e7cc64fa7c15b4ca40eccd", + "bytes": 10465 + }, + { + "path": "workers/python_host/capture_sim/__init__.py", + "mode": "100644", + "git_blob": "2646a1792544ac97cba76fd7d7246c313604351e", + "sha256": "a3c8506a26d20b0b10cd55f00b019b7ddc1e2d4cb5cffd5c155d70ef338d21ae", + "bytes": 259 + }, + { + "path": "workers/python_host/capture_sim/advertise.py", + "mode": "100644", + "git_blob": "c93044ce53b7a38d2e7db9fcbad83174b394ffd2", + "sha256": "6a41dafed67d08d4e3829c053dc5a2767ae28293d63733b4b4ae187a8d4a94b9", + "bytes": 15205 + } + ] +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/README.md b/docs/evidence/analysis-history-401c5d17da79/current-scope/README.md new file mode 100644 index 00000000..f02292b8 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/README.md @@ -0,0 +1,23 @@ +# Current scope and saved-history receiving + +This one native journey qualifies the joined scope/history hooks on actual main `3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e`. The exact runtime tree is `167bbac3bba862cc1532d954fe2d503e561a00df`; the corrected screen is Git blob `6893f119593f8ff6551167efcb1939d014a081e6`. The two history modules and the original history tests retain their authored bytes. + +The three-way screen merge required one resolution in `set_package`: retain the current scope owner's resolved path, conditional scope reset and `package_loaded` signal, and pass that same path to history. A real startup check then exposed that `_sync_enabled()` runs before `thread.start()`. Counting the retained thread handle as busy keeps native controls reserved until the existing finished cleanup clears it. The worker and thread cleanup remain unchanged from the current parent. The start-job method keeps its current lifecycle and uses the authored _clear_result_view() helper in place of the two direct gallery/inspector clears; it is unchanged between the initial composition and the one-line busy correction. + +## Accepted current boundary + +The final method ran through actual `QApplication.exec()` and `QTimer`, using the real `SessionHeader`, `AnalysisScreen` and two real QThread/MCAP feature jobs. **24 checks passed, none failed; process exit 0 in 3.534 seconds.** It verifies selected nanosecond ranges in saved parameters and manifests, control disable/restore, explicit read-only reopening without replacing the next scope, same-package normalization, and rejection of a real queued A completion after switching to B. All 142 frozen source files and both packages' raw inputs stayed byte-identical. + +Both jobs intentionally use the existing `completed_with_warnings` contract. Each saved manifest contains exactly the two expected warnings for this fixture: its `sealed` state and absent duration integrity metadata. Exact custom range values are independently checked; no unexpected execution failure or warning is accepted as success. + +The captured frame was inspected. The new scope and history controls remain legible together. The unusually long private package path wraps and clips in the existing narrow left column, so this frame is not claimed as complete layout acceptance. + +## Controls and limits + +The complete first control on the uncorrected composition passed identity/range checks and failed the real startup Refresh-disable condition. Its method, source hashes, receipt and log remain separate. A later continuation encountered ENOSPC while capturing artifacts and produced no complete receipt; that attempt is not acceptance or a newly inferred product failure. The final method emits its full receipt and PNG to stdout before transport, and the native process exits normally. + +The original 14-test and 19-check successes remain pinned to runtime `37443f0d` on `72c15d6b` dependencies. The QC/2 successor remains pinned to `e43da3b8`. The separately recorded current nested-numeric gallery gap remains with its own owner. This is a Linux/PySide6 component journey; it does not claim a Windows MainWindow, full suite, daemon, hardware or installed-release result. + +## Replay + +Materialize only the 142 exact source files listed in `candidate-source-inputs.json` into an isolated source directory, preserving the recorded Git blobs and SHA-256 values. Use the existing CaptureSuite environment with PySide6 and its analysis dependencies; no installation is part of this receiver. Run `check_scope_history.py --source --inputs candidate-source-inputs.json --output ` with Python `-B`. The output directory must not already exist. Capture the line beginning `HAMON_SCOPE_HISTORY_RECEIPT `; it contains the complete report and the native PNG as base64. Persist its raw stdout and extracted PNG with hash readback. The method creates only its own package/state/output data and verifies source bytes before and after execution. diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/candidate-source-inputs.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/candidate-source-inputs.json new file mode 100644 index 00000000..e1199525 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/candidate-source-inputs.json @@ -0,0 +1,865 @@ +{ + "repository": "Jacob-Met/CaptureSuite", + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "canonical_tree": "18e97093f04de23de5e9878fd22c1f5ed986d5f3", + "history_author_runtime": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "composition_tree": "167bbac3bba862cc1532d954fe2d503e561a00df", + "composed_screen_git_blob": "6893f119593f8ff6551167efcb1939d014a081e6", + "files": [ + { + "path": "desktop/capture_desktop/__init__.py", + "git_blob": "48777bd04b62e3b3b877e12311f7257819ab3a07", + "bytes": 119, + "sha256": "8426c94323c4cca0879b8612345e3577d0a75f6239237a28d79d94a42004c3b5" + }, + { + "path": "desktop/capture_desktop/__main__.py", + "git_blob": "f78ccce984b725bf7263407d5b4b2d4c56131433", + "bytes": 723, + "sha256": "8dbad73a7373565a3513ccbb613f11bffdd13a05861c3e8e07392b8d51008aa2" + }, + { + "path": "desktop/capture_desktop/analysis_history.py", + "git_blob": "1b8fd23aee632cc3af19990b9d7685c6a3ed1b5e", + "bytes": 6375, + "sha256": "2e0db8cee59ef268d3c91ea0beac7d761d83a3003862841cc9d7f1782fd3543c" + }, + { + "path": "desktop/capture_desktop/app.py", + "git_blob": "363b6acbdcf0ba382bd040903946e6916ab282c9", + "bytes": 47945, + "sha256": "e33cf4446d4edfda3634cb5445aa9456d2f243a8b710c0d9c6497b2ec28078b2" + }, + { + "path": "desktop/capture_desktop/daemon_link.py", + "git_blob": "620e5a753fbd8448c3a57fcfa6a8b8540ac0bcd0", + "bytes": 10899, + "sha256": "ab76628bbe0231c7e5e4d570f2abed01100dddd6a24bb62020b670a6b62427dd" + }, + { + "path": "desktop/capture_desktop/export_wizard.py", + "git_blob": "b22d0098eb9af3860c654591e411dbab68a0f05d", + "bytes": 6734, + "sha256": "fb957ff184109bcb4e379dde30414048e855c93ec390f9b50c7ab603c3cd4e30" + }, + { + "path": "desktop/capture_desktop/main.py", + "git_blob": "90ad2adebae1f52ffabb889efe43a31dca1b6454", + "bytes": 1059, + "sha256": "e61c29a1925f8d85b24438f087dec360a4481a32e0dc2bd8ed8feb6629026e84" + }, + { + "path": "desktop/capture_desktop/persistence.py", + "git_blob": "2f2da2bfda654009baa0e723465c82c1690a0676", + "bytes": 3379, + "sha256": "cdb1fa0094fec72543d5051435850e51d78d79d4bde8d5c83520fa072a2c74c4" + }, + { + "path": "desktop/capture_desktop/schema_form.py", + "git_blob": "2d5fa62b1448e168e639e3e8879989a3461e1053", + "bytes": 12206, + "sha256": "7d825b5dc7566d630f31775df6fcc9def1e916eaff5be17a552bf89f28b3418b" + }, + { + "path": "desktop/capture_desktop/screen_analysis.py", + "git_blob": "6893f119593f8ff6551167efcb1939d014a081e6", + "bytes": 19038, + "sha256": "1475764b8453ed870174fcaf98bc02370db76b5001c4175feb93263ad33d5b70" + }, + { + "path": "desktop/capture_desktop/screen_capture.py", + "git_blob": "b2d3cf05d57484f5efdbb0df85e5f0a065dab3d9", + "bytes": 34181, + "sha256": "4e101ddeeaed7f7f2b4ec2ab2e4b1f4f55ebb86f73b394d25cfd2b904cd2572e" + }, + { + "path": "desktop/capture_desktop/screen_presets.py", + "git_blob": "c143fb87629fb90f656a7a3b4b9f3c136b03f596", + "bytes": 5230, + "sha256": "b62d6f4bef6c1f0fc04b9eaf6a8afd1b2eeb17f6ce14946a06b0495ba33d402c" + }, + { + "path": "desktop/capture_desktop/screen_review.py", + "git_blob": "88a902ca7699faa2964f3fc22ec3348a339905a4", + "bytes": 7003, + "sha256": "e5aff59de4b194123ca4c4518b34e7b6103326fbd6b0280e2122d984d01072ec" + }, + { + "path": "desktop/capture_desktop/screen_settings.py", + "git_blob": "fe6d1e8884b7300e4cb5039b8e86679339e43b4d", + "bytes": 4581, + "sha256": "519436946827fac53d0be68270c2929bd1ce615a58b2372e9e3fc10619a7ba6e" + }, + { + "path": "desktop/capture_desktop/screen_setup.py", + "git_blob": "1df45aac30d63d6ab2e8ddc7efe0db394c513ab1", + "bytes": 11452, + "sha256": "01eb01ffffe835fcf5d26120d508800cc3cdac1e91ffaa3d0d2fa669c6326182" + }, + { + "path": "desktop/capture_desktop/state.py", + "git_blob": "95046ba5ef7f7bbf5685a54b7ae8fd400814148c", + "bytes": 17906, + "sha256": "97fc98498f4553fc7f052d0dc4db992cf2fc136ba7c4405cd275bd156c74e314" + }, + { + "path": "desktop/capture_desktop/theme.py", + "git_blob": "e309ce92bf66f65ca7c111698e1f536f05e4dca9", + "bytes": 12072, + "sha256": "c77f24e1afeb06400385bd0d535800f13dc15d972891e1ff8af504cbe5c818f3" + }, + { + "path": "desktop/capture_desktop/widgets_analysis_history.py", + "git_blob": "8798627cd7d694c5a09c3c402a739a4ec45b6574", + "bytes": 8458, + "sha256": "a3b77c87483c1412b50de7ddde1498f6bfd3968002fc3ac3bfa474a2477d9bc4" + }, + { + "path": "desktop/capture_desktop/widgets_analysis_jobs.py", + "git_blob": "c4d2f4513032d744f1f8066f0c887cda71d9b911", + "bytes": 6304, + "sha256": "5cdea6045456e61a58b5525dd224a22a140962d31d2adc5b0102168444468f98" + }, + { + "path": "desktop/capture_desktop/widgets_analysis_plots.py", + "git_blob": "bb6c3033b5e4ed96a2e08857d38715b836926bf5", + "bytes": 9382, + "sha256": "85c73f881ee7d60ef2f868f7ff73fc57c0a4ef99a717f7f5015534db23e1ab86" + }, + { + "path": "desktop/capture_desktop/widgets_analysis_scope.py", + "git_blob": "7b15a34fc1f8a9f31164d4ee9b4d144ff01a8d2d", + "bytes": 10391, + "sha256": "3f58ffba9125d0ce88fa99317f6aa593fe8aeb4b0dc1d799c95c9c04fb0b73ff" + }, + { + "path": "desktop/capture_desktop/widgets_mappings.py", + "git_blob": "62dd1b137ffc54a05aa81f37eb8627dd12e0032a", + "bytes": 3658, + "sha256": "89808d37cb0fce476665a24766963c7a509f5b1802d05dedbf9ca44351081f4b" + }, + { + "path": "desktop/capture_desktop/widgets_modality_expanded.py", + "git_blob": "70d67f7405730707ad67d1da0e71a7e87bf8b68e", + "bytes": 8566, + "sha256": "12db25b37e8b2724e5eaabdcb1810aa979633885097b6ec11c33d98a46a83a70" + }, + { + "path": "desktop/capture_desktop/widgets_preview.py", + "git_blob": "d0a760164a413616ab406a54d81c7b3f9b30d638", + "bytes": 27254, + "sha256": "78d79c9af67f7e0cbcee3a3a693a22e72753256ca465bab7edb9c2037822dec4" + }, + { + "path": "desktop/capture_desktop/widgets_radar_array.py", + "git_blob": "d270e7aa8b36a9a6376cfbd76a46ec6448bb9ae4", + "bytes": 2965, + "sha256": "be08874ade0b4d9197ea85cb6ae3b30db75273ddd3c426faaaf28b4f796653a8" + }, + { + "path": "desktop/capture_desktop/widgets_session_header.py", + "git_blob": "b1f4cbf5ab35ef06b4bf1da45f0be6ffb34b0a4a", + "bytes": 5749, + "sha256": "b9e11a7e3709283ed37bacbe96836d6720467f2bdcb934d75491df5dc02927fa" + }, + { + "path": "desktop/capture_desktop/widgets_session_timeline.py", + "git_blob": "2d9ba524b1e6231c934f6d037796a53e135a12f8", + "bytes": 10010, + "sha256": "7671ad4b632fd83498ad0c02f9030e4f46a0ef2d99a3764c13de3996e3c2ade4" + }, + { + "path": "desktop/pyproject.toml", + "git_blob": "dada23f8692dfda4c7c07fc012608844c7f41ab9", + "bytes": 552, + "sha256": "3646f83dcc0764b3c8cb198b98b03201dc47808bb80bfec4837e329e47bd012f" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/__init__.py", + "git_blob": "67a4fb257b771af771edb4010e573ceeab86a51f", + "bytes": 497, + "sha256": "14cfe6dccd33a0bda74fac3c9339e1a37a3538b2110a8ae6e307801b776eb43a" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/discover.py", + "git_blob": "d5c4fa7e06ac6e9139ebfc78fade90a3df5e451a", + "bytes": 4023, + "sha256": "344ee5d7cb0f5e95ac7524a0c1141b0a293bb9445e2bd4789c6736f39cfcb90d" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/eval/__init__.py", + "git_blob": "140fcb2784c4b73ddf69d21ddccfdcc8191cc0aa", + "bytes": 154, + "sha256": "54661df9ed7d7e0d4b1c2ab5941f107ceb608e4fdfaff810014ef5fad1431fe1" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/eval/job.py", + "git_blob": "95d40a6c28aabcdc311c18e3e195627f29ceb1a7", + "bytes": 3984, + "sha256": "a7f2a43c2fc3723c471e42a5532465dc5cfa44d4411c6cf581bba6910603fc57" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/__init__.py", + "git_blob": "e52dc3839105744e19193f8fc8067b818389a20b", + "bytes": 66, + "sha256": "3cdd6c626b6da12b8df56d8ddf35fca27c0a744865965ec01dd89d47da476fa1" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/emg.py", + "git_blob": "7f7536500a63ddc8b06774b8da65df8d56cd4f2b", + "bytes": 3072, + "sha256": "11f8f8350464b7c7c079353ca649b4c4aad2580ef8d355fe741c025c262b168e" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/imu.py", + "git_blob": "0ee47b3d579e4c3732634958dda21ae724beca9e", + "bytes": 2605, + "sha256": "246bfd1cc3ce72afa0680537062b6795e22b8a06ba6301503d7489a4440c6849" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/io.py", + "git_blob": "b998063a5036b73a67b773f70c193b1f9827c248", + "bytes": 1409, + "sha256": "c677d209292cca790ccdf1a64ba834f71a078ccce31ea57452e67ece358822ca" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/numeric_batch.py", + "git_blob": "77f19ccb048c93c0f4fca460eef0502180b37717", + "bytes": 4030, + "sha256": "ecdeb88ca4dd093b973294a53954e9fa0e5d6b4b908225a52d097ef70c7d2154" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/radar_doppler.py", + "git_blob": "ee20f7314cb1af4512901d6009f73e3dddf9025c", + "bytes": 2289, + "sha256": "cffc0ecbb8053fbc2244850c1927469366f4ae93b5439e4d194de2065877fa5c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/radar_frame.py", + "git_blob": "e798dee0fb72dd261b504a99ac76f815515dda9e", + "bytes": 3323, + "sha256": "f85c5fe5e2db68606f68e36a42a0c8f323086f0b1e7f233c0ddefa24cdccb443" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/video_qc.py", + "git_blob": "fa73c80d39a0d699f80d7e877b37167cf8b48b6a", + "bytes": 1766, + "sha256": "0e25c50e01fc2da47bc7b510d68ba3e72aba33d3e1c79c57b727f5c55c723e27" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/grids.py", + "git_blob": "2e03f79d9317d2d97b721321130a9a5e6212b111", + "bytes": 1007, + "sha256": "936c5404783145f7a2bc4c13df22d3b85612bcb227115bba74f0b78a11c0c483" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/jobs.py", + "git_blob": "7badee5cdf5a4b30a283e0dcbb2c5d85fb787489", + "bytes": 19627, + "sha256": "e7e9dda44eb014d18192563f1e2c0ae78cece850fbc853b0be3919daaf5ee276" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/__init__.py", + "git_blob": "aaf360b8a0085f89b95cd976857f0933596098a7", + "bytes": 178, + "sha256": "50a0f7fd39648abf269fc549d2c17eb48b1dc9add10ebdb76edc1935d6f80160" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/compute.py", + "git_blob": "928751e9c861e2b0da298214269e57111f492865", + "bytes": 6899, + "sha256": "6e3ca19bfda0c02877f5d778f0c1191b5aebad605373732ef182bd714dd7f086" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/job.py", + "git_blob": "fb8be113d8699427072f6dbcdae222a37738ac18", + "bytes": 4523, + "sha256": "d676e84f54aa1ae2b0f998c2cb37c4e02541c1fd0e3464e38e9865c0049a7239" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/registry.py", + "git_blob": "a28cfd708c90552401fb0b3157c60f713a06e14f", + "bytes": 1155, + "sha256": "1e53fb9da4c6a2743bc1a3f0e687d94599cf995d33f2a2555e0ce5ebc3966d48" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/__init__.py", + "git_blob": "eb6fae21d4bb79055f8d1af1528e846020f21459", + "bytes": 361, + "sha256": "2d51c509baf3c0b5c33360637d12e5ce3c7507a859e4f37030f2c3d711ef0b3d" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/base.py", + "git_blob": "941a6aa3cea6777f90534ea634cccf8fdd319a3f", + "bytes": 2461, + "sha256": "696093b31f22d2bef32fc2962c7a11249a590a0b4d776c40cef4edcbc1e48a97" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/emg.py", + "git_blob": "c35d22af7bdeea570e6ae45a713428627e90894c", + "bytes": 3089, + "sha256": "86eb7114be689cdbd2edd76affa2994e7278714916692a35381abd02ba9d599a" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/imu.py", + "git_blob": "8823f04bd089789ca4cbff6602154bf066d4161d", + "bytes": 2773, + "sha256": "5ea4747145bf5588974dfd72c834766436c5a2bc0d58d34ace0f8ef403b310d6" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/mcap_iter.py", + "git_blob": "b61ca0a914e4d3909790839774327aa5824c1b71", + "bytes": 1196, + "sha256": "03a418e7689840e378665aac92c42769dd14ba2c88a821a5cbf0cee80766540c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/numeric_batch.py", + "git_blob": "668e5397d6a603d8665fe639b3218128bbda72c2", + "bytes": 7139, + "sha256": "7c84c0425c1b9b821df711f4c40ea89ac13f267dbe6472922eb41a9263e4835c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/radar_doppler.py", + "git_blob": "fc87bfb7fbbeb98ad8d5d11b3438b2d04882de6c", + "bytes": 1539, + "sha256": "4942d08eb47229839e339ce7f2f8a64aee7e5fab44bac77029fcd7a3e3e490c1" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/radar_frame.py", + "git_blob": "a44af5392ba2b5b8b64de685f42772b141f1b8b1", + "bytes": 1828, + "sha256": "d071f9d95b371798974698fd0caa1fc4c865a85fb772232fd43e7227b15fad2b" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/video.py", + "git_blob": "6a192cd5999b45df08c666b9dad21dc29cf91824", + "bytes": 2200, + "sha256": "3c3e873ab641904a39ca649dac39072f11948031d068cc21ee459e996d1fc185" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/ml_bundle/__init__.py", + "git_blob": "619d634ebf6fcc82a7871ad9c463660a24fd65ae", + "bytes": 179, + "sha256": "e785a2e3bf65852018d811b38ecbaf6ff9c479648025789145218809dd50d8a1" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/ml_bundle/job.py", + "git_blob": "59c2e4df46aa041e48aaf7184a3dd0ba345aff6d", + "bytes": 9419, + "sha256": "c14c74760e20c818ce5e2428d0b03a8a949899b0bba6c46e37fa8fd797631c75" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pipeline.py", + "git_blob": "8113ab4cb51678a122bbb702a23f2200c9333233", + "bytes": 5262, + "sha256": "e8c0152040ba5b5f3f37ac53fb5188bac9dd9aaf0d5816d6a718be505c20898c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/modality.py", + "git_blob": "1de343cc2e11e663501ba190441325d5637d1492", + "bytes": 2419, + "sha256": "bc3aa15ee79d50280a6c9d6aa144fe0519f85dd2c74a0cfa99323f7d57ecd28d" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/style.py", + "git_blob": "3725e840e5eb046accea79d4b6376f902392dac8", + "bytes": 1249, + "sha256": "231e7b1c998f4349d5859295007235ffd41848f12fbb7819193bec9630cd3942" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/sync_dashboard.py", + "git_blob": "828204e998a46b9571b3a2b3ba08acd9fc6caa31", + "bytes": 1149, + "sha256": "6f9e0c64193688eb841565729b9d1e9a64136779e892419acabdc81591afd3d5" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/__init__.py", + "git_blob": "39c9c93eab1f5abf65ea73299c34b05ec184dd63", + "bytes": 225, + "sha256": "c511d4b9cd1cda042b781b06fbb02d2d99004de214735d6daeb459d6e41381fe" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/dummy.py", + "git_blob": "0152651c271234bf38252bed51efda3a3fc19c0f", + "bytes": 1618, + "sha256": "facf059d247bca44f2697383e12cc1296b1d1d12bede1196f4a52a1352d60495" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/handlers.py", + "git_blob": "03c8589064dfc4c6cfec6e4d00b7f46b10014414", + "bytes": 10646, + "sha256": "9be2e1820529b94e54d06790d53aa94cf658f982efb4063c6b64f9d07acc4b2e" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/manifest.yaml", + "git_blob": "0628968ee3965170b486306f974c81dd4eb84a53", + "bytes": 3876, + "sha256": "1efe3ee2d9eeeeac03c2c03c582edf0119c9abd6d214dfdca3d827fa10a5c048" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/numeric.py", + "git_blob": "d8adbc1d90dbfdeac0cd9179c95f027532c1a5d4", + "bytes": 3390, + "sha256": "75b55cb453095ad5470ce2532b65d3dce771e6a2f8ad1e46a538b4291fa4cf93" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/registry.py", + "git_blob": "3c582e1ab0de2b22956ac47fb628227eacdd1faf", + "bytes": 5389, + "sha256": "33a4d07600db8b116fbd46b67492f62129df513df5b66a2c455dced0b2a9dc69" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pose/__init__.py", + "git_blob": "108be2956adfed6328f397d88a3b61ebada0ac48", + "bytes": 156, + "sha256": "d58a03cae86259b2cb0ecd0a5ce2347c6824f14cfea6871c94d76acc3541a380" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pose/job.py", + "git_blob": "1a1a3f2436b0ac8decc551f84e76fa6c4c6e602d", + "bytes": 6262, + "sha256": "1f4c44f443c07e22e8c9ca877232c6780c4b1da7834d5565b82cf547b2f4c439" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/qc.py", + "git_blob": "530b86af1247599c127e2d0c3fa5e4d7d12169f6", + "bytes": 9187, + "sha256": "f24e0593a3723311d41054aef40b56c4bb46d4f3ba5ef4b01afcae3a6cc4440a" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/report_html.py", + "git_blob": "bb8032024cfce30c6fe9a2bd2c13b0d2cbc2d102", + "bytes": 4716, + "sha256": "f2c89c7faf6e4edc265540140272396b4195eb5aed9edf05c4912aac74286f03" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/types.py", + "git_blob": "2adf26816e0ef9e84e6763cf8bbff69d64697949", + "bytes": 3428, + "sha256": "e7996d02483f69265a2ef2ec0b28078c86f4f479daa53e38faf8b4a62645d02c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/version.py", + "git_blob": "d04b8cc1dd9271ca3ccf836d97436d9a961417c6", + "bytes": 62, + "sha256": "9e25143344b110699f68b6acdbef49576fc91c2cbda34956d7e2cb85bbbc4ae3" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/windows.py", + "git_blob": "80bea6bd69365a48c5b204c26d054b8ae179437a", + "bytes": 5618, + "sha256": "af40235d55341d2a6b11d7f67a0195779676301fa822b2bd05240d138ee28c50" + }, + { + "path": "libs/python/capture_analysis/pyproject.toml", + "git_blob": "6db8b1158b14da660128d7ac0ceacb45b8eb9924", + "bytes": 677, + "sha256": "84cd96465e48439bdd81f5fa126fea5da11ee7587b488bfaaa67a4cd8f760c75" + }, + { + "path": "libs/python/capture_protocol/LICENSE", + "git_blob": "d645695673349e3947e8e5ae42332d0ac3164cd7", + "bytes": 11358, + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + { + "path": "libs/python/capture_protocol/NOTICE", + "git_blob": "7f9ac0678aa56452f06e6e5f3badc9a873e2008a", + "bytes": 124, + "sha256": "3efb470f58c900a58deaef889527e074206274b0fd5fb0e2e62613c093064307" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/__init__.py", + "git_blob": "0e7ab2cf8689d3adbc689c283e8a23d12607b2d0", + "bytes": 698, + "sha256": "556f474a3d740adc03c40426acde432ab7a394b947f8268bd90eecc7832dff8a" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/codec.py", + "git_blob": "3034065efca2c52e34c3e67e147bdda526d2c8db", + "bytes": 7011, + "sha256": "f6c09246a7b165358835e51b99b1508e68d840f4bdbd54b5fb72db33d4912712" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/config_schema.py", + "git_blob": "c9b4a694e620e5597d338230fcb0f25ea3a757f6", + "bytes": 8444, + "sha256": "00d855895faec7d674cdb8e4da1ddc687888c9e9863f91d4950d24d9fb815e6e" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/constants.py", + "git_blob": "2542cda6bdb6a83d4334336f34d92f80040bc4a0", + "bytes": 486, + "sha256": "7f187edf873cd13f55bc09ff7972785797eb488d74dd5befcb395fc928a71d72" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/control_client.py", + "git_blob": "45e1c4b535ece8d7178cd6b32ab1affcc9e73e92", + "bytes": 20823, + "sha256": "68de412465b2eaa04886a2bb4566aa0595c898df7d7e782b3031b8ba919db7fa" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/framing.py", + "git_blob": "9dd5021b815b31ab02eaaa814210525ebb543862", + "bytes": 2884, + "sha256": "3ff7c7284d9907a2ad516c83fab383a4151996da3f2d5a1d27e24d7c7575d92e" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/__init__.py", + "git_blob": "16ae7d90a122b4973139c563ac0f72efa061b1de", + "bytes": 90, + "sha256": "1fac8216894ce1a1b5362de3b59398fbd78f005a59636aea9f074951bed5c1d7" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/__init__.py", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/__init__.py", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/arrays_pb2.py", + "git_blob": "a29ed506c4dd33f697ba74d13b6e8a9c945c6b6d", + "bytes": 2876, + "sha256": "6355750076724275e49f9a5faec383b2be92c0336ed58805a88954964bd13b86" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/common_pb2.py", + "git_blob": "66031212a0da44800dcc671b0d4bf0cd39e71f06", + "bytes": 9746, + "sha256": "6736e3b86b3c8749d34065794da1c880772ce69e2f248fdd2febd003f083bbd3" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/control_pb2.py", + "git_blob": "0597489cf8609a76e2094270965039da9b739ca3", + "bytes": 20028, + "sha256": "f2eea386aebf830ec47fa7379e6fb0493e0a199efecc7b90974bc8bb8c8b96b6" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/__init__.py", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/emg_batch_pb2.py", + "git_blob": "d8495ebeb8ab140824eaa5412be0779cf929ec6a", + "bytes": 1624, + "sha256": "1db5ef51143a546072e34cc7be7b263db996fa5f4d0d71606b230cb75b531a14" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/imu_frame_pb2.py", + "git_blob": "54bbf93dc638cdab95f49744ea7e0b43fefad374", + "bytes": 2222, + "sha256": "4a2048d2a737362bf26b99166e95c457d1492fcfba8848c894fe4d2748ff9f51" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/numeric_batch_pb2.py", + "git_blob": "beedaaae054bfb083af3642c96ca7c64af14cc8d", + "bytes": 1454, + "sha256": "a087cc019b9849f4ef47bcdf4c789a7da90d443240b7bef97c832bb23c1d4e24" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/radar_doppler_pb2.py", + "git_blob": "ad8fe84317d2f4049682f70bead19f90c6932457", + "bytes": 1773, + "sha256": "d1b85358aba0c2f4fc1745218463e9951224322604b18b068a2195359dcf790e" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/radar_frame_pb2.py", + "git_blob": "cef636d7b030b037b23331eec9a86f3b152bc358", + "bytes": 1729, + "sha256": "995ddbbb0aa614afb15088cf039c741421c33ea3e3e963ef1a7361b24754b862" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/video_timing_pb2.py", + "git_blob": "17937a141a9a2d81858cf52d74bc4705afc940b7", + "bytes": 1722, + "sha256": "002a79858ccd2d7763769a1fe1be6a16a7f6b8727d15f952d191bcd2240ba5ef" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/events_pb2.py", + "git_blob": "030bd4a90be609403e7709605607d8d5b993776e", + "bytes": 5480, + "sha256": "72951a468b0480e7fefc4fd3f9b4caac5fda0abdadf4ffcca92d4f19286429ce" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/health_pb2.py", + "git_blob": "b27bd32ec488168871ca2342062eb576d56a9e8e", + "bytes": 5898, + "sha256": "e1e0baa7073a9886e4d982d4f00020b490bfd46c32b1b4df129fd0477c1f5e61" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/presets_pb2.py", + "git_blob": "d20925410185e5cf52bbc56e438534c1c5ff1102", + "bytes": 2066, + "sha256": "d27336594b548f2e6e7ae212fe6de198e6e699c62a5f27752f691d7928ccb27b" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/preview_pb2.py", + "git_blob": "cb04387df1614a8b9d9755a702129bbbb8d6374e", + "bytes": 5333, + "sha256": "c992e91b9aef0aa0ec8d595eba2f7079889264d9e4de120b623afd1d8702c695" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/project_pb2.py", + "git_blob": "a8e71f0a426858cc679cb87ce31d1379e70a2817", + "bytes": 3355, + "sha256": "983bc5715147297cdcecca343b9a450f2095fcc1e895859cc3c52a3213d933f5" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/source_pb2.py", + "git_blob": "b72752efedc743d236713e51283dce923a526f55", + "bytes": 8053, + "sha256": "d15b443f27c910c0e809af19fed81d9c1a75f7112501df85877bf4bf9bc4f7a8" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/storage_pb2.py", + "git_blob": "4dd1b48ab16900c5c3e88d9788cebf83ee93cc5a", + "bytes": 5487, + "sha256": "f7a7b8903af9bfc2d2a419622c86cc057aed2a898949e4261475a7ac61222474" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/worker_pb2.py", + "git_blob": "7f3a4fc372384523638853f4bd458f49b664ba70", + "bytes": 11165, + "sha256": "112e832172913024c6fad128a9a9559bbcd14b18de06b1f2a3161ac380258dc0" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/handshake.py", + "git_blob": "9386e73b3c1eecb683d9d0ca98ad415268e307af", + "bytes": 4763, + "sha256": "63f740c992edf8812f666b79f9cd866d9ea33e65e5b310a5ebda2f5ef98ac115" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/structured_log.py", + "git_blob": "fc9c97b288280f4473c6b3c5b5e6ff07332fad49", + "bytes": 4657, + "sha256": "3d7883833286ecc004248294badcc0c66e44a57ecb7844ef281828d797b3c4fc" + }, + { + "path": "libs/python/capture_protocol/pyproject.toml", + "git_blob": "fa71ca45874d34076208507180c69c7a0e38fa76", + "bytes": 355, + "sha256": "61b2e33b2de2a153fb994144f532402c1b6b8ed02afb627ba0a15239e726ca71" + }, + { + "path": "libs/python/capture_session/capture_session/__init__.py", + "git_blob": "894e3c152a98b6e804de90122572afbcd929b3da", + "bytes": 2412, + "sha256": "da530f86c0d1d584862868ddba9f7087ccf5dfbddd64dd1e577337ecfd776419" + }, + { + "path": "libs/python/capture_session/capture_session/app_paths.py", + "git_blob": "46332cea7c62dd44247b219937ae6c8fbc747017", + "bytes": 561, + "sha256": "363e4522240e2356cac7492589cb207a798bc1af6031139bd1fa94890f1c4bfd" + }, + { + "path": "libs/python/capture_session/capture_session/package_reader.py", + "git_blob": "91fbf913c5af8489968425d7ceac51c04233d3e0", + "bytes": 6331, + "sha256": "9a1d9e6e7d24341a083cee602af9538413e948f3369b22660e484356e3d34eb1" + }, + { + "path": "libs/python/capture_session/capture_session/registry.py", + "git_blob": "c1d7799e1d2099424221b2f4af216a43a972c67a", + "bytes": 13989, + "sha256": "809b26ce8d8efc0559a3854cf85ea74b4e486fcd77d253ebfa76bade64b0a8d1" + }, + { + "path": "libs/python/capture_session/capture_session/settings_store.py", + "git_blob": "41b99cdaa78011d3d9b753c3131f32c72af9699f", + "bytes": 4622, + "sha256": "7719524a1f106cc54befcd21088810f9ec28f0160c8e88f60c374e1545fdb98d" + }, + { + "path": "libs/python/capture_session/pyproject.toml", + "git_blob": "c83450d780e97e5bd90feb48cef140917b6e47ff", + "bytes": 389, + "sha256": "3484887da96d4a2f32de8471b537d849f077b195c729ff0cc29307681e8d4895" + }, + { + "path": "libs/python/capture_worker/LICENSE", + "git_blob": "d645695673349e3947e8e5ae42332d0ac3164cd7", + "bytes": 11358, + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + { + "path": "libs/python/capture_worker/NOTICE", + "git_blob": "d74f1cbf89d4c89f70b3e75ab71cfadea8b7128f", + "bytes": 142, + "sha256": "2a7e69c4c7cd4e93a5cc9e9f984873a2d1276f465b91b10c71b951ebcfb2c588" + }, + { + "path": "libs/python/capture_worker/capture_worker/__init__.py", + "git_blob": "4bf1fc6b13bc4f5daab79d937ea89cf6c120cce3", + "bytes": 503, + "sha256": "c7ba88e956df8460002637eb3d8678a4c7217e680a388f833a22f073dc80f8fd" + }, + { + "path": "libs/python/capture_worker/capture_worker/__main__.py", + "git_blob": "a1047121f4173802074eeb66e5dcaf6c542c29c1", + "bytes": 150, + "sha256": "216422b76731bc985daa5fb0efe55a9d5ce600aa7e6081fa3df0c03afb6a893e" + }, + { + "path": "libs/python/capture_worker/capture_worker/cli.py", + "git_blob": "eb2d869f951f0205085b074d067282990657b5a0", + "bytes": 1818, + "sha256": "8a16c4cae0ffd11d4f9cd5d168f6abf1c6f9a4b5100e8edd18a29ce7d44d3f03" + }, + { + "path": "libs/python/capture_worker/capture_worker/preview.py", + "git_blob": "c47abe8a118ea022931843bde802132548194eef", + "bytes": 3202, + "sha256": "38b483dc06c9215b73e4c56c222fe563957180a5be58761a2c6dd4ea200b8e31" + }, + { + "path": "libs/python/capture_worker/capture_worker/transport.py", + "git_blob": "2e5e159bee3a0b5aa69bf90f62906feeffe23c8c", + "bytes": 5033, + "sha256": "020414c74bd08ec510e88da8c2f8b9ec5091a19cb585b4c54d2656b4bf300d35" + }, + { + "path": "libs/python/capture_worker/capture_worker/worker.py", + "git_blob": "d5ed2999fbb958116d73a8fa6319356d8b7d751a", + "bytes": 23439, + "sha256": "19a0dfd16a65479de884d4359a3d65f1bc127d8a6d4b44b93c6251757510de68" + }, + { + "path": "libs/python/capture_worker/capture_worker/writer.py", + "git_blob": "b3d194cc71dfa0d21884936a6ed5f7bdc95b3eb4", + "bytes": 6196, + "sha256": "b9e3b21ac26f2160da582a3f566a278dc4088c5a8b121d9b4e74f8d8c16cf96f" + }, + { + "path": "libs/python/capture_worker/pyproject.toml", + "git_blob": "5d79642edc9c1809fda636d5dcd78ad33e67abcc", + "bytes": 487, + "sha256": "0cba218b59a756185fedf72fb3a3307d1d9cb9218b6189ea92972d3cec139a46" + }, + { + "path": "pyproject.toml", + "git_blob": "52491c6beebc4b17983fc66bb8765154c33cf6d8", + "bytes": 1233, + "sha256": "0cb8de1ab3dfbfed84ff16b35f3c89c6440180183ee5851d5d80da83622e53d0" + }, + { + "path": "tests/analysis/test_numeric_batch_pipeline.py", + "git_blob": "9485adb27d02ab88e65d87576a06b86869a0360b", + "bytes": 19230, + "sha256": "43369bd0fea48d2c8b7dee1d8128b3bb131b508b7b0a14512fc457fcfdb0ba3c" + }, + { + "path": "tests/conftest.py", + "git_blob": "ad9b61fd8e9c1c3d74f91710d4e82dd7d899e6b4", + "bytes": 1773, + "sha256": "f669618fad17e906c91df7a1e9393fc7a54f458c6d62a4385436ba2622beca0e" + }, + { + "path": "tests/fixtures/mini_session/events/annotations.json", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + { + "path": "tests/fixtures/mini_session/events/checkpoints.json", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + { + "path": "tests/fixtures/mini_session/events/sync_anchors.json", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + { + "path": "tests/fixtures/mini_session/integrity.json", + "git_blob": "d10093b866427fcaed78a85e60e600d8657a86a7", + "bytes": 227, + "sha256": "af5d9bacd3eace7e831d48dee83eb5d9f578f4f4819d92218c4b55b0cb3ed556" + }, + { + "path": "tests/fixtures/mini_session/manifest.json", + "git_blob": "800dab5b41774bc043ebdee4714195770e75229b", + "bytes": 235, + "sha256": "c5254d3e4c0bc6a0ecaef124dc12d88117d647928a8e1725b71429097438d380" + }, + { + "path": "tests/fixtures/mini_session/processing/.gitkeep", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/health/gaps.jsonl", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/source.json", + "git_blob": "9528c95289b4b1b49d11d412b5ab2e3d019b4066", + "bytes": 112, + "sha256": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap", + "git_blob": "320ce3607fadf57d05cf506987d045cf5b62ad9f", + "bytes": 28, + "sha256": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/streams/sim.emg.main.batch/stream.json", + "git_blob": "12c4db8831572fc4ab3db9ba5f784fa236078e5f", + "bytes": 216, + "sha256": "8f8c02b89fd93e55643151e5222488e1174dd97a6b7a74f3ae5da8215b4d68e1" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/source.json", + "git_blob": "fcc248c52b8319f5e7fd0067763b74640f0040dd", + "bytes": 118, + "sha256": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap", + "git_blob": "320ce3607fadf57d05cf506987d045cf5b62ad9f", + "bytes": 28, + "sha256": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json", + "git_blob": "9c634d4af594372063fcc612331ba338ae95f8c9", + "bytes": 219, + "sha256": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d" + }, + { + "path": "tests/ui/test_analysis_history.py", + "git_blob": "f013473f750b515a8305e2f7f8426b6520e26a65", + "bytes": 10465, + "sha256": "48175547922125c308fa49bbb84149e3dac8903902e7cc64fa7c15b4ca40eccd" + }, + { + "path": "workers/python_host/capture_sim/__init__.py", + "git_blob": "2646a1792544ac97cba76fd7d7246c313604351e", + "bytes": 259, + "sha256": "a3c8506a26d20b0b10cd55f00b019b7ddc1e2d4cb5cffd5c155d70ef338d21ae" + }, + { + "path": "workers/python_host/capture_sim/advertise.py", + "git_blob": "c93044ce53b7a38d2e7db9fcbad83174b394ffd2", + "bytes": 15205, + "sha256": "6a41dafed67d08d4e3829c053dc5a2767ae28293d63733b4b4ae187a8d4a94b9" + } + ], + "scope": "Exact Python/fixture slice for one native scope/history composition journey; no Windows MainWindow or complete suite claim.", + "prior_composed_runtime_tree": "07d78241dca691015bb3e4d8d260b109672b7de0", + "isolation": "Unchanged immutable source leaves may reuse only this worker's frozen receiving slice via hard links; the sole changed screen must be independently written. Both trees are checked for unchanged bytes." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/check_scope_history.py b/docs/evidence/analysis-history-401c5d17da79/current-scope/check_scope_history.py new file mode 100644 index 00000000..8e4b3973 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/check_scope_history.py @@ -0,0 +1,272 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""One real native scope/history journey on the received current source.""" +from pathlib import Path +import argparse +import base64 +import hashlib +import importlib.util +import json +import os +import sys +import time +import traceback + + +def hashes(root, raw_only=False): + return {p.relative_to(root).as_posix(): hashlib.sha256(p.read_bytes()).hexdigest() + for p in sorted(root.rglob("*")) if p.is_file() + and (not raw_only or "processing" not in p.relative_to(root).parts)} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--source", type=Path, required=True) + parser.add_argument("--inputs", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + args = parser.parse_args() + source, output = args.source.resolve(), args.output.resolve() + assert source != output and source not in output.parents and not output.exists() + inputs = json.loads(args.inputs.read_bytes()) + expected = {row["path"]: row["sha256"] for row in inputs["files"]} + assert hashes(source) == expected + output.mkdir(parents=True) + for key, name in [("LOCALAPPDATA", "local"), ("APPDATA", "roaming"), + ("XDG_CONFIG_HOME", "config"), ("XDG_DATA_HOME", "data"), + ("XDG_CACHE_HOME", "cache"), ("MPLCONFIGDIR", "mpl"), + ("TMPDIR", "tmp"), ("XDG_RUNTIME_DIR", "runtime")]: + directory = output / "state" / name + directory.mkdir(parents=True, mode=0o700) + os.environ[key] = str(directory) + os.environ["QT_QPA_PLATFORM"] = "offscreen" + sys.dont_write_bytecode = True + for rel in reversed(["desktop", "libs/python/capture_analysis", "libs/python/capture_session", + "libs/python/capture_protocol", "libs/python/capture_protocol/capture_protocol/generated", + "libs/python/capture_worker"]): + sys.path.insert(0, str(source / rel)) + report = {"canonical_parent": inputs["canonical_parent"], "runtime_tree": inputs["composition_tree"], + "screen_git_blob": inputs["composed_screen_git_blob"], "checks": [], "errors": [], + "method": "QApplication.exec/QTimer; actual SessionHeader and AnalysisScreen, two real QThread/MCAP feature jobs", + "method_sha256": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), + "source_inputs_sha256": hashlib.sha256(args.inputs.read_bytes()).hexdigest(), + "scope": "One changed scope/history boundary. No Windows MainWindow, full-suite, nested-image repair or installed-release claim."} + + def check(name, condition, *, fatal=True): + report["checks"].append({"name": name, "passed": bool(condition)}) + if fatal: + assert condition, name + + try: + import PySide6 + from PySide6.QtCore import QBuffer, QCoreApplication, QEvent, QIODevice, QTimer, Qt + from PySide6.QtTest import QTest + from PySide6.QtWidgets import QApplication, QMessageBox, QPlainTextEdit, QVBoxLayout, QWidget + from capture_desktop import theme + from capture_desktop.screen_analysis import AnalysisScreen + from capture_desktop.state import CaptureState + from capture_desktop.widgets_session_header import SessionHeader + helper_path = source / "tests/analysis/test_numeric_batch_pipeline.py" + spec = importlib.util.spec_from_file_location("current_numeric_fixture", helper_path) + fixture = importlib.util.module_from_spec(spec) + spec.loader.exec_module(fixture) + + def package(name): + root = output / (name + ".mmsession") + root.mkdir() + (root / "manifest.json").write_text(json.dumps({"sessionId": name, "state": "sealed"}) + "\n") + stream = root / "sources/lsl/streams/numeric" + stream.mkdir(parents=True) + fixture._write_mcap(stream / "segments/000000.mcap", [(1_000_000_000, fixture._batch())]) + (stream / "stream.json").write_text(json.dumps({"sourceId": "lsl", "streamId": "numeric.stream", "modality": "eeg", "dataSchemaId": "generic.numeric_batch/1", "nominalRateHz": 2.0, "units": "V", "dimensions": [2]}) + "\n") + return root + + first, second = package("scope history A"), package("scope history B") + raw_before = {str(p): hashes(p, raw_only=True) for p in [first, second]} + app = QApplication([]) + theme.apply_theme(app, setting="dark") + shell = QWidget() + layout = QVBoxLayout(shell) + header, screen = SessionHeader(), AnalysisScreen(CaptureState()) + layout.addWidget(header) + layout.addWidget(screen, 1) + header.scope_changed.connect(screen.set_scope) + + def package_loaded(summary): + if summary is None: + header.clear() + else: + header.refresh_sealed(summary, selection=screen.scope) + + screen.package_loaded.connect(package_loaded) + shell.resize(1280, 1050) + shell.show() + picker = header._scope_picker + state = {"phase": "start", "deadline": time.monotonic() + 50, "dialogs": [], "cancelled": False} + ranges = [(1_500_000_001, 2_500_000_001), (1_000_000_001, 2_000_000_001)] + + def choose(bounds): + picker._mode.setCurrentIndex(picker._mode.findData("range")) + picker._start.setText(f"{bounds[0] // 10**9}.{bounds[0] % 10**9:09d}") + picker._end.setText(f"{bounds[1] // 10**9}.{bounds[1] % 10**9:09d}") + + def jobs(root): + directory = root / "processing/jobs" + return set(directory.iterdir()) if directory.exists() else set() + + def assert_job(job, bounds): + params = json.loads((job / "params.json").read_bytes()) + manifest = json.loads((job / "job_manifest.json").read_bytes()) + check("real saved job retains its exact selected nanosecond parameters", + (params["startSessionNs"], params["endSessionNs"]) == bounds and params["checkpointSection"] is None) + check("completed current numeric job reports that selected interval", + (manifest["timeRange"]["startSessionNs"], manifest["timeRange"]["endSessionNs"]) == bounds + and manifest["status"] == "completed_with_warnings") + check("successful saved job contains only the two expected fixture metadata warnings", + manifest["warnings"] == [ + "package state is 'sealed' (prefer finalized)", + "package duration_ns is unknown/zero — analysis uses an open time window (integrity entries lack endSessionTimeNs)", + ]) + report.setdefault("saved_job_manifests", []).append(manifest) + return params, manifest + + def finish(): + timer.stop() + shell.close() + app.quit() + + def tick(): + try: + modal = QApplication.activeModalWidget() + if isinstance(modal, QMessageBox): + state["dialogs"].append(modal.text()) + modal.accept() + if state["cancelled"]: + if screen._thread is None: + finish() + return + if time.monotonic() > state["deadline"]: + raise TimeoutError("The bounded native scope/history journey did not finish.") + phase = state["phase"] + if phase == "start": + screen.set_package(str(first) + "/.") + check("screen, header and history use one normalized package identity", + screen.package_path == header.package_path == screen._history.package == str(first)) + screen._command.setCurrentIndex(screen._command.findData("features")) + choose(ranges[0]) + check("real header selection enables the composed Analysis screen with exact bounds", + screen._btn_run.isEnabled() and screen.scope is picker.selection + and (screen.scope.start_ns, screen.scope.end_ns) == ranges[0]) + QTest.mouseClick(screen._btn_run, Qt.MouseButton.LeftButton) + check("real feature worker disables saved-history actions while running", + screen._thread is not None and not screen._history._open.isEnabled() + and not screen._history._refresh.isEnabled(), fatal=False) + report["initial_busy_state"] = {"thread_retained": screen._thread is not None, "thread_running": screen._thread.isRunning() if screen._thread is not None else False, "history_refresh_enabled": screen._history._refresh.isEnabled(), "history_open_enabled": screen._history._open.isEnabled()} + state["phase"] = "first-job" + elif phase == "first-job" and screen._thread is None: + check("the first real worker completes without a modal failure", not state["dialogs"]) + check("settled first job restores native Run and history controls", + screen._btn_run.isEnabled() and not screen._btn_cancel.isEnabled() + and screen._history._refresh.isEnabled() and screen._history._open.isEnabled() + and screen._history._details.isEnabled()) + check("completed scoped job reaches the saved-history viewer", + len(jobs(first)) == 1 and bool(screen._last_job_dir) + and screen._history.loaded_job_id == Path(screen._last_job_dir).name) + job = Path(screen._last_job_dir) + assert_job(job, ranges[0]) + state["first_job"] = job + state["saved_bytes"] = hashes(job) + choose(ranges[1]) + selected = screen.scope + QTest.mouseClick(screen._history._refresh, Qt.MouseButton.LeftButton) + QTest.mouseClick(screen._history._open, Qt.MouseButton.LeftButton) + check("explicitly reopening the old job preserves the next selected scope", + screen.scope == picker.selection == selected + and (selected.start_ns, selected.end_ns) == ranges[1]) + check("reopen is read-only and starts no additional worker", + hashes(job) == state["saved_bytes"] and jobs(first) == {job} + and screen._thread is None) + QTest.mouseClick(screen._history._details, Qt.MouseButton.LeftButton) + dialog = screen._history._dialog + params_editor = dialog.findChild(QPlainTextEdit, "analysisHistoryParameters") + saved_params = json.loads(params_editor.toPlainText()) + check("native read-only details show the saved scope, distinct from the next selection", + params_editor.isReadOnly() + and (saved_params["startSessionNs"], saved_params["endSessionNs"]) == ranges[0] + and screen.scope == selected) + dialog.close() + screen.set_package(str(first) + "/.") + check("same-package refresh preserves both scope and loaded saved result", + screen.scope == picker.selection == selected + and screen._history.loaded_job_id == job.name) + state["phase"] = "capture-and-second-job" + elif phase == "capture-and-second-job": + buffer = QBuffer() + buffer.open(QIODevice.OpenModeFlag.WriteOnly) + captured = shell.grab().save(buffer, "PNG") + frame = bytes(buffer.data()) + buffer.close() + check("combined native frame is captured", captured and frame.startswith(b"\x89PNG\r\n\x1a\n")) + report["native_frame"] = {"filename": "scope-history-reopened.png", "bytes": len(frame), "sha256": hashlib.sha256(frame).hexdigest(), "base64": base64.b64encode(frame).decode()} + state["jobs_before_second"] = jobs(first) + QTest.mouseClick(screen._btn_run, Qt.MouseButton.LeftButton) + check("a second real worker starts from the next selection", screen._thread is not None) + # The current application may change package context while a + # worker is pending. Its real queued completion must stay A. + screen.set_package(str(second)) + check("changing package resets scope and clears history as one transition", + screen.package_path == header.package_path == screen._history.package == str(second) + and screen.scope.mode == picker.selection.mode == "full" + and not screen._last_job_dir and not screen._history.loaded_job_id) + state["phase"] = "second-job" + elif phase == "second-job" and screen._thread is None: + completed = jobs(first) - state["jobs_before_second"] + check("late real completion is retained under its originating package only", + len(completed) == 1 and not jobs(second) and not state["dialogs"]) + second_job = next(iter(completed)) + assert_job(second_job, ranges[1]) + check("late foreign completion cannot repaint current history or scope", + screen.package_path == str(second) and screen.scope.mode == picker.selection.mode == "full" + and not screen._last_job_dir and not screen._history.loaded_job_id + and "Result saved for the previous package" in screen._log.toPlainText()) + check("late-job settlement restores controls for the current package only", + screen._btn_run.isEnabled() and not screen._btn_cancel.isEnabled() + and screen._history._refresh.isEnabled() and not screen._history._open.isEnabled()) + check("the prior reopened job remains byte-identical after the second job", + hashes(state["first_job"]) == state["saved_bytes"]) + check("both real package raw inputs remain byte-identical", + all(hashes(p, raw_only=True) == raw_before[str(p)] for p in [first, second])) + report["real_jobs"] = [str(state["first_job"]), str(second_job)] + report["raw_package_hashes"] = raw_before + report["last_native_log"] = screen._log.toPlainText() + report["dialogs"] = state["dialogs"] + finish() + except BaseException: + report["errors"].append(traceback.format_exc()) + state["cancelled"] = True + if screen._thread is not None: + screen._cancel_job() + else: + finish() + + timer = QTimer() + timer.timeout.connect(tick) + timer.start(15) + report["event_loop_exit"] = app.exec() + shell.deleteLater() + QCoreApplication.sendPostedEvents(None, QEvent.Type.DeferredDelete) + app.processEvents() + report["pyside6"] = PySide6.__version__ + report["python"] = sys.version + except BaseException: + report["errors"].append(traceback.format_exc()) + report["source_unchanged"] = hashes(source) == expected + report["passed"] = sum(row["passed"] for row in report["checks"]) + report["failed"] = sum(not row["passed"] for row in report["checks"]) + report["exit_code"] = 0 if not report["errors"] and not report["failed"] and report["source_unchanged"] else 1 + # Emit the complete native receipt and frame before the caller persists them. + # Package/job writes stay real; artifact transport cannot erase an outcome. + print("HAMON_SCOPE_HISTORY_RECEIPT " + json.dumps(report, separators=(",", ":")), flush=True) + return report["exit_code"] + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/custody.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/custody.json new file mode 100644 index 00000000..ea5d347c --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/custody.json @@ -0,0 +1,100 @@ +{ + "schema": "hamon.exact-source-custody.v1", + "source_and_method_destination": "/Users/me/hamon/estate-401c5d17da79/capturesuite-history/scope-prepared-6893f119", + "prepared_checkpoint": { + "schema": "hamon.prepared-source-custody.v1", + "root": "/Users/me/hamon/estate-401c5d17da79/capturesuite-history/scope-prepared-6893f119", + "uid": 501, + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "runtime_tree": "167bbac3bba862cc1532d954fe2d503e561a00df", + "candidate_screen_blob": "6893f119593f8ff6551167efcb1939d014a081e6", + "files": [ + { + "path": "screen_analysis.py", + "bytes": 19038, + "sha256": "1475764b8453ed870174fcaf98bc02370db76b5001c4175feb93263ad33d5b70" + }, + { + "path": "check_scope_history.py", + "bytes": 16423, + "sha256": "c45eb2b2b02b8c9423565d811ae7782eff576b1313bf5cef366c4af8bf4e3802" + }, + { + "path": "candidate-source-inputs.json", + "bytes": 36983, + "sha256": "7e2d4d219c8a4b70865f780750fa8fe5362da54a43898097082a44784f807438" + }, + { + "path": "correction.diff", + "bytes": 411, + "sha256": "a673362be10374234e4c0a7747db5dc0ebe4d197c9053a8791204b703cbeb79d" + }, + { + "path": "startup-negative.json", + "bytes": 1711, + "sha256": "5c31757b0432077a91140cb4deb60503f83e353cb4eb2e1fe9c384a76e6e36f6" + } + ], + "preparation_sha256": "047a3ec794ef2037c116ab68de6544f191163909498d58fea13ab4dbb6c95e1a", + "source_blobs_and_changed_trees_verified": true, + "native_acceptance": "Pending actual corrected native journey; this checkpoint preserves source and receiver, not acceptance." + }, + "prepared_checkpoint_sha256": "3f1fdce7f3db1506b8f617adb3eb6b930e0af4aa3eb4eb225c2e3ff9b00e8d67", + "qualified_receiving_destination": "/Users/me/hamon/estate-401c5d17da79/capturesuite-history/scope-prepared-6893f119/qualified-receiving", + "qualified_checkpoint": { + "schema": "hamon.native-receiving-custody.v1", + "root": "/Users/me/hamon/estate-401c5d17da79/capturesuite-history/scope-prepared-6893f119/qualified-receiving", + "runtime_tree": "167bbac3bba862cc1532d954fe2d503e561a00df", + "screen_git_blob": "6893f119593f8ff6551167efcb1939d014a081e6", + "method_sha256": "c45eb2b2b02b8c9423565d811ae7782eff576b1313bf5cef366c4af8bf4e3802", + "native_platform": "Linux Python3.12/PySide6 6.11.2 from the established CaptureSuite environment; Mac is custody only", + "process_exit_code": 0, + "checks_passed": 24, + "checks_failed": 0, + "seconds": 3.534, + "raw_stdout_and_stderr_sha_verified": true, + "frame_extracted_and_read_back_exact": true, + "files": [ + { + "path": "README.md", + "bytes": 3748, + "sha256": "983f657b0ab4bc194c16cb3938d2494d110ecd3fd5f4c0de7890f6f0b8de306e" + }, + { + "path": "native.stderr.log", + "bytes": 250, + "sha256": "bcd516d5e9014bd0f43bf526bc701b744bbd4ea9c35d16fdd65e6fde7b0270d5" + }, + { + "path": "native.stdout.log", + "bytes": 268056, + "sha256": "aab4b265957f5404474d87c430bb03167b3514fb8fb05399e23cf5534f4b9c70" + }, + { + "path": "process.json", + "bytes": 817, + "sha256": "668d3732d79062b8390c6f9b2660bebca1b1deb566b0852a049d7a952fc217f6" + }, + { + "path": "receipt.json", + "bytes": 13734, + "sha256": "2b7114760bd212372ae1071c4954e1904724010c486cbff510f254f1f2fa9471" + }, + { + "path": "receiving.json", + "bytes": 2196, + "sha256": "31e28e425b8dfc74b5224418671d6720cd3ddc86a2fd7fae0ba2e5210330403f" + }, + { + "path": "scope-history-reopened.png", + "bytes": 193004, + "sha256": "c8ec0afb810a76da3254e035cdac3a5e0ec46097976743e1917e672441a550f5" + } + ], + "qualification_scope": "One current scope/history journey; original 37443/72c15 acceptance and e43 QC remain separate." + }, + "qualified_checkpoint_sha256": "69757fc3f931d781c999a728e7ae3d381999c94a267f3d93d961cc5f6f7c5059", + "verification": "Both checkpoints were independently read back through RDC and SHA-256 matched. Full final native stdout and its embedded original PNG are preserved in the qualified receiving destination.", + "prior_0ed_packet": "/Users/me/hamon/estate-401c5d17da79/capturesuite-history/source-pr-0ed1ccaa-2355dee/packet", + "prior_0ed_checkpoint_sha256": "7ec1926ff45e95b1034cbd0b14919fcfcd5896ee4a7ac63b0f70a9450d651839" +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/freshness-d43.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/freshness-d43.json new file mode 100644 index 00000000..1711f6fe --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/freshness-d43.json @@ -0,0 +1,346 @@ +{ + "schema": "hamon.capture-history-publication-freshness.v1", + "repository": "Jacob-Met/CaptureSuite", + "qualified_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "latest_observed_main": "d43bdea867d6198a707a5f55e29216c76054517e", + "source_url": "https://api.github.com/repos/Jacob-Met/CaptureSuite/compare/3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e...d43bdea867d6198a707a5f55e29216c76054517e", + "compare_html_url": "https://github.com/Jacob-Met/CaptureSuite/compare/3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e...d43bdea867d6198a707a5f55e29216c76054517e", + "base_commit": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "merge_base_commit": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "status": "ahead", + "ahead_by": 3, + "behind_by": 0, + "total_commits": 3, + "commits": [ + { + "sha": "0dd591b41bea35ce0639bba312d6f56b77f68088", + "parents": [ + "e43da3b855475c8aacf815c201fa03eddaeec0f1" + ], + "message": "Preserve missing pose evidence in kinematic labels\n\nMask non-simulated landmarks by each joint's required finite geometry and confidence instead of selecting synthetic fallback angles. Retain independent limb validity and NaN velocity/AFR values at invalid frames, with unchanged complete-geometry and explicit-sim Parquet bytes.\n\nReceive the frozen 21-test native author result, independent four-workflow/36-assertion CLI review, and one current-QC/report CLI composition check. Preserve all 777 unrelated current-main leaves and the complete current progress log. Existing supported Windows CI remains required before merge.\n\nCloses #56" + }, + { + "sha": "711e8ec22d462b7588e52727cf3d6524d7524c7a", + "parents": [ + "0dd591b41bea35ce0639bba312d6f56b77f68088", + "284d168d7614e2465bafba1092d8cbe4b6e13b40" + ], + "message": "Merge current main and retain both kinematics and storage progress entries\n\nPreserve all37 frozen non-PROGRESS contribution leaves and all815 unrelated current-main leaves. Resolve only the concurrent PROGRESS prepend, retaining the exact current log plus the original1527-byte entry. Runtime, regression tests and receiving evidence are unchanged." + }, + { + "sha": "d43bdea867d6198a707a5f55e29216c76054517e", + "parents": [ + "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "711e8ec22d462b7588e52727cf3d6524d7524c7a" + ], + "message": "Preserve missing pose evidence in kinematic labels\n\nKeep absent or invalid non-simulated pose geometry masked independently for each elbow and shoulder. Preserve complete-input and explicit-simulation math; only explicit sim_ models select fixture equations.\n\nQualified source head 711e8ec22d462b7588e52727cf3d6524d7524c7a with the current desktop scope and Windows atomic-write changes in actual CI checkout dc9ab33f4b3f3aefbb6308bbffb4e3f041d4b524, tree fea0e03773742d330963b89e0ceb72a22c7ad495. Windows run 37786404581 passed 400 Python tests with six missing-daemon skips, all 30 CTests, and all six separate native daemon/recovery cases without skips. All existing workflow gates remain unchanged.\n\nIndependent real CLI receiving passed 4/4 cases and36 assertions; baseline complete geometry and explicit sim Parquet bytes remain exact. All37 non-progress contribution leaves, all current unrelated leaves and the complete prior progress log were received from current3e3ecc5e. Original negative evidence and both CI generations are preserved. No installed release or physical measurement claim.\n\nCloses #56." + } + ], + "files": [ + { + "filename": "docs/design/KINEMATICS_PIPELINE.md", + "status": "modified", + "sha": "4206818b8834c56db530ca939b04cfe59e73aff6", + "additions": 24, + "deletions": 0, + "changes": 24 + }, + { + "filename": "docs/design/research/PROGRESS.md", + "status": "modified", + "sha": "36b05b80604935e3c70d1f076be5150e8639c164", + "additions": 24, + "deletions": 0, + "changes": 24 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/README.md", + "status": "added", + "sha": "5eee94afdfc2af12ad806fb816c3a9bf7f56f480", + "additions": 113, + "deletions": 0, + "changes": 113 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/author-receipt.json", + "status": "added", + "sha": "c51c2acc07ef57aae579c908f1fe3c31bb4b472c", + "additions": 60, + "deletions": 0, + "changes": 60 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-native-readback.json", + "status": "added", + "sha": "2110facf1a59ad9c1656aed76a09fad3cf8496cf", + "additions": 7, + "deletions": 0, + "changes": 7 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-runtime.tar.gz", + "status": "added", + "sha": "e973cff1bb0a0bffd768bf9fcef5400834ab2280", + "additions": 0, + "deletions": 0, + "changes": 0 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-source-manifest.json", + "status": "added", + "sha": "90416594a540a5227a70071b7597c87b291ff8de", + "additions": 812, + "deletions": 0, + "changes": 812 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-tests.json", + "status": "added", + "sha": "dc03cfdffaabb0209fd855482e78abb21179a658", + "additions": 298, + "deletions": 0, + "changes": 298 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-tests.log", + "status": "added", + "sha": "16860275d5331b2398cf48b0a2dca14601534df8", + "additions": 289, + "deletions": 0, + "changes": 289 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-tests.xml", + "status": "added", + "sha": "ed4db6467dd4d1410cc51e45097269ced09ef5c6", + "additions": 232, + "deletions": 0, + "changes": 232 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-native-readback.json", + "status": "added", + "sha": "369ab414496f49d86b28afa8a7a78b6b1e7a4e92", + "additions": 12, + "deletions": 0, + "changes": 12 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-source-manifest.json", + "status": "added", + "sha": "4fb157009d615aef9c7e000355df2d1750d56392", + "additions": 35, + "deletions": 0, + "changes": 35 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-tests.json", + "status": "added", + "sha": "15e3c7ebfc9af89e52f7d9ad5c31aaac0bf22d9f", + "additions": 301, + "deletions": 0, + "changes": 301 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-tests.log", + "status": "added", + "sha": "c124b9b2ffcbebd9cc3e5f87ac061017abf78741", + "additions": 12, + "deletions": 0, + "changes": 12 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-tests.xml", + "status": "added", + "sha": "6c202590a276a097c6b037d7939dce273fc5aaf2", + "additions": 1, + "deletions": 0, + "changes": 1 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/environment.json", + "status": "added", + "sha": "345664d3eb842ccc52018d36bd81cd9e892463ff", + "additions": 19, + "deletions": 0, + "changes": 19 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/manifest.json", + "status": "added", + "sha": "e96529b2c4475276c8483ca62414875ff049b596", + "additions": 100, + "deletions": 0, + "changes": 100 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/product.patch", + "status": "added", + "sha": "5f5581fb530ed1ee5f45ae89116dd772b2c00ca8", + "additions": 430, + "deletions": 0, + "changes": 430 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/static-checks.json", + "status": "added", + "sha": "fb1093707700a5fbbc746d7fcb3d4d6a29f6f0c6", + "additions": 28, + "deletions": 0, + "changes": 28 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/test-artifact-manifest.json", + "status": "added", + "sha": "b84b3cbc9bc474efa700cc7e1d632b162628ef1a", + "additions": 1665, + "deletions": 0, + "changes": 1665 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/test-artifacts.tar.gz", + "status": "added", + "sha": "692f10a8452e12ef0060177a89648ba0e247e9fc", + "additions": 0, + "deletions": 0, + "changes": 0 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/test_kinematics_validity.py", + "status": "added", + "sha": "7cf66857bcbeb9b72851ad53ce7c08f97d528fc8", + "additions": 202, + "deletions": 0, + "changes": 202 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/README.md", + "status": "added", + "sha": "5e3b6e546922665e6639b3a4f49c837983fc56f5", + "additions": 43, + "deletions": 0, + "changes": 43 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/junit.xml", + "status": "added", + "sha": "e574c6fab6ed3890ac856040421e2a576f385607", + "additions": 1, + "deletions": 0, + "changes": 1 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/manifest.json", + "status": "added", + "sha": "741306eabe2798bdc0927e34773cf9f7478b312a", + "additions": 51, + "deletions": 0, + "changes": 51 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/process.log", + "status": "added", + "sha": "7e1ead8287c87a8d972a2cf50390981926c5dd1a", + "additions": 12, + "deletions": 0, + "changes": 12 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/receipt.json", + "status": "added", + "sha": "75d0d3aee60e47679da6672ee3e9c8ec07b16d8f", + "additions": 300, + "deletions": 0, + "changes": 300 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/receive-current-seam.cjs", + "status": "added", + "sha": "cdc7717acd47e6776ca9c1afc100e429cc6e5ea9", + "additions": 16, + "deletions": 0, + "changes": 16 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/source-manifest.json", + "status": "added", + "sha": "6cb4dfce021abbeaff5e7e1b36f10c5822c9cdb6", + "additions": 818, + "deletions": 0, + "changes": 818 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/test-artifact-manifest.json", + "status": "added", + "sha": "4747226f7cb788048bdf0593ad3f82911da0b4eb", + "additions": 130, + "deletions": 0, + "changes": 130 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/test-artifacts.tar.gz", + "status": "added", + "sha": "30a23f4ce7066ac1db085ea21179b763f3ad0829", + "additions": 0, + "deletions": 0, + "changes": 0 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/README.md", + "status": "added", + "sha": "355804bd71cd836250a57126b3fee28a47f233be", + "additions": 13, + "deletions": 0, + "changes": 13 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/independent-cli-artifacts.tar.gz", + "status": "added", + "sha": "739fc581cae5561014b45049f225a2d4abdc2a6f", + "additions": 0, + "deletions": 0, + "changes": 0 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/manifest.json", + "status": "added", + "sha": "b58ee77faebd30f53581475d4f4a931cf54c64e6", + "additions": 30, + "deletions": 0, + "changes": 30 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/receiving.json", + "status": "added", + "sha": "4e63e2efd9e71728329abf66fe283597ee8ee815", + "additions": 59, + "deletions": 0, + "changes": 59 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/source-review.json", + "status": "added", + "sha": "bbfb3c062188f4287388741cfd526d07249f5177", + "additions": 26, + "deletions": 0, + "changes": 26 + }, + { + "filename": "libs/python/capture_analysis/capture_analysis/kinematics/compute.py", + "status": "modified", + "sha": "fb8be59b00e15d9c264aad0983cf75a757c9e210", + "additions": 53, + "deletions": 43, + "changes": 96 + }, + { + "filename": "tests/analysis/test_kinematics_validity.py", + "status": "added", + "sha": "7cf66857bcbeb9b72851ad53ce7c08f97d528fc8", + "additions": 202, + "deletions": 0, + "changes": 202 + } + ], + "decision": "Retain the qualified actual 3e3 parent. This later merge changes only the kinematics compute implementation, its tests/design/evidence and shared progress. The accepted 24-check native journey exercised numeric features; no desktop/history/scope or numeric-feature source changed. These receipts do not claim complete d43 acceptance." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/native.stderr.log b/docs/evidence/analysis-history-401c5d17da79/current-scope/native.stderr.log new file mode 100644 index 00000000..90774a0e --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/native.stderr.log @@ -0,0 +1,5 @@ +This plugin does not support propagateSizeHints() +This plugin does not support propagateSizeHints() +This plugin does not support propagateSizeHints() +This plugin does not support propagateSizeHints() +This plugin does not support propagateSizeHints() diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/nonaccepting-continuation/check_scope_history.py b/docs/evidence/analysis-history-401c5d17da79/current-scope/nonaccepting-continuation/check_scope_history.py new file mode 100644 index 00000000..944472f0 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/nonaccepting-continuation/check_scope_history.py @@ -0,0 +1,251 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""One real native scope/history journey on the received current source.""" +from pathlib import Path +import argparse +import hashlib +import importlib.util +import json +import os +import sys +import time +import traceback + + +def hashes(root, raw_only=False): + return {p.relative_to(root).as_posix(): hashlib.sha256(p.read_bytes()).hexdigest() + for p in sorted(root.rglob("*")) if p.is_file() + and (not raw_only or "processing" not in p.relative_to(root).parts)} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--source", type=Path, required=True) + parser.add_argument("--inputs", type=Path, required=True) + parser.add_argument("--output", type=Path, required=True) + args = parser.parse_args() + source, output = args.source.resolve(), args.output.resolve() + assert source != output and source not in output.parents and not output.exists() + inputs = json.loads(args.inputs.read_bytes()) + expected = {row["path"]: row["sha256"] for row in inputs["files"]} + assert hashes(source) == expected + output.mkdir(parents=True) + for key, name in [("LOCALAPPDATA", "local"), ("APPDATA", "roaming"), + ("XDG_CONFIG_HOME", "config"), ("XDG_DATA_HOME", "data"), + ("XDG_CACHE_HOME", "cache"), ("MPLCONFIGDIR", "mpl"), + ("TMPDIR", "tmp"), ("XDG_RUNTIME_DIR", "runtime")]: + directory = output / "state" / name + directory.mkdir(parents=True, mode=0o700) + os.environ[key] = str(directory) + os.environ["QT_QPA_PLATFORM"] = "offscreen" + sys.dont_write_bytecode = True + for rel in reversed(["desktop", "libs/python/capture_analysis", "libs/python/capture_session", + "libs/python/capture_protocol", "libs/python/capture_protocol/capture_protocol/generated", + "libs/python/capture_worker"]): + sys.path.insert(0, str(source / rel)) + report = {"canonical_parent": inputs["canonical_parent"], "runtime_tree": inputs["composition_tree"], + "screen_git_blob": inputs["composed_screen_git_blob"], "checks": [], "errors": [], + "method": "QApplication.exec/QTimer; actual SessionHeader and AnalysisScreen, two real QThread/MCAP feature jobs", + "method_sha256": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), + "source_inputs_sha256": hashlib.sha256(args.inputs.read_bytes()).hexdigest(), + "scope": "One changed scope/history boundary. No Windows MainWindow, full-suite, nested-image repair or installed-release claim."} + + def check(name, condition, *, fatal=True): + report["checks"].append({"name": name, "passed": bool(condition)}) + if fatal: + assert condition, name + + try: + import PySide6 + from PySide6.QtCore import QCoreApplication, QEvent, QTimer, Qt + from PySide6.QtTest import QTest + from PySide6.QtWidgets import QApplication, QMessageBox, QPlainTextEdit, QVBoxLayout, QWidget + from capture_desktop import theme + from capture_desktop.screen_analysis import AnalysisScreen + from capture_desktop.state import CaptureState + from capture_desktop.widgets_session_header import SessionHeader + helper_path = source / "tests/analysis/test_numeric_batch_pipeline.py" + spec = importlib.util.spec_from_file_location("current_numeric_fixture", helper_path) + fixture = importlib.util.module_from_spec(spec) + spec.loader.exec_module(fixture) + + def package(name): + root = output / (name + ".mmsession") + root.mkdir() + (root / "manifest.json").write_text(json.dumps({"sessionId": name, "state": "sealed"}) + "\n") + stream = root / "sources/lsl/streams/numeric" + stream.mkdir(parents=True) + fixture._write_mcap(stream / "segments/000000.mcap", [(1_000_000_000, fixture._batch())]) + (stream / "stream.json").write_text(json.dumps({"sourceId": "lsl", "streamId": "numeric.stream", "modality": "eeg", "dataSchemaId": "generic.numeric_batch/1", "nominalRateHz": 2.0, "units": "V", "dimensions": [2]}) + "\n") + return root + + first, second = package("scope history A"), package("scope history B") + raw_before = {str(p): hashes(p, raw_only=True) for p in [first, second]} + app = QApplication([]) + theme.apply_theme(app, setting="dark") + shell = QWidget() + layout = QVBoxLayout(shell) + header, screen = SessionHeader(), AnalysisScreen(CaptureState()) + layout.addWidget(header) + layout.addWidget(screen, 1) + header.scope_changed.connect(screen.set_scope) + + def package_loaded(summary): + if summary is None: + header.clear() + else: + header.refresh_sealed(summary, selection=screen.scope) + + screen.package_loaded.connect(package_loaded) + shell.resize(1280, 1050) + shell.show() + picker = header._scope_picker + state = {"phase": "start", "deadline": time.monotonic() + 50, "dialogs": [], "cancelled": False} + ranges = [(1_500_000_001, 2_500_000_001), (1_000_000_001, 2_000_000_001)] + + def choose(bounds): + picker._mode.setCurrentIndex(picker._mode.findData("range")) + picker._start.setText(f"{bounds[0] // 10**9}.{bounds[0] % 10**9:09d}") + picker._end.setText(f"{bounds[1] // 10**9}.{bounds[1] % 10**9:09d}") + + def jobs(root): + directory = root / "processing/jobs" + return set(directory.iterdir()) if directory.exists() else set() + + def assert_job(job, bounds): + params = json.loads((job / "params.json").read_bytes()) + manifest = json.loads((job / "job_manifest.json").read_bytes()) + check("real saved job retains its exact selected nanosecond parameters", + (params["startSessionNs"], params["endSessionNs"]) == bounds and params["checkpointSection"] is None) + check("completed current numeric job reports that selected interval", + (manifest["timeRange"]["startSessionNs"], manifest["timeRange"]["endSessionNs"]) == bounds + and manifest["status"] in {"completed", "completed_with_warnings"}) + return params, manifest + + def finish(): + timer.stop() + shell.close() + app.quit() + + def tick(): + try: + modal = QApplication.activeModalWidget() + if isinstance(modal, QMessageBox): + state["dialogs"].append(modal.text()) + modal.accept() + if state["cancelled"]: + if screen._thread is None: + finish() + return + if time.monotonic() > state["deadline"]: + raise TimeoutError("The bounded native scope/history journey did not finish.") + phase = state["phase"] + if phase == "start": + screen.set_package(str(first) + "/.") + check("screen, header and history use one normalized package identity", + screen.package_path == header.package_path == screen._history.package == str(first)) + screen._command.setCurrentIndex(screen._command.findData("features")) + choose(ranges[0]) + check("real header selection enables the composed Analysis screen with exact bounds", + screen._btn_run.isEnabled() and screen.scope is picker.selection + and (screen.scope.start_ns, screen.scope.end_ns) == ranges[0]) + QTest.mouseClick(screen._btn_run, Qt.MouseButton.LeftButton) + check("real feature worker disables saved-history actions while running", + screen._thread is not None and not screen._history._open.isEnabled() + and not screen._history._refresh.isEnabled(), fatal=False) + report["initial_busy_state"] = {"thread_retained": screen._thread is not None, "thread_running": screen._thread.isRunning() if screen._thread is not None else False, "history_refresh_enabled": screen._history._refresh.isEnabled(), "history_open_enabled": screen._history._open.isEnabled()} + state["phase"] = "first-job" + elif phase == "first-job" and screen._thread is None: + check("the first real worker completes without a modal failure", not state["dialogs"]) + check("completed scoped job reaches the saved-history viewer", + len(jobs(first)) == 1 and bool(screen._last_job_dir) + and screen._history.loaded_job_id == Path(screen._last_job_dir).name) + job = Path(screen._last_job_dir) + assert_job(job, ranges[0]) + state["first_job"] = job + state["saved_bytes"] = hashes(job) + choose(ranges[1]) + selected = screen.scope + QTest.mouseClick(screen._history._refresh, Qt.MouseButton.LeftButton) + QTest.mouseClick(screen._history._open, Qt.MouseButton.LeftButton) + check("explicitly reopening the old job preserves the next selected scope", + screen.scope == picker.selection == selected + and (selected.start_ns, selected.end_ns) == ranges[1]) + check("reopen is read-only and starts no additional worker", + hashes(job) == state["saved_bytes"] and jobs(first) == {job} + and screen._thread is None) + QTest.mouseClick(screen._history._details, Qt.MouseButton.LeftButton) + dialog = screen._history._dialog + params_editor = dialog.findChild(QPlainTextEdit, "analysisHistoryParameters") + saved_params = json.loads(params_editor.toPlainText()) + check("native read-only details show the saved scope, distinct from the next selection", + params_editor.isReadOnly() + and (saved_params["startSessionNs"], saved_params["endSessionNs"]) == ranges[0] + and screen.scope == selected) + dialog.close() + screen.set_package(str(first) + "/.") + check("same-package refresh preserves both scope and loaded saved result", + screen.scope == picker.selection == selected + and screen._history.loaded_job_id == job.name) + state["phase"] = "capture-and-second-job" + elif phase == "capture-and-second-job": + check("combined native frame is captured", shell.grab().save(str(output / "scope-history-reopened.png"))) + state["jobs_before_second"] = jobs(first) + QTest.mouseClick(screen._btn_run, Qt.MouseButton.LeftButton) + check("a second real worker starts from the next selection", screen._thread is not None) + # The current application may change package context while a + # worker is pending. Its real queued completion must stay A. + screen.set_package(str(second)) + check("changing package resets scope and clears history as one transition", + screen.package_path == header.package_path == screen._history.package == str(second) + and screen.scope.mode == picker.selection.mode == "full" + and not screen._last_job_dir and not screen._history.loaded_job_id) + state["phase"] = "second-job" + elif phase == "second-job" and screen._thread is None: + completed = jobs(first) - state["jobs_before_second"] + check("late real completion is retained under its originating package only", + len(completed) == 1 and not jobs(second) and not state["dialogs"]) + second_job = next(iter(completed)) + assert_job(second_job, ranges[1]) + check("late foreign completion cannot repaint current history or scope", + screen.package_path == str(second) and screen.scope.mode == picker.selection.mode == "full" + and not screen._last_job_dir and not screen._history.loaded_job_id + and "Result saved for the previous package" in screen._log.toPlainText()) + check("the prior reopened job remains byte-identical after the second job", + hashes(state["first_job"]) == state["saved_bytes"]) + check("both real package raw inputs remain byte-identical", + all(hashes(p, raw_only=True) == raw_before[str(p)] for p in [first, second])) + report["real_jobs"] = [str(state["first_job"]), str(second_job)] + report["raw_package_hashes"] = raw_before + report["last_native_log"] = screen._log.toPlainText() + report["dialogs"] = state["dialogs"] + finish() + except BaseException: + report["errors"].append(traceback.format_exc()) + state["cancelled"] = True + if screen._thread is not None: + screen._cancel_job() + else: + finish() + + timer = QTimer() + timer.timeout.connect(tick) + timer.start(15) + report["event_loop_exit"] = app.exec() + shell.deleteLater() + QCoreApplication.sendPostedEvents(None, QEvent.Type.DeferredDelete) + app.processEvents() + report["pyside6"] = PySide6.__version__ + report["python"] = sys.version + except BaseException: + report["errors"].append(traceback.format_exc()) + report["source_unchanged"] = hashes(source) == expected + report["passed"] = sum(row["passed"] for row in report["checks"]) + report["failed"] = sum(not row["passed"] for row in report["checks"]) + report["exit_code"] = 0 if not report["errors"] and not report["failed"] and report["source_unchanged"] else 1 + (output / "receipt.json").write_text(json.dumps(report, indent=2) + "\n") + print(json.dumps({k: report[k] for k in ["passed", "failed", "source_unchanged", "exit_code"]})) + return report["exit_code"] + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/nonaccepting-continuation/receipt-state.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/nonaccepting-continuation/receipt-state.json new file mode 100644 index 00000000..022d1eef --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/nonaccepting-continuation/receipt-state.json @@ -0,0 +1,10 @@ +{ + "method_sha256": "1f7029cb84c999feed1b5b636d65551a75938f5875d09bbff20065aa9d1cc0b2", + "source_blob": "ee2db9acacdc92d3aa8ba0bfe12f638e9418f9b4", + "runtime_tree": "07d78241dca691015bb3e4d8d260b109672b7de0", + "classification": "Non-accepting artifact-capture continuation; no complete native outcome claimed", + "reason": "ENOSPC while writing frame/receipt and supervisor artifacts", + "receipt_bytes": 0, + "receipt_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "preservation": "Original private source, method, partial native fixture and zero-byte receipt were retained without deletion or truncation. The final qualified method emits a complete report and PNG through stdout." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/process.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/process.json new file mode 100644 index 00000000..7ecceded --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/process.json @@ -0,0 +1,19 @@ +{ + "command": [ + "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "-B", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/check_scope_history_qualified.py", + "--source", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/receiving-source-candidate", + "--inputs", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/candidate-source-inputs.json", + "--output", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified" + ], + "exit_code": 0, + "seconds": 3.534, + "free_before": 11571200, + "free_after": 13574144, + "stdout_sha256": "aab4b265957f5404474d87c430bb03167b3514fb8fb05399e23cf5534f4b9c70", + "stderr_sha256": "bcd516d5e9014bd0f43bf526bc701b744bbd4ea9c35d16fdd65e6fde7b0270d5" +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/receipt.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/receipt.json new file mode 100644 index 00000000..a21d97a4 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/receipt.json @@ -0,0 +1,380 @@ +{ + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "runtime_tree": "167bbac3bba862cc1532d954fe2d503e561a00df", + "screen_git_blob": "6893f119593f8ff6551167efcb1939d014a081e6", + "checks": [ + { + "name": "screen, header and history use one normalized package identity", + "passed": true + }, + { + "name": "real header selection enables the composed Analysis screen with exact bounds", + "passed": true + }, + { + "name": "real feature worker disables saved-history actions while running", + "passed": true + }, + { + "name": "the first real worker completes without a modal failure", + "passed": true + }, + { + "name": "settled first job restores native Run and history controls", + "passed": true + }, + { + "name": "completed scoped job reaches the saved-history viewer", + "passed": true + }, + { + "name": "real saved job retains its exact selected nanosecond parameters", + "passed": true + }, + { + "name": "completed current numeric job reports that selected interval", + "passed": true + }, + { + "name": "successful saved job contains only the two expected fixture metadata warnings", + "passed": true + }, + { + "name": "explicitly reopening the old job preserves the next selected scope", + "passed": true + }, + { + "name": "reopen is read-only and starts no additional worker", + "passed": true + }, + { + "name": "native read-only details show the saved scope, distinct from the next selection", + "passed": true + }, + { + "name": "same-package refresh preserves both scope and loaded saved result", + "passed": true + }, + { + "name": "combined native frame is captured", + "passed": true + }, + { + "name": "a second real worker starts from the next selection", + "passed": true + }, + { + "name": "changing package resets scope and clears history as one transition", + "passed": true + }, + { + "name": "late real completion is retained under its originating package only", + "passed": true + }, + { + "name": "real saved job retains its exact selected nanosecond parameters", + "passed": true + }, + { + "name": "completed current numeric job reports that selected interval", + "passed": true + }, + { + "name": "successful saved job contains only the two expected fixture metadata warnings", + "passed": true + }, + { + "name": "late foreign completion cannot repaint current history or scope", + "passed": true + }, + { + "name": "late-job settlement restores controls for the current package only", + "passed": true + }, + { + "name": "the prior reopened job remains byte-identical after the second job", + "passed": true + }, + { + "name": "both real package raw inputs remain byte-identical", + "passed": true + } + ], + "errors": [], + "method": "QApplication.exec/QTimer; actual SessionHeader and AnalysisScreen, two real QThread/MCAP feature jobs", + "method_sha256": "c45eb2b2b02b8c9423565d811ae7782eff576b1313bf5cef366c4af8bf4e3802", + "source_inputs_sha256": "7e2d4d219c8a4b70865f780750fa8fe5362da54a43898097082a44784f807438", + "scope": "One changed scope/history boundary. No Windows MainWindow, full-suite, nested-image repair or installed-release claim.", + "initial_busy_state": { + "thread_retained": true, + "thread_running": true, + "history_refresh_enabled": false, + "history_open_enabled": false + }, + "saved_job_manifests": [ + { + "analysisGrids": [], + "captureAnalysisVersion": "0.1.0", + "createdUtc": "2026-10-08T14:16:48Z", + "errors": [], + "evalWindowCount": null, + "featureTables": [ + { + "featureSchemaVersion": 1, + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.parquet", + "rows": 1 + } + ], + "gapPolicy": "mask", + "gapSummary": { + "closed": 0, + "maskedNs": 0, + "open": 0, + "validFraction": null + }, + "jobId": "20261008T141648Z_3bcabb8c", + "kinematicsRows": null, + "manifestSha256": "53cfd49d90b9467e45769ff379fe20457e738e27dbff76ce64e4845d4e0a7028", + "mlBundleWindowCount": null, + "modalities": [ + "eeg" + ], + "outputs": [ + { + "bytes": 257, + "kind": "params", + "relativePath": "params.json", + "sha256": "6fbf697209770acc7d5e1690e95bd7869ba803a809c593f0e5b011508f6c5798" + }, + { + "bytes": 1141, + "kind": "qc_json", + "relativePath": "reports/qc.json", + "sha256": "fd46c1fdbb332dfb11d3b3362d51c25d57f8c2a79396d5bdfca537a6705dbd5b" + }, + { + "bytes": 2220, + "kind": "qc_html", + "relativePath": "reports/qc.html", + "sha256": "e7a1d98a2ce429128b11125b062c70f968f2bffd9198d326563457e5573de10d" + }, + { + "bytes": 5266, + "kind": "feature_parquet", + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.parquet", + "sha256": "03cfd112d75b61015ea9e109359f349857d5a9f7fbcd04718ab425ae8945da92" + }, + { + "bytes": 156, + "kind": "feature_csv", + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.csv", + "sha256": "b82f0241cf32d20ee1809d8a67e406b6074dd0fe1197316c900c1bf8cc236191" + }, + { + "bytes": 2691, + "kind": "feature_schema", + "relativePath": "features/_schema.json", + "sha256": "5d389cc9b624d1d818c6739554fcaf5d881ad4cffb0d31d74486fa644a969e85" + }, + { + "bytes": 3279, + "kind": "manifest", + "relativePath": "job_manifest.json", + "sha256": "305136787550fa5ef4df95ee41187dea93f414ad39d7eaa8c551f7a9666f73c4" + } + ], + "packagePath": "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified/scope history A.mmsession", + "packageState": "sealed", + "paramsDigest": "3bcabb8cfbc12d0ec01c35b20c8d098b0559e7161440de5406af9e5cf4775f33", + "pluginIds": [ + "emg.envelope.v1", + "imu.kinematics.v1", + "radar.rd_energy.v1", + "radar_doppler.mag.v1", + "video.timing_qc.v1", + "numeric.basic.v1", + "test.dummy.feature.v1" + ], + "pluginManifestVersion": "1.0.0", + "poseJobId": null, + "poseModelId": null, + "poseTables": [], + "schemaId": "capture.analysis_job/1", + "sessionId": "scope history A", + "sourcesSelected": [ + "lsl" + ], + "status": "completed_with_warnings", + "syncAnchorsApplied": { + "anchors": [], + "applied": false + }, + "timeRange": { + "checkpointIds": [], + "endSessionNs": 2500000001, + "mode": "custom", + "startSessionNs": 1500000001 + }, + "tooling": { + "captureAnalysis": "0.1.0", + "matplotlib": "3.11.2", + "numpy": "2.5.3", + "pandas": "3.0.6", + "platform": "Linux-6.18.44-x86_64-with-glibc2.39", + "python": "3.12.14", + "scipy": "1.18.1" + }, + "warnings": [ + "package state is 'sealed' (prefer finalized)", + "package duration_ns is unknown/zero — analysis uses an open time window (integrity entries lack endSessionTimeNs)" + ] + }, + { + "analysisGrids": [], + "captureAnalysisVersion": "0.1.0", + "createdUtc": "2026-10-08T14:16:48Z", + "errors": [], + "evalWindowCount": null, + "featureTables": [ + { + "featureSchemaVersion": 1, + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.parquet", + "rows": 1 + } + ], + "gapPolicy": "mask", + "gapSummary": { + "closed": 0, + "maskedNs": 0, + "open": 0, + "validFraction": null + }, + "jobId": "20261008T141648Z_b793f3b4", + "kinematicsRows": null, + "manifestSha256": "53cfd49d90b9467e45769ff379fe20457e738e27dbff76ce64e4845d4e0a7028", + "mlBundleWindowCount": null, + "modalities": [ + "eeg" + ], + "outputs": [ + { + "bytes": 257, + "kind": "params", + "relativePath": "params.json", + "sha256": "efa12cb2a20649da7c1f3f823a265ee25b31540d28feeee0b47125b944e3d7e4" + }, + { + "bytes": 1141, + "kind": "qc_json", + "relativePath": "reports/qc.json", + "sha256": "fd46c1fdbb332dfb11d3b3362d51c25d57f8c2a79396d5bdfca537a6705dbd5b" + }, + { + "bytes": 2220, + "kind": "qc_html", + "relativePath": "reports/qc.html", + "sha256": "e7a1d98a2ce429128b11125b062c70f968f2bffd9198d326563457e5573de10d" + }, + { + "bytes": 5266, + "kind": "feature_parquet", + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.parquet", + "sha256": "858438d0c22ee6ecb5e304d22c7ad80579ecbe2178ebf5f8cd169494ae249b0d" + }, + { + "bytes": 156, + "kind": "feature_csv", + "relativePath": "features/numeric/source-6c736c/stream-6e756d657269632e73747265616d/windows.csv", + "sha256": "786ee658a04e19c111cc65914e64dbbff86c063dfe897b67e9a5290188af874e" + }, + { + "bytes": 2691, + "kind": "feature_schema", + "relativePath": "features/_schema.json", + "sha256": "5d389cc9b624d1d818c6739554fcaf5d881ad4cffb0d31d74486fa644a969e85" + }, + { + "bytes": 3279, + "kind": "manifest", + "relativePath": "job_manifest.json", + "sha256": "dd592f615b84e455c6dc18dd7385b05f45c5e9b195c0b33236062e3870f5e8af" + } + ], + "packagePath": "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified/scope history A.mmsession", + "packageState": "sealed", + "paramsDigest": "b793f3b4690f50a5651d48f7479d01d0c846391249aecbf2afb7a44d96a05fc7", + "pluginIds": [ + "emg.envelope.v1", + "imu.kinematics.v1", + "radar.rd_energy.v1", + "radar_doppler.mag.v1", + "video.timing_qc.v1", + "numeric.basic.v1", + "test.dummy.feature.v1" + ], + "pluginManifestVersion": "1.0.0", + "poseJobId": null, + "poseModelId": null, + "poseTables": [], + "schemaId": "capture.analysis_job/1", + "sessionId": "scope history A", + "sourcesSelected": [ + "lsl" + ], + "status": "completed_with_warnings", + "syncAnchorsApplied": { + "anchors": [], + "applied": false + }, + "timeRange": { + "checkpointIds": [], + "endSessionNs": 2000000001, + "mode": "custom", + "startSessionNs": 1000000001 + }, + "tooling": { + "captureAnalysis": "0.1.0", + "matplotlib": "3.11.2", + "numpy": "2.5.3", + "pandas": "3.0.6", + "platform": "Linux-6.18.44-x86_64-with-glibc2.39", + "python": "3.12.14", + "scipy": "1.18.1" + }, + "warnings": [ + "package state is 'sealed' (prefer finalized)", + "package duration_ns is unknown/zero — analysis uses an open time window (integrity entries lack endSessionTimeNs)" + ] + } + ], + "native_frame": { + "filename": "scope-history-reopened.png", + "bytes": 193004, + "sha256": "c8ec0afb810a76da3254e035cdac3a5e0ec46097976743e1917e672441a550f5" + }, + "real_jobs": [ + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified/scope history A.mmsession/processing/jobs/20261008T141648Z_3bcabb8c", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified/scope history A.mmsession/processing/jobs/20261008T141648Z_b793f3b4" + ], + "raw_package_hashes": { + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified/scope history A.mmsession": { + "manifest.json": "53cfd49d90b9467e45769ff379fe20457e738e27dbff76ce64e4845d4e0a7028", + "sources/lsl/streams/numeric/segments/000000.mcap": "f3df8e3cc95f76462c502935aad5abafd4392ed3224c239775650c5b49bcd18f", + "sources/lsl/streams/numeric/stream.json": "1adfb22cb81843c0e5bef319c9c2268ea2746e930232f6d89e154d133e0fa885" + }, + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified/scope history B.mmsession": { + "manifest.json": "bb31522d57c0572ddf144fdebb5037fa4dc51940cbe52034bbfd64911f9cdc3b", + "sources/lsl/streams/numeric/segments/000000.mcap": "f3df8e3cc95f76462c502935aad5abafd4392ed3224c239775650c5b49bcd18f", + "sources/lsl/streams/numeric/stream.json": "1adfb22cb81843c0e5bef319c9c2268ea2746e930232f6d89e154d133e0fa885" + } + }, + "last_native_log": "Starting features on /dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified/scope history A.mmsession\nscope=1.000000001–2.000000001 s\nstart (0%)\nqc (15%)\nwrite_qc (25%)\nfeatures_plots (45%)\nmanifest (90%)\ndone (100%)\nDone status=completed_with_warnings job_id=20261008T141648Z_b793f3b4\ndir=/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-qualified/scope history A.mmsession/processing/jobs/20261008T141648Z_b793f3b4\nResult saved for the previous package; select that package to inspect it.", + "dialogs": [], + "event_loop_exit": 0, + "pyside6": "6.11.2", + "python": "3.12.14 (main, Aug 25 2026, 14:00:49) [Clang 22.1.3 ]", + "source_unchanged": true, + "passed": 24, + "failed": 0, + "exit_code": 0 +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/receiving.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/receiving.json new file mode 100644 index 00000000..4af1b82d --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/receiving.json @@ -0,0 +1,37 @@ +{ + "schema": "hamon.current-scope-history-receiving.v1", + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "runtime_tree": "167bbac3bba862cc1532d954fe2d503e561a00df", + "screen_git_blob": "6893f119593f8ff6551167efcb1939d014a081e6", + "screen_sha256": "1475764b8453ed870174fcaf98bc02370db76b5001c4175feb93263ad33d5b70", + "receiver_sha256": "c45eb2b2b02b8c9423565d811ae7782eff576b1313bf5cef366c4af8bf4e3802", + "process_exit_code": 0, + "seconds": 3.534, + "checks_passed": 24, + "checks_failed": 0, + "source_files": 142, + "source_bytes_unchanged": true, + "raw_package_bytes_unchanged": true, + "frame_sha256": "c8ec0afb810a76da3254e035cdac3a5e0ec46097976743e1917e672441a550f5", + "visual_review": "The current native scope picker and saved-history row are legible together. The very long private package path wraps and clips in the existing narrow left control column; this is not a complete layout or Windows MainWindow acceptance.", + "startup_control": { + "source_blob": "ee2db9acacdc92d3aa8ba0bfe12f638e9418f9b4", + "runtime_tree": "07d78241dca691015bb3e4d8d260b109672b7de0", + "method_sha256": "44c24508e4e4aa9d14d1771be486bb953f8b3719652183c2e9d7c3bb81ac2b17", + "passed_before_stop": 2, + "failed": 1, + "receipt": "startup-negative/receipt.json" + }, + "receiver_adjustments": [ + "Accept the existing completed_with_warnings status only with both exact expected fixture metadata warnings and exact saved range.", + "Explicitly verify Run/history controls restore after each completed worker.", + "Emit complete receipt and native PNG in stdout so artifact transport is independent of the native journey." + ], + "nonaccepting_continuation": { + "method_sha256": "1f7029cb84c999feed1b5b636d65551a75938f5875d09bbff20065aa9d1cc0b2", + "cause": "ENOSPC while writing frame/receipt and supervisor artifacts", + "receipt_bytes": 0, + "native_outcome": "not accepted; no complete result claimed" + }, + "qualification_limits": "Original 14 tests / 19 checks remain on 37443 and 72c15; QC/2 remains e43; current numeric nested-gallery limitation remains separate. No full Windows, MainWindow, daemon, hardware or installed-release acceptance." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/scope-history-reopened.png b/docs/evidence/analysis-history-401c5d17da79/current-scope/scope-history-reopened.png new file mode 100644 index 0000000000000000000000000000000000000000..35b7f4984412c703d15bf177de8eacb1cfb181be GIT binary patch literal 193004 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

=`8yhom}R@~^+DzBfyC zY^F^QFH`p>h?Cu7fbg1EgK9z`C`t9F%g-vTn3jvbV4Et0)rrm5&H zr{Vj3te~BHPK=ZsJJ+219;Tzm^-R2*^s|()i(nCfS6tO1_a%<_P=3}eO+M?^RQ6mu zMmhe!^CexQ(cE*Vm;1v@t7L491&HoJ9^YOrm0V393>Rn82eR61@k&82f11x_*-Wt-ukAEgtAVWQnyf~{xpfsrDym;)1qn4aUZEKkjuJK!~vQCfdvqI zL$+=8w_{)2J;zLUhu$YnjFA^DX5fMzH=H+k=XvQy2 z5EA2`1~#bMcO7lGV|>9T|;^i&o<+-g_3=)VO_S)mFIqU|8*nPMF`s-wEUp;{(kyIDY>u}6u?GbV9?rb|* z$Z_k#>Gds?yX*Xs@W_a+%{+VSQJYC_lH^%YD5YdwKG%zp*~kacD!s~<*GAVU&Xyys zi9@6B_{|4?JRFD~GpL5{(>hq98`7OAG%EYl0F?jL83bc{`W(X(xC(Ic8)s$*LrYj( z#q-r>Y8+GO8*AKi^VU`~07z)%zds_yvypH#_xR5oUFo%W>*Lkyy8piI=#Hg4c|P@7 z!2G+q=ckWGPFj8R&OH&Vu)X>)c$8-LBaw$lYn#W!v-iHk0p%r|W_i|_cO_2-WO&N6 z8!eOj5Ob|qAMG0!U?U?Q2hnn4LFBLD5-#1D&{K_j7}{cJIl^ z|Co0@+WO(N@_?Zt4(sK!Ls+`_KSj3j?|5gd> zwwU+ZpCuJ`I$0*~2g32$eIHJ9bmfw^pYgwMAKurqi_MPkZr6D0wxj+`9oLu2xtNmw zNoK?0s8yHh;kIKH_=hc|n3*l`ZFr%3NeGZ@Ak50eEs{a`d?Rf+{gs;I8=4 z@nGDC76C|bFEGb#3~`%Z%ataTWsspEO?%tsNxa<(%3`pUk&NSOwT>U69D>eExw%n; z&I2Q)b3)?4gahuwthuzj_y=ne`Anrp0`03ke`56hODP#ZfxhCUEuqiP~H9a(mkbu4VdTh3Z zwS|q~Kz#7!Oib0K5P3CK!ZF@YL*P=Q1%6g(Ej2YQd8h>GLpXl}=JY%n{#LqK>%p0} z-1~IcA8IQ4Yn`CN-&Wvvn0<-e0zz<|)Mg=|xc67^q-h$01Zj1NZ3pwEZ_UWukd%Ub zjXb1oa`OBdh@886zE8PO9lj>L%^zAzL#qZFkTun8LMGHGIT9mcK-RUi(!z-GtrK@q z24uKkYf+SmH?ve8Q26^K8ib^m({w;A?I*RFcqjv)k7dQ>-@>w1nvvBgl7fmG$RB+3 zA{+4;fXvcqa^UNIOp5$QYn)o;Wos?_GUs`(Sa$PuA`uOd(_%cL%bju0>fEF(16)+} z#RXD$BV|cfB*O=AU$cIb*B6qoyZo`jo)>k|@G-Yjd23i^h@7Yvl6-3`n}PtU?)$&y z!#8XXOS z9IfncEf5<7Zd>}FM+^S3pzr)-Z!wc z%ahz}y3{dT#(^`${Au^35f)=kaneq})6=td7l+zEV=g-KU0vJSSnk`#(IpKTG|+p- zcQ^lm7{!f?K?-E*C37n9$O(0UB*du~-PN(=_v4{n|GxFue_4SEUFapenvQ{5kzAmZ z=Gt$l+z}VYMo<{%K}ieO?fzLQmo#_g$#`}WzsUaZfOF(xsJ&&5M6!r3rYEhXchGAF z)~f}X`sf9z>GL|&PMDi;pzR5VO%hI~zq!6v`)k_oiS+BcD*=}pX3FApLz~MbH^9S8 z(NWI4Jh?pni>jftH|%pj4fCfOU|Z&2gGBVtutWb0i`8@SeNw>-nPlvPrkJR6-`lQ= zO0DX;>+M8{o=~?;+-8jQE4i-rgitP_hM_N0g9bHOR@I}w1#KL*^?$hlVCk4%LcpJy z`0sUBr*>0HP#6J*v#qyHikPf;76XFj-dCIZg_ISYx}5SZ^LLPK2jzyuM*&?n!}OOQ z(+`(~j+GgWmxHaXdjlg&%}3ZsWUWxC-cO1>858q8I?+FDupc`>2vEH(VJ89~JO#+^fHk z7H2x-o&FY>gy+Tic06zm`n&6 zs)cZ^x_5%(g)!4V!o<)2y;970X?(l+>cl>^2*{hC1?v?(#%kB9NFaJf6C0+xkyW&w z=P0-HAL);G^JZ+Av6_J*4jU*D8!@Sdi`n>nqfexeZ60q_Jjo3&&&?Bh+}?F%y(G*2 zyv7RX(qn2z`#mHkzv0^#OZq*m%_S3gm`@Jf|?)2o6o*O)FY&$mk z*a#=6?f#`3cen=}P_Ar$m<7F}3A4@IeRh$`&F0E7@kNwGH3}sHPRoWd~+|>ccJa#w1 zeM>iI+*ptll50ILX2mi)e7;8)r%+YYs!Po-*S7MlrHup}4n;hwzL&k`bUkg1Lw}f- zKKHL|ln~VCX9X?Gf3hn=ct&wz3vBNEi)Nlk&?K0Kf|&kwW3=D@!_APF!?Cd)ds)Cw zIK9r^i!IqPo}Z;?Y#SZlnI+Ez_$hj)1efC+Zze*#l%NIS2*EW|_&Zj=78;YcB);P4 z)8@lR?hGQ(M=Hm4b#Ud1vu|^ud35P4j-F076ZDvsJ=)aFv-I3dz9izK#!-qaGr3A^ zIh>>*LgWjWOg-}tt~YO9;Svh1hIw;@^Mb|)hz$~s*?7OY|48J*Nt!$i51ZbqVTIG^ znBg_Fe(W07?ncDup~>&-lBEe}eiI8CfV(di4;4g!nf7UM>q~jz>y5o|t=Ue%8aRu! zkE~hbOBpS(2Q4FoK@I3}MGTvd6-z+_Nq^^z#nrtmYJ9mtn! z?lQ-E6}#JaGH`_1AGVba6 zyDV$)=kYAuPm`UwiYH7k@raoCWMb<*n0y#b8awv)Bv(A`CqX4wOE(?U2C-?H?^Anm zLWeKt=Yaptz4QFK+v^MY4vPzD0c$?8R`>DlFHFq)L2)9i364%h!QGp=?0ur%>)rOl zujd?$RQU|DEiYzGM8V&>)tCY#>#KS5*POPC2mBraR04MzJf`g4!JA#J+h>zm#A;K& z`c<@;R2l_}NHI7@CMPE(EG|0UIV$zFCu(e0k?@<-lNH62CU4T(UkmYyI=kr^ zuB;rx5g{zUc+a_4&K2sDROK;1;!M?3MCO?5qrnjSGVWFV?Z3~@j5WFG?;sk`LkQko zxxNpP!mv-3K=O=5`J3n5e=;x0Wc-L`$@6e5`&NOjT*-zFB}}D-R*~@I_d+V+Tf$OM zDKrZFM;D4i&gq=mejM6=jUk%Dt&cQ^1s&6n>Fz1P7sNasC<6+b)*KCnd5EN=gUFIw zW-1|J&I4CoIVy%Wm(r@-*e+tlQUI{s-LxK5A`)~k3zf-I!qHs6;$cSK8%{yA?Jc}|l0LZ8A@UAH-7AiW_xQGAf z;q~#={n0EjyfoHuwD`ag4~ewXqu5}k^B7NA4)@7({bNJn**b}wFB=BpOQw?Q@giKm zFwTebfW~f8P|KUPub1RN?62Y{hWx(yttE5ILH6`70$`;eg`@GSH`A~38eNRR^J=J1 zcbtmupFeFbw2sceV(x>$%_e9p!Ied>1XPNNpXU@;sp_tU&LO_9$w zI?W$7aoB>|h6$zIx`lssbYDanvr`%cGPSZ=yIT$+Qseu_|({hbs z(N2MMJ9Jvw#3VY=N$gxtmwwGUQL}EkSDW*sPxz_R$t_K;uQ_5ZP2raN+uO=ToVmq$NDP*2l`%^@JpyMP47I_j>$3eC89*zFqyjmD{z(@(-w3MSzHi zd-oEq2XR+C4fC?2O>@ufUfv++v@ty4nn=ifqZ}_9snIRHbmujcK@ls+lAcx1xq~qi z3c%Im^M9_4|8!!bt2mSV%hpq%W}gHxwwp23u6dk42S$+jD}BjZJ3IESmz+7<5=^+|3a6cU4%?d*cO3(Mu`zeFy+_~1N|*6fB%ZDODJXOnsFFJb)Z4v z4qcIlW~iEBO6Quh6*r%3sIU7z`%X7sKfK;ZD;1Y~dTM!7)ch#ga!|6kj!dvepN9)m zBNTwGO7nEdY7mb(XrMp=K{06Y4t0`}mE`%NIM6kz2`zM%zN&$T8r(b7k=hjQKX8Q4 z4IPF2)0&amqVV+S)h2wrHz$+==yM}EFnl!dL#GJpGf;p=#S9uXP(UFw9&5Ij*AsH> zz5pS_n%;E2VE->R>m|h00E;_%!#La~qt{i{B2i&cT~@iEA#hDKXgN%NR~oGaS`;lQ zsiuG0Sk)%G)tSwgqq+P+53g1Htx=0o)d~V&*B5YGVm8?eefU61(}RcQD;*5@UwqjM z8WiG_0Q^l!Zi_P$n_uzOB{{c$eC>lLZm`nDg{8?HuOW^>rG<_e2ok18x=qt6|H=FI zJG}@WA2?&ojm*Wb|2@FZl3rg|R0RT6Y0>xme31r$t>-4St=vIN&mlF0|KZND2v!!Y zN0C#yFGb>;m);<$(tnZVpMH6ES}^ecJJA6>dnPBi|AX9yc5&#PQD}hUrb|oqv!3>k z|ANq608HYYx;n&wp8h}R_J!uwW2S|Z&!WEWKU)>?T#gdE+0O-w`Qq+QOaSWtieFYB zMS@3vhe&(ryn{6AYAWT8{s+`v$qZ!1`@O^>v@sMs#+cEASQ}1)NdH#uGq+yovz}sRtPx-)RMC$RUiPhXO({#eF2h}FVG z6X@ak_oOcnS1^c0v;uw?2Skd)gsnCmf3Bxaw{bW5zcE@K@VnkKb3y>cSX-^Q=_-XR z_qi=rKR$zLK$w}s?9u;x+yZ#Z4< zS@WY@f*FXqJjqV3@;Zm);u!|(&@m`PMt!0b5)tSzy6ww14_Xs_ILO0F`JHCITI&9aU!~k61DC}T5UgnTN=4pcN6?)6D+Etps>rHijdI1M zFnQkN+!qW|4NKr*=y&{{7W>t4I^R24uU68U>ggC1=e&1r^KYs`)a9`m*YITst$wX> zM0u3)6M`pi^XH8mp||w@&=)VjB_ZmN5T651_vx~-lj9dVI`5C{^!q|sgtIf}%RdYX zQ+>u+WAe5kE44aUu5^#;Z= zUK_6}VQ1K4lK&@*^m7@_aEFuc*Y;Q*Z0+xv79zf0n+{N7>0O-xsW3yQ$4&pH77`E# zbG5I2+rYASGFF?*oxZu?Av55Jl+Lj*xsoul^0xm*Y!I6MJ~3m6oK(;z_lrE|s=_90 zjn;7u00dVRG%N2GmdW9=6H7HGvxR9Sg*5fhqMRBi=qj`#=Cr}5=&5c^;Eot$KrgS) zQ$MUlOMQk^;B0A{mMDW$&nn!hE_FIovXCO(F!&uLTC9dS6arnX$oLIWti0C zQCNU$nduU!+bt%^C4I_+nH}9PYy;0(tjg}qoG0PL6B!e~TzGf>YH2=bu>|)lU0eFY zGVeR`J*et0*s1Q~(aX0KtxrRQYy^8IaS{tCtcG0B!S0J$+e#ZAcX48K72sS3Tm%`| zWUu2y7e~EJy``M1(5V)vV4o)t5OYWh;8aY13w_RIWTXcT^1u01Mx|?L_c-B~l#qMdD~+ zmj)J=V)b10*X}-*_)tY7Uzqk$VK$wrlao8*H_0zX&NPsGv3+J1C$|{qA#vbnQ+ydg zwOH#ly{%FN-FttuG-;wKbv4bH#9LREpZ1wN3uvtQeOr5c75~p8f$`G%Bczt-cj)Y$ zp#X&#i>HqqN41doyoP6aQ=@WEI2g0;SRn%i^xkLm7-?+IX8+N>Wj6lLH<~U;6pt#_ zBm>diIz4Y6YtCpS$~R-hN81VWmEUl@^eNT0V-ZFW7o)i65+xPxxx49mmfz|w&)if$ zql@D0Ec$rwVFPieFfKAKUqWX0OQv&t{CnU75rqGyb^jRiaF_$k+(GUdM)o$E5(Z?; zR?XhUHoj&5grGh{igxsiO+;VFzN%7A8~>l5)N>=X`mqs>?qA4=WbZy3usYnq(GfF@ z$;X6`+Mm+%Qz6~9%{e;GOvpn9hZz-d`#|LGxhaXNZr)+InbYh2*`*-DP|ewnr||?` z(FgAH`l9YXr=u5N|1dAwBfy`L((G--A`V3~^|4afsCN8pq=kg^Ws)m{8Z6K)kY95v ztg^L7bN#Lzrg64mEPiwFux+S?l)a~h;joh)PqFUw9O%F=#(UZ|vVC&^2L~9ORw_MQ zOw6anW(fFYNsrc%tr?z7D5|_R>;L`r!_a_i29i`#XyMNS2NoE~hmWL$!Mu*J4lbPz zzyt!P?Pa%IT2q|yo4k*93ZhdhwB`$qY>v8nT+?EN;A@Ex!88S2d7MAbXC**dJrRp} zit%Y36xCHY+Vq4}9t7$CPc+u1N!Lucty{Y98KukNC;B$@_nRczAL2^hdDj+{07_^x z-6WCUo0n|sF(4(d?D{#oy%uS_^TBzQ*qr0cYx%r5$7Q?5!>=a63@`UQRiU$3ImMdS_b2%oy(&MIU+;jx^} zf>>NnAjqkGnsO!L4$O7n6-O@VY0-al#kPg@ed!K4WcOXY_{2_t(L^q`c9hjK7qJps z#PUF5qV0MVW~<5_3E{L&yj}XNVnqOHpb?F`uj*v!rl+1gf2rb8>Ux~L%N>=C&O6gi z+OC8IWSj+(eTKA{pi{nY=J*`xVt2pL^(g!W5~wa~!vf&uM%>)fVrejDiv;z1(&Pon zd3}(Jen3c$-JG!j3W`d7ghqw(DwRaA_hCho+REBocFMD|+I?A_&^+oiWCHZ@94C)oszQAuDmootQT9R4EUE&^A*b>05|=OHiz`~;uU2( z9@0uUC7b1o0GOM0cTLlN=cCqz4zaK$MUBh6I>^?26>k0~zG%nOs7VG^AtR9~V{RY| zdUT*cqOy3^?1)dsYMcNI%(~0ANzH|2Wj*q23xp|a_vADGZo%{-eRv2sD=#$}!6N~J z%ZFx>N6+mI2o0*dOiW&eS5IcVl>gyhym*lTT^h#Nn|@?*c7CGqmpl%aDy8Ckh_YLC z+3_CS25Gn1JhM%tXA+K)$UvM5g_-6FMuO2Nh303-bd8N1lyT2rNvI7``(ZbO|CEVI z(9$u`CX)Fd?V)SxON*d$hfiC^YcQhzPG(qi+*$og<4~@$EQuBzP}!6Dc!WlSG?Ssb z!rYWf#MCBqqvD!PDoa?6Xp@y^}|XrB77HRr9+XS)L+QY7q%*l>uKcqhOBP zN1v6CcwlR0!TGtpPw+c5ee+;_+s_C0LN~v{XI6G8XoXyTYWzJD>5}GCTs0_RPtIR< z3<(0$0eOeXG{px}OqmGD#j)LTK;Bd=#UbI>MSWkZmpLe8zNv?`Ant#1By8sO;M>2p)T@U-y%JEle~FLspmLZ?U_OHc7W za>5B#QSun>w1N!qwJqX9U-9g^HrLXx)WETN%WH)%yk zqX8($l)7H08;1@7#%f4k#AHJ_YxP=HK#%G2j!%S^)kWk`TJ#CutDeB>S4t8jS+UO2 zu2$oD{8OH7i#a}3*7H-5{@eD48IpFG{x!F^OfPm4-v$3etLZ|H)6v-E_%$Dtn#yqO z)uy?qs=ol%HgBG)dB!_M_feN8H(Yaa1$S)JRo^n$Gns7DEjw6S(N2&8RFB$Z)8#)G zA-4oddAbVI?kynV-uEuV)jBrLU5wxZ4xLfC;urb`wi=i z8CKd=vq{XrdfIv%+f9p4*F_TEE4bwn$&h_}eY%RaP-;;V?FUWbCj@g?Ip4a3eGBt^ zi;iOVt?25m*7ui4ux{XLUa_?d<2&l|llOQ=#$E)P9b+I5jZsN;bX(P3im=N4`O-RA z6nfe3=%vfik1wH+; z914Sv1VwARXU*^|~C7`X?`zPlgw>y#!F@@tly^L1dN?^r26D=#5I z0~FHH8+fX#j(_`2GiO@(kw_ONEvcr!Fu+O;xo}pLDmH=u0V3eMzbV3#a6WFIHIAJA z+9&n#lc}cBFWoPYJCCwD?5jet<3`*JZ{M9y!9gY0*jzA1^Sn8OSE}UrN2c6vIx!#{ zGoRrHk1dbK^ZIolvSlV~%y5$Hp9xySJpubgRBOH(Vyx$!NVek>`(vI+Hy&xq(H|1^ z>Fnlj7Ld->tEC0pxzu>!^JI*g^11CbOw}T18RN(H3v)?@`hH$e_qWA0^Xswd=a+oq z=+?OrLbzf%7~+#G#%R#_mh=&P4lMyNkideGS*~TJ@SWyO;7QPDE1;~^mCV<9B;v3z zPK}OEdL?&8%bjl4Z=symSfzc?LavH*b(6NRO&8IZJ#yV~y!~!n35+yu zGh6H^_V@0$6Tl9%v|0?s)fEr1b{-2JVY7SD#l=vX@aF+1P&-<*xa-go7>I5p1ZS#* zChX0fFcHTC5SBim;j9UCxOamNN!F>>DBZh`nD8X2vcG0BBw-K^5XY261QrY*8T;7~ z8O*VrWUoHYu1{mlJy7-0vfqDSwx%w(Q^bJDNnDOmAzCNawd31O3||=4pT@ER{7>0D z?~ML7ZkpGq2Oa({M}T1?+{V-w^O|_9w;voLZ&|FvYsakdgT-;r z$fAg)h<2%H7jZ3$@zF%YtT&K1RA}q#^X~XJDPSf=uZPcIYC}FW;9%+0Ha?k?+|f)% zv);8)WlcjxwW7|aU4mkq%Oiq_+wmxL7BWy$RcEhBF<9qE~&HdP#t*YtJ6Ibok(B!8Nd z%e*jvJQpeczOK-*+iSFNguY3Z)iuin!JWs+bNV(K=}F|Z;4xHLC_tcZ|B$f|rq6Zg zrJ#{hF9Zl68GpY0sx?&XSYvk7g`XXhU>1 z)*d@(o*>D)^Wi1CM+1`8D%D0!3yxO^HvMa2pRc5+YqxTD*sV&|sR7YQ1hQ_ecUkZ1 zJ-c6nXFomohNE4-x{sKwkQxi8d+%EDAuWL!KRJ*4YtseakgN4}t$DLIveJuK+_mCp z%IVfR%s@$LvG-qQp$$SJhXuRb$ zWqwg~m1%x{@nyJQB=4PLqMFE3i_XsaOv8}S%MKAHad1~_tqqR|)ke#g&1vTpLJ&q?n$jIZIR3FCEn1`DdHl z!=gd9@cUpMp7!7X7?d?4&nl&*%hq}=OYt?&XIBGmuv1#54=;Zjo+j00v!bqV%VwVc-4b9wfEki?hKZaY{!)=i%)KefHrS+W&F^ z3Np_!oDC|EuMYdAI!j@I1Tsq^&=e#zk}%gjqe*@`1xc!U|j#Iz08dzJo<3b zX?7j?*!aCvo{$k4qJA~6liXYSVYR9J&ADj>J^vb)&DNcXRjG8od5hcc)e~xu2Qinu zA{8D!k2*S%KX>b6jq!H6nN}?evmHb2;pz(OUwK>Es=KUCLqe)r#R0RwcUnqQIit3x zyh-FpT|tyF4qx(sQQAbgU#3mCZuMB)2KOiIc4q)ABZNc(4n|@el@KE9dwTu=A@w(> z>>uJ1Jd-(x+%6)u{n5LtM3Ark1OPR|`k?j7#?)5_4BZwSb*9 z6zz*^Gi!+yeLlyp4T&CY9n^b*HL@cZuy7Cx&HDnxLd9&j+?n5RHC%8|#FN{nUm9Cj zbSK!puFBO~d+} z7Oy305m^|cPwx(8#_MSc!7LQ#ZvmZD-5{cU%0602+rooN0nZjq3_|F-;nxTV2yd-E z#lm?GRirt95gXEl=?$fn3c0{iKV(uF`=02s-D2HvxN=oVgtH@pB-LJWfK~CI zB*IDqDy3e)*5q+dB*P+P;`C?Kyk@Us*8^=?4HhA^wrfXeuga7-_0N~%_KCBC_{e(f z=4r~7&XV)lBH~J$!#y|}K94O`=FUd^y3ifV!O4a(DEo*-qXJD-?f&atVn3W#N3*@o z7omq2q5}MPzq$shiyTbxEo#mCA}mGSGw`Rw0}O3wVQh)~=bAS?1Evk;ZFj9|2!bb) z^|6DP74F>#IMH`>JSnt(?P9^@ek&UH(b*jc#Xru8Ztf|r=ejhrZ9c3TpAh;Dri*CP zsRZX=XC)78NEw~IL=%t7ZokR4kBs>By~JeOSBPmSa`rDJOrYUw;8j?i<1H<y^`2E#htfMj$(qN41G21dLiY%rODR;QAvNlV=tx`zj_e-_LY{OZ` zudVSR1;_K$dABtvPdFz;EBE$Vd!>Asgi*E`-OBH7?&5CJLtPurdoN9My z0{D@ilj^?+@N=A%DBK++3*mXd%HbaG8}yeP%6iQ1qTx*#UQaB=Zf)_8<#K+%@5o6f zc-Z{6$bm~RN5THg+Pr8qlFpH6yYMR(Az$^Q3yv?+H0LFcrLzGO0)Kv)Y!5zO{CwGm zF)sHv6*Vp5;l)9TUJ=z)vS~_AJfv*iwe-Pe-RHiqTArMa4SzBAh zvqtR$F!}AnB-CY9nGC)~n{fHuh^b?`(x?JU^;ZCB�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�(i=JntFa$kxrHj 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 state["deadline"]: + raise TimeoutError("The bounded native scope/history journey did not finish.") + phase = state["phase"] + if phase == "start": + screen.set_package(str(first) + "/.") + check("screen, header and history use one normalized package identity", + screen.package_path == header.package_path == screen._history.package == str(first)) + screen._command.setCurrentIndex(screen._command.findData("features")) + choose(ranges[0]) + check("real header selection enables the composed Analysis screen with exact bounds", + screen._btn_run.isEnabled() and screen.scope is picker.selection + and (screen.scope.start_ns, screen.scope.end_ns) == ranges[0]) + QTest.mouseClick(screen._btn_run, Qt.MouseButton.LeftButton) + check("real feature worker disables saved-history actions while running", + screen._thread is not None and not screen._history._open.isEnabled() + and not screen._history._refresh.isEnabled()) + state["phase"] = "first-job" + elif phase == "first-job" and screen._thread is None: + check("the first real worker completes without a modal failure", not state["dialogs"]) + check("completed scoped job reaches the saved-history viewer", + len(jobs(first)) == 1 and bool(screen._last_job_dir) + and screen._history.loaded_job_id == Path(screen._last_job_dir).name) + job = Path(screen._last_job_dir) + assert_job(job, ranges[0]) + state["first_job"] = job + state["saved_bytes"] = hashes(job) + choose(ranges[1]) + selected = screen.scope + QTest.mouseClick(screen._history._refresh, Qt.MouseButton.LeftButton) + QTest.mouseClick(screen._history._open, Qt.MouseButton.LeftButton) + check("explicitly reopening the old job preserves the next selected scope", + screen.scope == picker.selection == selected + and (selected.start_ns, selected.end_ns) == ranges[1]) + check("reopen is read-only and starts no additional worker", + hashes(job) == state["saved_bytes"] and jobs(first) == {job} + and screen._thread is None) + QTest.mouseClick(screen._history._details, Qt.MouseButton.LeftButton) + dialog = screen._history._dialog + params_editor = dialog.findChild(QPlainTextEdit, "analysisHistoryParameters") + saved_params = json.loads(params_editor.toPlainText()) + check("native read-only details show the saved scope, distinct from the next selection", + params_editor.isReadOnly() + and (saved_params["startSessionNs"], saved_params["endSessionNs"]) == ranges[0] + and screen.scope == selected) + dialog.close() + screen.set_package(str(first) + "/.") + check("same-package refresh preserves both scope and loaded saved result", + screen.scope == picker.selection == selected + and screen._history.loaded_job_id == job.name) + state["phase"] = "capture-and-second-job" + elif phase == "capture-and-second-job": + check("combined native frame is captured", shell.grab().save(str(output / "scope-history-reopened.png"))) + state["jobs_before_second"] = jobs(first) + QTest.mouseClick(screen._btn_run, Qt.MouseButton.LeftButton) + check("a second real worker starts from the next selection", screen._thread is not None) + # The current application may change package context while a + # worker is pending. Its real queued completion must stay A. + screen.set_package(str(second)) + check("changing package resets scope and clears history as one transition", + screen.package_path == header.package_path == screen._history.package == str(second) + and screen.scope.mode == picker.selection.mode == "full" + and not screen._last_job_dir and not screen._history.loaded_job_id) + state["phase"] = "second-job" + elif phase == "second-job" and screen._thread is None: + completed = jobs(first) - state["jobs_before_second"] + check("late real completion is retained under its originating package only", + len(completed) == 1 and not jobs(second) and not state["dialogs"]) + second_job = next(iter(completed)) + assert_job(second_job, ranges[1]) + check("late foreign completion cannot repaint current history or scope", + screen.package_path == str(second) and screen.scope.mode == picker.selection.mode == "full" + and not screen._last_job_dir and not screen._history.loaded_job_id + and "Result saved for the previous package" in screen._log.toPlainText()) + check("the prior reopened job remains byte-identical after the second job", + hashes(state["first_job"]) == state["saved_bytes"]) + check("both real package raw inputs remain byte-identical", + all(hashes(p, raw_only=True) == raw_before[str(p)] for p in [first, second])) + report["real_jobs"] = [str(state["first_job"]), str(second_job)] + report["raw_package_hashes"] = raw_before + report["last_native_log"] = screen._log.toPlainText() + report["dialogs"] = state["dialogs"] + finish() + except BaseException: + report["errors"].append(traceback.format_exc()) + state["cancelled"] = True + if screen._thread is not None: + screen._cancel_job() + else: + finish() + + timer = QTimer() + timer.timeout.connect(tick) + timer.start(15) + report["event_loop_exit"] = app.exec() + shell.deleteLater() + QCoreApplication.sendPostedEvents(None, QEvent.Type.DeferredDelete) + app.processEvents() + report["pyside6"] = PySide6.__version__ + report["python"] = sys.version + except BaseException: + report["errors"].append(traceback.format_exc()) + report["source_unchanged"] = hashes(source) == expected + report["passed"] = sum(row["passed"] for row in report["checks"]) + report["failed"] = sum(not row["passed"] for row in report["checks"]) + report["exit_code"] = 0 if not report["errors"] and not report["failed"] and report["source_unchanged"] else 1 + (output / "receipt.json").write_text(json.dumps(report, indent=2) + "\n") + print(json.dumps({k: report[k] for k in ["passed", "failed", "source_unchanged", "exit_code"]})) + return report["exit_code"] + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/native.stderr.log b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/native.stderr.log new file mode 100644 index 00000000..a61736e6 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/native.stderr.log @@ -0,0 +1,3 @@ +This plugin does not support propagateSizeHints() +This plugin does not support propagateSizeHints() +This plugin does not support propagateSizeHints() diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/native.stdout.log b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/native.stdout.log new file mode 100644 index 00000000..85569fcb --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/native.stdout.log @@ -0,0 +1 @@ +{"passed": 2, "failed": 1, "source_unchanged": true, "exit_code": 1} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/process.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/process.json new file mode 100644 index 00000000..8713ebe9 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/process.json @@ -0,0 +1,18 @@ +{ + "command": [ + "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "-B", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/check_scope_history.py", + "--source", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/receiving-source-verified", + "--inputs", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/source-inputs.json", + "--output", + "/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/native-scope-run" + ], + "exit_code": 1, + "seconds": 3.46, + "stdout_sha256": "ca6c5fb808170de343775ef9272647c204a8662d37fa236ee83d8b9c59d03a70", + "stderr_sha256": "f1aa9b66f160e1438e3c1b8beee83bb34d3af8ade06f075e0a751d8d46ebb208", + "method_sha256": "44c24508e4e4aa9d14d1771be486bb953f8b3719652183c2e9d7c3bb81ac2b17" +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/receipt.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/receipt.json new file mode 100644 index 00000000..a24fabcd --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/receipt.json @@ -0,0 +1,33 @@ +{ + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "runtime_tree": "07d78241dca691015bb3e4d8d260b109672b7de0", + "screen_git_blob": "ee2db9acacdc92d3aa8ba0bfe12f638e9418f9b4", + "checks": [ + { + "name": "screen, header and history use one normalized package identity", + "passed": true + }, + { + "name": "real header selection enables the composed Analysis screen with exact bounds", + "passed": true + }, + { + "name": "real feature worker disables saved-history actions while running", + "passed": false + } + ], + "errors": [ + "Traceback (most recent call last):\n File \"/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/check_scope_history.py\", line 151, in tick\n check(\"real feature worker disables saved-history actions while running\",\n File \"/dev/shm/hamon-401c5d17da79-capture-history-pr/scope-current-seam/check_scope_history.py\", line 54, in check\n assert condition, name\n ^^^^^^^^^\nAssertionError: real feature worker disables saved-history actions while running\n" + ], + "method": "QApplication.exec/QTimer; actual SessionHeader and AnalysisScreen, two real QThread/MCAP feature jobs", + "method_sha256": "44c24508e4e4aa9d14d1771be486bb953f8b3719652183c2e9d7c3bb81ac2b17", + "source_inputs_sha256": "3d76e4d458693e38756479d37fe325301e5ed9eda01ee4945e913f93e6206557", + "scope": "One changed scope/history boundary. No Windows MainWindow, full-suite, nested-image repair or installed-release claim.", + "event_loop_exit": 0, + "pyside6": "6.11.2", + "python": "3.12.14 (main, Aug 25 2026, 14:00:49) [Clang 22.1.3 ]", + "source_unchanged": true, + "passed": 2, + "failed": 1, + "exit_code": 1 +} diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/screen_analysis.py.txt b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/screen_analysis.py.txt new file mode 100644 index 00000000..ee2db9ac --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/screen_analysis.py.txt @@ -0,0 +1,517 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""Offline Analysis workbench — jobs in QThread; figures in-app via PyQtGraph.""" + +from __future__ import annotations + +import os +import threading +from pathlib import Path +from typing import Any + +from PySide6.QtCore import QObject, QThread, Signal, Slot +from PySide6.QtWidgets import ( + QComboBox, + QFileDialog, + QHBoxLayout, + QLabel, + QMessageBox, + QProgressBar, + QPushButton, + QSplitter, + QTextEdit, + QVBoxLayout, + QWidget, +) + +from . import theme +from .analysis_history import SavedJobDetails, job_belongs_to_package, load_saved_job +from .persistence import DesktopPersistence +from .state import CaptureState, fmt_time +from .widgets_analysis_history import AnalysisHistory +from .widgets_analysis_jobs import AnalysisJobExtras, peek_ml_bundle_summary +from .widgets_analysis_plots import FigureGallery, JobInspector +from .widgets_analysis_scope import WINDOW_COMMANDS, ScopeSelection +from .widgets_mappings import AnatomicalMappingPanel + + +class _AnalysisWorker(QObject): + progress = Signal(str, float) + finished = Signal(object) # JobResult + failed = Signal(str) + + def __init__( + self, + package: str, + command: str, + gap_policy: str, + extra: dict[str, Any] | None = None, + *, + scope: ScopeSelection | None = None, + ) -> None: + super().__init__() + self._package = package + self._command = command + self._gap_policy = gap_policy + self._extra = dict(extra or {}) + self._scope = scope or ScopeSelection() + self._cancel = threading.Event() + + def request_cancel(self) -> None: + self._cancel.set() + + @Slot() + def run(self) -> None: + try: + from capture_analysis import JobParams, run + + if self._scope.mode != "full" and self._command not in WINDOW_COMMANDS: + raise ValueError("This command requires Full session scope.") + + def on_progress(stage: str, frac: float) -> None: + self.progress.emit(stage, float(frac)) + + result = run( + self._package, + JobParams( + command=self._command, + gap_policy=self._gap_policy, + extra=self._extra, + **self._scope.job_fields(), + ), + progress=on_progress, + cancel=self._cancel, + ) + self.finished.emit(result) + except InterruptedError as exc: + self.failed.emit("\n".join(["cancelled", *getattr(exc, "__notes__", ())])) + except Exception as exc: # noqa: BLE001 + self.failed.emit("\n".join([str(exc), *getattr(exc, "__notes__", ())])) + + +class AnalysisScreen(QWidget): + """Analysis workbench — never talks to the daemon.""" + + package_loaded = Signal(object) # ReviewSummary, or None after a failed open + + def __init__( + self, + state: CaptureState, + persistence: DesktopPersistence | None = None, + parent: QWidget | None = None, + ) -> None: + super().__init__(parent) + self._state = state + self._persistence = persistence + self._package = "" + self._summary = None + self._scope: ScopeSelection | None = ScopeSelection() + self._last_job_dir = "" + self._thread: QThread | None = None + self._worker: _AnalysisWorker | None = None + + root = QVBoxLayout(self) + root.setContentsMargins(12, 10, 12, 10) + root.setSpacing(8) + + title = QLabel("Analysis") + title.setFont(theme.ui(14, bold=True)) + root.addWidget(title) + + self._banner = QLabel( + "Offline jobs write under processing/jobs/. Raw streams are never modified." + ) + self._banner.setObjectName("Dim") + self._banner.setWordWrap(True) + root.addWidget(self._banner) + self._scope_note = QLabel("Scope: full session") + self._scope_note.setWordWrap(True) + self._scope_note.setObjectName("Dim") + root.addWidget(self._scope_note) + + self._history = AnalysisHistory() + self._history.job_loaded.connect(self._show_saved_job) + self._history.view_cleared.connect(self._clear_result_view) + root.addWidget(self._history) + + splitter = QSplitter() + splitter.setChildrenCollapsible(False) + root.addWidget(splitter, 1) + + left = QWidget() + left.setMinimumWidth(300) + left_layout = QVBoxLayout(left) + left_layout.setContentsMargins(0, 0, 8, 0) + left_layout.setSpacing(8) + self._build_controls(left_layout) + self._mappings = AnatomicalMappingPanel(persistence) + left_layout.addWidget(self._mappings) + splitter.addWidget(left) + + self._gallery = FigureGallery() + splitter.addWidget(self._gallery) + + self._inspector = JobInspector() + self._inspector.setMinimumWidth(240) + splitter.addWidget(self._inspector) + splitter.setStretchFactor(0, 0) + splitter.setStretchFactor(1, 3) + splitter.setStretchFactor(2, 1) + + def _build_controls(self, root: QVBoxLayout) -> None: + path_row = QHBoxLayout() + self._path = QLabel("No package selected") + self._path.setObjectName("Dim") + self._path.setWordWrap(True) + self._btn_browse = QPushButton("Browse…") + self._btn_browse.clicked.connect(self._browse) + self._btn_use_open = QPushButton("Use open session") + self._btn_use_open.clicked.connect(self._use_open_session) + path_row.addWidget(self._path, 1) + path_row.addWidget(self._btn_use_open) + path_row.addWidget(self._btn_browse) + root.addLayout(path_row) + + cards = QHBoxLayout() + self._card_session = QLabel("—") + self._card_sources = QLabel("—") + self._card_gaps = QLabel("—") + self._card_duration = QLabel("—") + for label, widget in ( + ("Session", self._card_session), + ("Sources", self._card_sources), + ("Gaps", self._card_gaps), + ("Duration", self._card_duration), + ): + box = QWidget() + box.setObjectName("Card") + col = QVBoxLayout(box) + col.setContentsMargins(8, 6, 8, 6) + head = QLabel(label) + head.setObjectName("Faint") + head.setFont(theme.ui(8)) + widget.setFont(theme.ui(10, bold=True)) + widget.setWordWrap(True) + col.addWidget(head) + col.addWidget(widget) + cards.addWidget(box, 1) + root.addLayout(cards) + + opts = QVBoxLayout() + cmd_row = QHBoxLayout() + cmd_row.addWidget(QLabel("Command")) + self._command = QComboBox() + for label, value in ( + ("QC only", "qc"), + ("Features + plots", "all"), + ("Features only", "features"), + ("Plots only", "plots"), + ("Pose (body teacher)", "pose"), + ("Kinematics (Tier A)", "kinematics"), + ("ML bundle", "ml_bundle"), + ("Eval report", "eval"), + ): + self._command.addItem(label, value) + self._command.currentIndexChanged.connect(self._on_command_changed) + cmd_row.addWidget(self._command, 1) + opts.addLayout(cmd_row) + gap_row = QHBoxLayout() + gap_row.addWidget(QLabel("Gap policy")) + self._gap_policy = QComboBox() + for policy in ("mask", "split", "fail"): + self._gap_policy.addItem(policy, policy) + gap_row.addWidget(self._gap_policy, 1) + opts.addLayout(gap_row) + root.addLayout(opts) + + self._extras = AnalysisJobExtras() + self._extras.set_command("qc") + root.addWidget(self._extras) + + actions = QHBoxLayout() + self._btn_run = QPushButton("Run") + self._btn_run.setObjectName("Primary") + self._btn_run.clicked.connect(self._start_job) + self._btn_cancel = QPushButton("Cancel") + self._btn_cancel.setEnabled(False) + self._btn_cancel.clicked.connect(self._cancel_job) + actions.addWidget(self._btn_run) + actions.addWidget(self._btn_cancel) + root.addLayout(actions) + + aux = QHBoxLayout() + self._btn_open_job = QPushButton("Open job folder") + self._btn_open_job.setEnabled(False) + self._btn_open_job.clicked.connect(self._open_job_folder) + self._btn_open_report = QPushButton("Open QC report (HTML)") + self._btn_open_report.setEnabled(False) + self._btn_open_report.clicked.connect(self._open_report) + aux.addWidget(self._btn_open_job) + aux.addWidget(self._btn_open_report) + root.addLayout(aux) + + self._progress = QProgressBar() + self._progress.setRange(0, 100) + self._progress.setValue(0) + root.addWidget(self._progress) + + self._log = QTextEdit() + self._log.setReadOnly(True) + self._log.setFont(theme.mono(9)) + self._log.setPlaceholderText("Job log…") + self._log.setMaximumHeight(160) + root.addWidget(self._log) + root.addStretch(1) + + def _on_command_changed(self) -> None: + command = str(self._command.currentData() or "qc") + self._extras.set_command(command) + self._extras.refresh() + self._sync_enabled() + + @property + def package_path(self) -> str: + return self._package + + @property + def summary(self): + return self._summary + + @property + def scope(self) -> ScopeSelection | None: + return self._scope + + def set_scope(self, package_path: str, selection: ScopeSelection | None) -> None: + if str(Path(package_path).resolve()) != self._package: + return + self._scope = selection + self._sync_enabled() + + def _scope_error(self) -> str | None: + if self._scope is None: + return "Correct the scope bounds in the session header before running analysis." + try: + self._scope.job_fields() + except ValueError as exc: + return str(exc) + if self._scope.mode != "full" and self._command.currentData() not in WINDOW_COMMANDS: + return ( + "This command uses the full session or its input jobs. " + "Select Full session to run." + ) + return None + + def set_package(self, package_path: str) -> None: + if not package_path: + return + resolved = str(Path(package_path).resolve()) + if resolved != self._package: + self._scope = ScopeSelection() + self._package = resolved + self._path.setText(resolved) + self._history.set_package(resolved) + self._extras.set_package(resolved) + self._refresh_summary() + self._sync_enabled() + self.package_loaded.emit(self._summary) + + def refresh_from_state(self) -> None: + if self._state.package_path and not self._package: + self.set_package(self._state.package_path) + self._sync_enabled() + + def _recording_locked(self) -> bool: + from capture_protocol.generated.capture.v1 import control_pb2 + + return self._state.session_state in ( + control_pb2.SESSION_STATE_RECORDING, + control_pb2.SESSION_STATE_ARMING, + ) + + def _sync_enabled(self) -> None: + busy = self._thread is not None and self._thread.isRunning() + locked = self._recording_locked() + has_pkg = self._summary is not None + scope_error = self._scope_error() + self._btn_run.setEnabled(has_pkg and not busy and not locked and scope_error is None) + self._scope_note.setText( + scope_error or f"Scope: {self._scope.describe()}. QC reports cover the full package." + ) + self._btn_cancel.setEnabled(busy) + self._btn_browse.setEnabled(not busy) + self._btn_use_open.setEnabled(not busy and bool(self._state.package_path)) + self._command.setEnabled(not busy) + self._gap_policy.setEnabled(not busy) + self._history.set_busy(busy) + if locked: + self._banner.setText( + "Analysis is disabled while the session is arming or recording." + ) + + def _refresh_summary(self) -> None: + try: + from capture_session import load_review_summary + + summary = load_review_summary(self._package) + except Exception as exc: # noqa: BLE001 + self._summary = None + for card in ( + self._card_session, self._card_sources, self._card_gaps, self._card_duration, + ): + card.setText("—") + self._banner.setText(f"Could not load package: {exc}") + return + self._summary = summary + self._banner.setText( + f"State {summary.state}. Jobs write only under processing/jobs/." + ) + self._card_session.setText(summary.session_id or "—") + self._card_sources.setText(str(len(summary.source_ids))) + self._card_gaps.setText( + f"{len(summary.gaps)} · {summary.open_gap_count} open" + ) + dur = summary.duration_ns / 1e9 if summary.duration_ns > 1 else 0.0 + self._card_duration.setText(fmt_time(dur) if dur else "unknown") + + def _browse(self) -> None: + start = self._package or str( + Path(os.environ.get("LOCALAPPDATA", "")) / "CaptureSuite" / "sessions" + ) + path = QFileDialog.getExistingDirectory(self, "Select .mmsession package", start) + if path: + self.set_package(path) + + def _use_open_session(self) -> None: + if self._state.package_path: + self.set_package(self._state.package_path) + + def _append_log(self, line: str) -> None: + self._log.append(line) + + def _start_job(self) -> None: + if self._summary is None or (self._thread and self._thread.isRunning()): + return + if self._recording_locked(): + QMessageBox.warning( + self, + "Analysis", + "Stop recording before running offline analysis.", + ) + return + scope_error = self._scope_error() + if scope_error: + QMessageBox.warning(self, "Analysis scope", scope_error) + return + command = str(self._command.currentData()) + gap_policy = str(self._gap_policy.currentData()) + err = self._extras.validate_for(command) + if err: + QMessageBox.warning(self, "Analysis", err) + return + extra = self._extras.build_extra(command) + self._log.clear() + self._clear_result_view() + self._append_log(f"Starting {command} on {self._package}") + self._append_log(f"scope={self._scope.describe()}") + if extra: + self._append_log(f"extra={extra}") + self._progress.setValue(0) + + thread = QThread(self) + worker = _AnalysisWorker(self._package, command, gap_policy, extra, scope=self._scope) + worker.moveToThread(thread) + thread.started.connect(worker.run) + worker.progress.connect(self._on_progress) + worker.finished.connect(self._on_finished) + worker.failed.connect(self._on_failed) + worker.finished.connect(thread.quit) + worker.failed.connect(thread.quit) + thread.finished.connect(worker.deleteLater) + thread.finished.connect(thread.deleteLater) + thread.finished.connect(self._on_thread_finished) + self._thread = thread + self._worker = worker + self._sync_enabled() + thread.start() + + def _cancel_job(self) -> None: + if self._worker is not None: + self._append_log("Cancel requested…") + self._worker.request_cancel() + + @Slot(str, float) + def _on_progress(self, stage: str, frac: float) -> None: + self._progress.setValue(int(max(0.0, min(1.0, frac)) * 100)) + self._append_log(f"{stage} ({frac:.0%})") + + @Slot(object) + def _on_finished(self, result: object) -> None: + job_dir = str(getattr(result, "job_dir", "") or "") + status = str(getattr(result, "status", "") or "") + job_id = str(getattr(result, "job_id", "") or "") + self._append_log(f"Done status={status} job_id={job_id}") + self._append_log(f"dir={job_dir}") + if not job_belongs_to_package(self._package, job_dir): + self._append_log( + "Result saved for the previous package; select that package to inspect it." + ) + return + self._progress.setValue(100) + self._history.refresh(preferred_job_id=job_id) + try: + details = load_saved_job(self._package, Path(job_dir).name) + except (OSError, ValueError, UnicodeError) as exc: + self._append_log(f"Result saved, but the viewer could not load it: {exc}") + return + self._show_saved_job(details) + + def _clear_result_view(self) -> None: + self._last_job_dir = "" + self._btn_open_job.setEnabled(False) + self._btn_open_report.setEnabled(False) + self._gallery.clear() + self._inspector.clear() + self._history.clear_loaded() + + @Slot(object) + def _show_saved_job(self, details: SavedJobDetails) -> None: + if not job_belongs_to_package(self._package, details.job.directory): + return + job_dir = str(details.job.directory) + self._last_job_dir = job_dir + self._history.show_loaded(details) + self._btn_open_job.setEnabled(bool(job_dir)) + report = Path(job_dir) / "reports" / "qc.html" if job_dir else Path() + self._btn_open_report.setEnabled(report.is_file()) + if job_dir: + path = Path(job_dir) + self._gallery.load_job_dir(path) + self._inspector.load_job_dir(path) + self._append_log("Figures loaded in-app (sync dashboard + gallery tabs).") + ml_summary = peek_ml_bundle_summary(path) + if ml_summary: + self._append_log(ml_summary) + eval_path = path / "eval" / "eval_report.json" + if eval_path.is_file(): + self._append_log(f"Eval report: {eval_path.name}") + self._extras.refresh() + + @Slot(str) + def _on_failed(self, message: str) -> None: + self._append_log(f"FAIL: {message}") + self._history.refresh() + if message.split("\n", 1)[0] != "cancelled": + QMessageBox.warning(self, "Analysis failed", message) + + def _on_thread_finished(self) -> None: + self._thread = None + self._worker = None + self._sync_enabled() + + def _open_job_folder(self) -> None: + if self._last_job_dir and Path(self._last_job_dir).is_dir(): + os.startfile(self._last_job_dir) # noqa: S606 — explorer only + + def _open_report(self) -> None: + path = Path(self._last_job_dir) / "reports" / "qc.html" + if path.is_file(): + os.startfile(str(path)) # noqa: S606 — HTML QC external per workbench spec diff --git a/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/source-inputs.json b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/source-inputs.json new file mode 100644 index 00000000..1abccfd7 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/current-scope/startup-negative/source-inputs.json @@ -0,0 +1,863 @@ +{ + "repository": "Jacob-Met/CaptureSuite", + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "canonical_tree": "18e97093f04de23de5e9878fd22c1f5ed986d5f3", + "history_author_runtime": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "composition_tree": "07d78241dca691015bb3e4d8d260b109672b7de0", + "composed_screen_git_blob": "ee2db9acacdc92d3aa8ba0bfe12f638e9418f9b4", + "files": [ + { + "path": "desktop/capture_desktop/__init__.py", + "git_blob": "48777bd04b62e3b3b877e12311f7257819ab3a07", + "bytes": 119, + "sha256": "8426c94323c4cca0879b8612345e3577d0a75f6239237a28d79d94a42004c3b5" + }, + { + "path": "desktop/capture_desktop/__main__.py", + "git_blob": "f78ccce984b725bf7263407d5b4b2d4c56131433", + "bytes": 723, + "sha256": "8dbad73a7373565a3513ccbb613f11bffdd13a05861c3e8e07392b8d51008aa2" + }, + { + "path": "desktop/capture_desktop/analysis_history.py", + "git_blob": "1b8fd23aee632cc3af19990b9d7685c6a3ed1b5e", + "bytes": 6375, + "sha256": "2e0db8cee59ef268d3c91ea0beac7d761d83a3003862841cc9d7f1782fd3543c" + }, + { + "path": "desktop/capture_desktop/app.py", + "git_blob": "363b6acbdcf0ba382bd040903946e6916ab282c9", + "bytes": 47945, + "sha256": "e33cf4446d4edfda3634cb5445aa9456d2f243a8b710c0d9c6497b2ec28078b2" + }, + { + "path": "desktop/capture_desktop/daemon_link.py", + "git_blob": "620e5a753fbd8448c3a57fcfa6a8b8540ac0bcd0", + "bytes": 10899, + "sha256": "ab76628bbe0231c7e5e4d570f2abed01100dddd6a24bb62020b670a6b62427dd" + }, + { + "path": "desktop/capture_desktop/export_wizard.py", + "git_blob": "b22d0098eb9af3860c654591e411dbab68a0f05d", + "bytes": 6734, + "sha256": "fb957ff184109bcb4e379dde30414048e855c93ec390f9b50c7ab603c3cd4e30" + }, + { + "path": "desktop/capture_desktop/main.py", + "git_blob": "90ad2adebae1f52ffabb889efe43a31dca1b6454", + "bytes": 1059, + "sha256": "e61c29a1925f8d85b24438f087dec360a4481a32e0dc2bd8ed8feb6629026e84" + }, + { + "path": "desktop/capture_desktop/persistence.py", + "git_blob": "2f2da2bfda654009baa0e723465c82c1690a0676", + "bytes": 3379, + "sha256": "cdb1fa0094fec72543d5051435850e51d78d79d4bde8d5c83520fa072a2c74c4" + }, + { + "path": "desktop/capture_desktop/schema_form.py", + "git_blob": "2d5fa62b1448e168e639e3e8879989a3461e1053", + "bytes": 12206, + "sha256": "7d825b5dc7566d630f31775df6fcc9def1e916eaff5be17a552bf89f28b3418b" + }, + { + "path": "desktop/capture_desktop/screen_analysis.py", + "git_blob": "ee2db9acacdc92d3aa8ba0bfe12f638e9418f9b4", + "bytes": 19067, + "sha256": "5c059bcca587879ec1cd4c21188db641a3063ad9848898bbc8ad500fb3c8f4c8" + }, + { + "path": "desktop/capture_desktop/screen_capture.py", + "git_blob": "b2d3cf05d57484f5efdbb0df85e5f0a065dab3d9", + "bytes": 34181, + "sha256": "4e101ddeeaed7f7f2b4ec2ab2e4b1f4f55ebb86f73b394d25cfd2b904cd2572e" + }, + { + "path": "desktop/capture_desktop/screen_presets.py", + "git_blob": "c143fb87629fb90f656a7a3b4b9f3c136b03f596", + "bytes": 5230, + "sha256": "b62d6f4bef6c1f0fc04b9eaf6a8afd1b2eeb17f6ce14946a06b0495ba33d402c" + }, + { + "path": "desktop/capture_desktop/screen_review.py", + "git_blob": "88a902ca7699faa2964f3fc22ec3348a339905a4", + "bytes": 7003, + "sha256": "e5aff59de4b194123ca4c4518b34e7b6103326fbd6b0280e2122d984d01072ec" + }, + { + "path": "desktop/capture_desktop/screen_settings.py", + "git_blob": "fe6d1e8884b7300e4cb5039b8e86679339e43b4d", + "bytes": 4581, + "sha256": "519436946827fac53d0be68270c2929bd1ce615a58b2372e9e3fc10619a7ba6e" + }, + { + "path": "desktop/capture_desktop/screen_setup.py", + "git_blob": "1df45aac30d63d6ab2e8ddc7efe0db394c513ab1", + "bytes": 11452, + "sha256": "01eb01ffffe835fcf5d26120d508800cc3cdac1e91ffaa3d0d2fa669c6326182" + }, + { + "path": "desktop/capture_desktop/state.py", + "git_blob": "95046ba5ef7f7bbf5685a54b7ae8fd400814148c", + "bytes": 17906, + "sha256": "97fc98498f4553fc7f052d0dc4db992cf2fc136ba7c4405cd275bd156c74e314" + }, + { + "path": "desktop/capture_desktop/theme.py", + "git_blob": "e309ce92bf66f65ca7c111698e1f536f05e4dca9", + "bytes": 12072, + "sha256": "c77f24e1afeb06400385bd0d535800f13dc15d972891e1ff8af504cbe5c818f3" + }, + { + "path": "desktop/capture_desktop/widgets_analysis_history.py", + "git_blob": "8798627cd7d694c5a09c3c402a739a4ec45b6574", + "bytes": 8458, + "sha256": "a3b77c87483c1412b50de7ddde1498f6bfd3968002fc3ac3bfa474a2477d9bc4" + }, + { + "path": "desktop/capture_desktop/widgets_analysis_jobs.py", + "git_blob": "c4d2f4513032d744f1f8066f0c887cda71d9b911", + "bytes": 6304, + "sha256": "5cdea6045456e61a58b5525dd224a22a140962d31d2adc5b0102168444468f98" + }, + { + "path": "desktop/capture_desktop/widgets_analysis_plots.py", + "git_blob": "bb6c3033b5e4ed96a2e08857d38715b836926bf5", + "bytes": 9382, + "sha256": "85c73f881ee7d60ef2f868f7ff73fc57c0a4ef99a717f7f5015534db23e1ab86" + }, + { + "path": "desktop/capture_desktop/widgets_analysis_scope.py", + "git_blob": "7b15a34fc1f8a9f31164d4ee9b4d144ff01a8d2d", + "bytes": 10391, + "sha256": "3f58ffba9125d0ce88fa99317f6aa593fe8aeb4b0dc1d799c95c9c04fb0b73ff" + }, + { + "path": "desktop/capture_desktop/widgets_mappings.py", + "git_blob": "62dd1b137ffc54a05aa81f37eb8627dd12e0032a", + "bytes": 3658, + "sha256": "89808d37cb0fce476665a24766963c7a509f5b1802d05dedbf9ca44351081f4b" + }, + { + "path": "desktop/capture_desktop/widgets_modality_expanded.py", + "git_blob": "70d67f7405730707ad67d1da0e71a7e87bf8b68e", + "bytes": 8566, + "sha256": "12db25b37e8b2724e5eaabdcb1810aa979633885097b6ec11c33d98a46a83a70" + }, + { + "path": "desktop/capture_desktop/widgets_preview.py", + "git_blob": "d0a760164a413616ab406a54d81c7b3f9b30d638", + "bytes": 27254, + "sha256": "78d79c9af67f7e0cbcee3a3a693a22e72753256ca465bab7edb9c2037822dec4" + }, + { + "path": "desktop/capture_desktop/widgets_radar_array.py", + "git_blob": "d270e7aa8b36a9a6376cfbd76a46ec6448bb9ae4", + "bytes": 2965, + "sha256": "be08874ade0b4d9197ea85cb6ae3b30db75273ddd3c426faaaf28b4f796653a8" + }, + { + "path": "desktop/capture_desktop/widgets_session_header.py", + "git_blob": "b1f4cbf5ab35ef06b4bf1da45f0be6ffb34b0a4a", + "bytes": 5749, + "sha256": "b9e11a7e3709283ed37bacbe96836d6720467f2bdcb934d75491df5dc02927fa" + }, + { + "path": "desktop/capture_desktop/widgets_session_timeline.py", + "git_blob": "2d9ba524b1e6231c934f6d037796a53e135a12f8", + "bytes": 10010, + "sha256": "7671ad4b632fd83498ad0c02f9030e4f46a0ef2d99a3764c13de3996e3c2ade4" + }, + { + "path": "desktop/pyproject.toml", + "git_blob": "dada23f8692dfda4c7c07fc012608844c7f41ab9", + "bytes": 552, + "sha256": "3646f83dcc0764b3c8cb198b98b03201dc47808bb80bfec4837e329e47bd012f" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/__init__.py", + "git_blob": "67a4fb257b771af771edb4010e573ceeab86a51f", + "bytes": 497, + "sha256": "14cfe6dccd33a0bda74fac3c9339e1a37a3538b2110a8ae6e307801b776eb43a" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/discover.py", + "git_blob": "d5c4fa7e06ac6e9139ebfc78fade90a3df5e451a", + "bytes": 4023, + "sha256": "344ee5d7cb0f5e95ac7524a0c1141b0a293bb9445e2bd4789c6736f39cfcb90d" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/eval/__init__.py", + "git_blob": "140fcb2784c4b73ddf69d21ddccfdcc8191cc0aa", + "bytes": 154, + "sha256": "54661df9ed7d7e0d4b1c2ab5941f107ceb608e4fdfaff810014ef5fad1431fe1" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/eval/job.py", + "git_blob": "95d40a6c28aabcdc311c18e3e195627f29ceb1a7", + "bytes": 3984, + "sha256": "a7f2a43c2fc3723c471e42a5532465dc5cfa44d4411c6cf581bba6910603fc57" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/__init__.py", + "git_blob": "e52dc3839105744e19193f8fc8067b818389a20b", + "bytes": 66, + "sha256": "3cdd6c626b6da12b8df56d8ddf35fca27c0a744865965ec01dd89d47da476fa1" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/emg.py", + "git_blob": "7f7536500a63ddc8b06774b8da65df8d56cd4f2b", + "bytes": 3072, + "sha256": "11f8f8350464b7c7c079353ca649b4c4aad2580ef8d355fe741c025c262b168e" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/imu.py", + "git_blob": "0ee47b3d579e4c3732634958dda21ae724beca9e", + "bytes": 2605, + "sha256": "246bfd1cc3ce72afa0680537062b6795e22b8a06ba6301503d7489a4440c6849" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/io.py", + "git_blob": "b998063a5036b73a67b773f70c193b1f9827c248", + "bytes": 1409, + "sha256": "c677d209292cca790ccdf1a64ba834f71a078ccce31ea57452e67ece358822ca" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/numeric_batch.py", + "git_blob": "77f19ccb048c93c0f4fca460eef0502180b37717", + "bytes": 4030, + "sha256": "ecdeb88ca4dd093b973294a53954e9fa0e5d6b4b908225a52d097ef70c7d2154" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/radar_doppler.py", + "git_blob": "ee20f7314cb1af4512901d6009f73e3dddf9025c", + "bytes": 2289, + "sha256": "cffc0ecbb8053fbc2244850c1927469366f4ae93b5439e4d194de2065877fa5c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/radar_frame.py", + "git_blob": "e798dee0fb72dd261b504a99ac76f815515dda9e", + "bytes": 3323, + "sha256": "f85c5fe5e2db68606f68e36a42a0c8f323086f0b1e7f233c0ddefa24cdccb443" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/features/video_qc.py", + "git_blob": "fa73c80d39a0d699f80d7e877b37167cf8b48b6a", + "bytes": 1766, + "sha256": "0e25c50e01fc2da47bc7b510d68ba3e72aba33d3e1c79c57b727f5c55c723e27" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/grids.py", + "git_blob": "2e03f79d9317d2d97b721321130a9a5e6212b111", + "bytes": 1007, + "sha256": "936c5404783145f7a2bc4c13df22d3b85612bcb227115bba74f0b78a11c0c483" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/jobs.py", + "git_blob": "7badee5cdf5a4b30a283e0dcbb2c5d85fb787489", + "bytes": 19627, + "sha256": "e7e9dda44eb014d18192563f1e2c0ae78cece850fbc853b0be3919daaf5ee276" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/__init__.py", + "git_blob": "aaf360b8a0085f89b95cd976857f0933596098a7", + "bytes": 178, + "sha256": "50a0f7fd39648abf269fc549d2c17eb48b1dc9add10ebdb76edc1935d6f80160" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/compute.py", + "git_blob": "928751e9c861e2b0da298214269e57111f492865", + "bytes": 6899, + "sha256": "6e3ca19bfda0c02877f5d778f0c1191b5aebad605373732ef182bd714dd7f086" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/job.py", + "git_blob": "fb8be113d8699427072f6dbcdae222a37738ac18", + "bytes": 4523, + "sha256": "d676e84f54aa1ae2b0f998c2cb37c4e02541c1fd0e3464e38e9865c0049a7239" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/kinematics/registry.py", + "git_blob": "a28cfd708c90552401fb0b3157c60f713a06e14f", + "bytes": 1155, + "sha256": "1e53fb9da4c6a2743bc1a3f0e687d94599cf995d33f2a2555e0ce5ebc3966d48" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/__init__.py", + "git_blob": "eb6fae21d4bb79055f8d1af1528e846020f21459", + "bytes": 361, + "sha256": "2d51c509baf3c0b5c33360637d12e5ce3c7507a859e4f37030f2c3d711ef0b3d" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/base.py", + "git_blob": "941a6aa3cea6777f90534ea634cccf8fdd319a3f", + "bytes": 2461, + "sha256": "696093b31f22d2bef32fc2962c7a11249a590a0b4d776c40cef4edcbc1e48a97" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/emg.py", + "git_blob": "c35d22af7bdeea570e6ae45a713428627e90894c", + "bytes": 3089, + "sha256": "86eb7114be689cdbd2edd76affa2994e7278714916692a35381abd02ba9d599a" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/imu.py", + "git_blob": "8823f04bd089789ca4cbff6602154bf066d4161d", + "bytes": 2773, + "sha256": "5ea4747145bf5588974dfd72c834766436c5a2bc0d58d34ace0f8ef403b310d6" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/mcap_iter.py", + "git_blob": "b61ca0a914e4d3909790839774327aa5824c1b71", + "bytes": 1196, + "sha256": "03a418e7689840e378665aac92c42769dd14ba2c88a821a5cbf0cee80766540c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/numeric_batch.py", + "git_blob": "668e5397d6a603d8665fe639b3218128bbda72c2", + "bytes": 7139, + "sha256": "7c84c0425c1b9b821df711f4c40ea89ac13f267dbe6472922eb41a9263e4835c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/radar_doppler.py", + "git_blob": "fc87bfb7fbbeb98ad8d5d11b3438b2d04882de6c", + "bytes": 1539, + "sha256": "4942d08eb47229839e339ce7f2f8a64aee7e5fab44bac77029fcd7a3e3e490c1" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/radar_frame.py", + "git_blob": "a44af5392ba2b5b8b64de685f42772b141f1b8b1", + "bytes": 1828, + "sha256": "d071f9d95b371798974698fd0caa1fc4c865a85fb772232fd43e7227b15fad2b" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/loaders/video.py", + "git_blob": "6a192cd5999b45df08c666b9dad21dc29cf91824", + "bytes": 2200, + "sha256": "3c3e873ab641904a39ca649dac39072f11948031d068cc21ee459e996d1fc185" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/ml_bundle/__init__.py", + "git_blob": "619d634ebf6fcc82a7871ad9c463660a24fd65ae", + "bytes": 179, + "sha256": "e785a2e3bf65852018d811b38ecbaf6ff9c479648025789145218809dd50d8a1" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/ml_bundle/job.py", + "git_blob": "59c2e4df46aa041e48aaf7184a3dd0ba345aff6d", + "bytes": 9419, + "sha256": "c14c74760e20c818ce5e2428d0b03a8a949899b0bba6c46e37fa8fd797631c75" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pipeline.py", + "git_blob": "8113ab4cb51678a122bbb702a23f2200c9333233", + "bytes": 5262, + "sha256": "e8c0152040ba5b5f3f37ac53fb5188bac9dd9aaf0d5816d6a718be505c20898c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/modality.py", + "git_blob": "1de343cc2e11e663501ba190441325d5637d1492", + "bytes": 2419, + "sha256": "bc3aa15ee79d50280a6c9d6aa144fe0519f85dd2c74a0cfa99323f7d57ecd28d" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/style.py", + "git_blob": "3725e840e5eb046accea79d4b6376f902392dac8", + "bytes": 1249, + "sha256": "231e7b1c998f4349d5859295007235ffd41848f12fbb7819193bec9630cd3942" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plots/sync_dashboard.py", + "git_blob": "828204e998a46b9571b3a2b3ba08acd9fc6caa31", + "bytes": 1149, + "sha256": "6f9e0c64193688eb841565729b9d1e9a64136779e892419acabdc81591afd3d5" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/__init__.py", + "git_blob": "39c9c93eab1f5abf65ea73299c34b05ec184dd63", + "bytes": 225, + "sha256": "c511d4b9cd1cda042b781b06fbb02d2d99004de214735d6daeb459d6e41381fe" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/dummy.py", + "git_blob": "0152651c271234bf38252bed51efda3a3fc19c0f", + "bytes": 1618, + "sha256": "facf059d247bca44f2697383e12cc1296b1d1d12bede1196f4a52a1352d60495" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/handlers.py", + "git_blob": "03c8589064dfc4c6cfec6e4d00b7f46b10014414", + "bytes": 10646, + "sha256": "9be2e1820529b94e54d06790d53aa94cf658f982efb4063c6b64f9d07acc4b2e" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/manifest.yaml", + "git_blob": "0628968ee3965170b486306f974c81dd4eb84a53", + "bytes": 3876, + "sha256": "1efe3ee2d9eeeeac03c2c03c582edf0119c9abd6d214dfdca3d827fa10a5c048" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/numeric.py", + "git_blob": "d8adbc1d90dbfdeac0cd9179c95f027532c1a5d4", + "bytes": 3390, + "sha256": "75b55cb453095ad5470ce2532b65d3dce771e6a2f8ad1e46a538b4291fa4cf93" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/plugins/registry.py", + "git_blob": "3c582e1ab0de2b22956ac47fb628227eacdd1faf", + "bytes": 5389, + "sha256": "33a4d07600db8b116fbd46b67492f62129df513df5b66a2c455dced0b2a9dc69" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pose/__init__.py", + "git_blob": "108be2956adfed6328f397d88a3b61ebada0ac48", + "bytes": 156, + "sha256": "d58a03cae86259b2cb0ecd0a5ce2347c6824f14cfea6871c94d76acc3541a380" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/pose/job.py", + "git_blob": "1a1a3f2436b0ac8decc551f84e76fa6c4c6e602d", + "bytes": 6262, + "sha256": "1f4c44f443c07e22e8c9ca877232c6780c4b1da7834d5565b82cf547b2f4c439" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/qc.py", + "git_blob": "530b86af1247599c127e2d0c3fa5e4d7d12169f6", + "bytes": 9187, + "sha256": "f24e0593a3723311d41054aef40b56c4bb46d4f3ba5ef4b01afcae3a6cc4440a" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/report_html.py", + "git_blob": "bb8032024cfce30c6fe9a2bd2c13b0d2cbc2d102", + "bytes": 4716, + "sha256": "f2c89c7faf6e4edc265540140272396b4195eb5aed9edf05c4912aac74286f03" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/types.py", + "git_blob": "2adf26816e0ef9e84e6763cf8bbff69d64697949", + "bytes": 3428, + "sha256": "e7996d02483f69265a2ef2ec0b28078c86f4f479daa53e38faf8b4a62645d02c" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/version.py", + "git_blob": "d04b8cc1dd9271ca3ccf836d97436d9a961417c6", + "bytes": 62, + "sha256": "9e25143344b110699f68b6acdbef49576fc91c2cbda34956d7e2cb85bbbc4ae3" + }, + { + "path": "libs/python/capture_analysis/capture_analysis/windows.py", + "git_blob": "80bea6bd69365a48c5b204c26d054b8ae179437a", + "bytes": 5618, + "sha256": "af40235d55341d2a6b11d7f67a0195779676301fa822b2bd05240d138ee28c50" + }, + { + "path": "libs/python/capture_analysis/pyproject.toml", + "git_blob": "6db8b1158b14da660128d7ac0ceacb45b8eb9924", + "bytes": 677, + "sha256": "84cd96465e48439bdd81f5fa126fea5da11ee7587b488bfaaa67a4cd8f760c75" + }, + { + "path": "libs/python/capture_protocol/LICENSE", + "git_blob": "d645695673349e3947e8e5ae42332d0ac3164cd7", + "bytes": 11358, + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + { + "path": "libs/python/capture_protocol/NOTICE", + "git_blob": "7f9ac0678aa56452f06e6e5f3badc9a873e2008a", + "bytes": 124, + "sha256": "3efb470f58c900a58deaef889527e074206274b0fd5fb0e2e62613c093064307" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/__init__.py", + "git_blob": "0e7ab2cf8689d3adbc689c283e8a23d12607b2d0", + "bytes": 698, + "sha256": "556f474a3d740adc03c40426acde432ab7a394b947f8268bd90eecc7832dff8a" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/codec.py", + "git_blob": "3034065efca2c52e34c3e67e147bdda526d2c8db", + "bytes": 7011, + "sha256": "f6c09246a7b165358835e51b99b1508e68d840f4bdbd54b5fb72db33d4912712" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/config_schema.py", + "git_blob": "c9b4a694e620e5597d338230fcb0f25ea3a757f6", + "bytes": 8444, + "sha256": "00d855895faec7d674cdb8e4da1ddc687888c9e9863f91d4950d24d9fb815e6e" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/constants.py", + "git_blob": "2542cda6bdb6a83d4334336f34d92f80040bc4a0", + "bytes": 486, + "sha256": "7f187edf873cd13f55bc09ff7972785797eb488d74dd5befcb395fc928a71d72" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/control_client.py", + "git_blob": "45e1c4b535ece8d7178cd6b32ab1affcc9e73e92", + "bytes": 20823, + "sha256": "68de412465b2eaa04886a2bb4566aa0595c898df7d7e782b3031b8ba919db7fa" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/framing.py", + "git_blob": "9dd5021b815b31ab02eaaa814210525ebb543862", + "bytes": 2884, + "sha256": "3ff7c7284d9907a2ad516c83fab383a4151996da3f2d5a1d27e24d7c7575d92e" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/__init__.py", + "git_blob": "16ae7d90a122b4973139c563ac0f72efa061b1de", + "bytes": 90, + "sha256": "1fac8216894ce1a1b5362de3b59398fbd78f005a59636aea9f074951bed5c1d7" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/__init__.py", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/__init__.py", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/arrays_pb2.py", + "git_blob": "a29ed506c4dd33f697ba74d13b6e8a9c945c6b6d", + "bytes": 2876, + "sha256": "6355750076724275e49f9a5faec383b2be92c0336ed58805a88954964bd13b86" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/common_pb2.py", + "git_blob": "66031212a0da44800dcc671b0d4bf0cd39e71f06", + "bytes": 9746, + "sha256": "6736e3b86b3c8749d34065794da1c880772ce69e2f248fdd2febd003f083bbd3" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/control_pb2.py", + "git_blob": "0597489cf8609a76e2094270965039da9b739ca3", + "bytes": 20028, + "sha256": "f2eea386aebf830ec47fa7379e6fb0493e0a199efecc7b90974bc8bb8c8b96b6" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/__init__.py", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/emg_batch_pb2.py", + "git_blob": "d8495ebeb8ab140824eaa5412be0779cf929ec6a", + "bytes": 1624, + "sha256": "1db5ef51143a546072e34cc7be7b263db996fa5f4d0d71606b230cb75b531a14" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/imu_frame_pb2.py", + "git_blob": "54bbf93dc638cdab95f49744ea7e0b43fefad374", + "bytes": 2222, + "sha256": "4a2048d2a737362bf26b99166e95c457d1492fcfba8848c894fe4d2748ff9f51" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/numeric_batch_pb2.py", + "git_blob": "beedaaae054bfb083af3642c96ca7c64af14cc8d", + "bytes": 1454, + "sha256": "a087cc019b9849f4ef47bcdf4c789a7da90d443240b7bef97c832bb23c1d4e24" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/radar_doppler_pb2.py", + "git_blob": "ad8fe84317d2f4049682f70bead19f90c6932457", + "bytes": 1773, + "sha256": "d1b85358aba0c2f4fc1745218463e9951224322604b18b068a2195359dcf790e" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/radar_frame_pb2.py", + "git_blob": "cef636d7b030b037b23331eec9a86f3b152bc358", + "bytes": 1729, + "sha256": "995ddbbb0aa614afb15088cf039c741421c33ea3e3e963ef1a7361b24754b862" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/data/video_timing_pb2.py", + "git_blob": "17937a141a9a2d81858cf52d74bc4705afc940b7", + "bytes": 1722, + "sha256": "002a79858ccd2d7763769a1fe1be6a16a7f6b8727d15f952d191bcd2240ba5ef" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/events_pb2.py", + "git_blob": "030bd4a90be609403e7709605607d8d5b993776e", + "bytes": 5480, + "sha256": "72951a468b0480e7fefc4fd3f9b4caac5fda0abdadf4ffcca92d4f19286429ce" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/health_pb2.py", + "git_blob": "b27bd32ec488168871ca2342062eb576d56a9e8e", + "bytes": 5898, + "sha256": "e1e0baa7073a9886e4d982d4f00020b490bfd46c32b1b4df129fd0477c1f5e61" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/presets_pb2.py", + "git_blob": "d20925410185e5cf52bbc56e438534c1c5ff1102", + "bytes": 2066, + "sha256": "d27336594b548f2e6e7ae212fe6de198e6e699c62a5f27752f691d7928ccb27b" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/preview_pb2.py", + "git_blob": "cb04387df1614a8b9d9755a702129bbbb8d6374e", + "bytes": 5333, + "sha256": "c992e91b9aef0aa0ec8d595eba2f7079889264d9e4de120b623afd1d8702c695" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/project_pb2.py", + "git_blob": "a8e71f0a426858cc679cb87ce31d1379e70a2817", + "bytes": 3355, + "sha256": "983bc5715147297cdcecca343b9a450f2095fcc1e895859cc3c52a3213d933f5" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/source_pb2.py", + "git_blob": "b72752efedc743d236713e51283dce923a526f55", + "bytes": 8053, + "sha256": "d15b443f27c910c0e809af19fed81d9c1a75f7112501df85877bf4bf9bc4f7a8" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/storage_pb2.py", + "git_blob": "4dd1b48ab16900c5c3e88d9788cebf83ee93cc5a", + "bytes": 5487, + "sha256": "f7a7b8903af9bfc2d2a419622c86cc057aed2a898949e4261475a7ac61222474" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/generated/capture/v1/worker_pb2.py", + "git_blob": "7f3a4fc372384523638853f4bd458f49b664ba70", + "bytes": 11165, + "sha256": "112e832172913024c6fad128a9a9559bbcd14b18de06b1f2a3161ac380258dc0" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/handshake.py", + "git_blob": "9386e73b3c1eecb683d9d0ca98ad415268e307af", + "bytes": 4763, + "sha256": "63f740c992edf8812f666b79f9cd866d9ea33e65e5b310a5ebda2f5ef98ac115" + }, + { + "path": "libs/python/capture_protocol/capture_protocol/structured_log.py", + "git_blob": "fc9c97b288280f4473c6b3c5b5e6ff07332fad49", + "bytes": 4657, + "sha256": "3d7883833286ecc004248294badcc0c66e44a57ecb7844ef281828d797b3c4fc" + }, + { + "path": "libs/python/capture_protocol/pyproject.toml", + "git_blob": "fa71ca45874d34076208507180c69c7a0e38fa76", + "bytes": 355, + "sha256": "61b2e33b2de2a153fb994144f532402c1b6b8ed02afb627ba0a15239e726ca71" + }, + { + "path": "libs/python/capture_session/capture_session/__init__.py", + "git_blob": "894e3c152a98b6e804de90122572afbcd929b3da", + "bytes": 2412, + "sha256": "da530f86c0d1d584862868ddba9f7087ccf5dfbddd64dd1e577337ecfd776419" + }, + { + "path": "libs/python/capture_session/capture_session/app_paths.py", + "git_blob": "46332cea7c62dd44247b219937ae6c8fbc747017", + "bytes": 561, + "sha256": "363e4522240e2356cac7492589cb207a798bc1af6031139bd1fa94890f1c4bfd" + }, + { + "path": "libs/python/capture_session/capture_session/package_reader.py", + "git_blob": "91fbf913c5af8489968425d7ceac51c04233d3e0", + "bytes": 6331, + "sha256": "9a1d9e6e7d24341a083cee602af9538413e948f3369b22660e484356e3d34eb1" + }, + { + "path": "libs/python/capture_session/capture_session/registry.py", + "git_blob": "c1d7799e1d2099424221b2f4af216a43a972c67a", + "bytes": 13989, + "sha256": "809b26ce8d8efc0559a3854cf85ea74b4e486fcd77d253ebfa76bade64b0a8d1" + }, + { + "path": "libs/python/capture_session/capture_session/settings_store.py", + "git_blob": "41b99cdaa78011d3d9b753c3131f32c72af9699f", + "bytes": 4622, + "sha256": "7719524a1f106cc54befcd21088810f9ec28f0160c8e88f60c374e1545fdb98d" + }, + { + "path": "libs/python/capture_session/pyproject.toml", + "git_blob": "c83450d780e97e5bd90feb48cef140917b6e47ff", + "bytes": 389, + "sha256": "3484887da96d4a2f32de8471b537d849f077b195c729ff0cc29307681e8d4895" + }, + { + "path": "libs/python/capture_worker/LICENSE", + "git_blob": "d645695673349e3947e8e5ae42332d0ac3164cd7", + "bytes": 11358, + "sha256": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30" + }, + { + "path": "libs/python/capture_worker/NOTICE", + "git_blob": "d74f1cbf89d4c89f70b3e75ab71cfadea8b7128f", + "bytes": 142, + "sha256": "2a7e69c4c7cd4e93a5cc9e9f984873a2d1276f465b91b10c71b951ebcfb2c588" + }, + { + "path": "libs/python/capture_worker/capture_worker/__init__.py", + "git_blob": "4bf1fc6b13bc4f5daab79d937ea89cf6c120cce3", + "bytes": 503, + "sha256": "c7ba88e956df8460002637eb3d8678a4c7217e680a388f833a22f073dc80f8fd" + }, + { + "path": "libs/python/capture_worker/capture_worker/__main__.py", + "git_blob": "a1047121f4173802074eeb66e5dcaf6c542c29c1", + "bytes": 150, + "sha256": "216422b76731bc985daa5fb0efe55a9d5ce600aa7e6081fa3df0c03afb6a893e" + }, + { + "path": "libs/python/capture_worker/capture_worker/cli.py", + "git_blob": "eb2d869f951f0205085b074d067282990657b5a0", + "bytes": 1818, + "sha256": "8a16c4cae0ffd11d4f9cd5d168f6abf1c6f9a4b5100e8edd18a29ce7d44d3f03" + }, + { + "path": "libs/python/capture_worker/capture_worker/preview.py", + "git_blob": "c47abe8a118ea022931843bde802132548194eef", + "bytes": 3202, + "sha256": "38b483dc06c9215b73e4c56c222fe563957180a5be58761a2c6dd4ea200b8e31" + }, + { + "path": "libs/python/capture_worker/capture_worker/transport.py", + "git_blob": "2e5e159bee3a0b5aa69bf90f62906feeffe23c8c", + "bytes": 5033, + "sha256": "020414c74bd08ec510e88da8c2f8b9ec5091a19cb585b4c54d2656b4bf300d35" + }, + { + "path": "libs/python/capture_worker/capture_worker/worker.py", + "git_blob": "d5ed2999fbb958116d73a8fa6319356d8b7d751a", + "bytes": 23439, + "sha256": "19a0dfd16a65479de884d4359a3d65f1bc127d8a6d4b44b93c6251757510de68" + }, + { + "path": "libs/python/capture_worker/capture_worker/writer.py", + "git_blob": "b3d194cc71dfa0d21884936a6ed5f7bdc95b3eb4", + "bytes": 6196, + "sha256": "b9e3b21ac26f2160da582a3f566a278dc4088c5a8b121d9b4e74f8d8c16cf96f" + }, + { + "path": "libs/python/capture_worker/pyproject.toml", + "git_blob": "5d79642edc9c1809fda636d5dcd78ad33e67abcc", + "bytes": 487, + "sha256": "0cba218b59a756185fedf72fb3a3307d1d9cb9218b6189ea92972d3cec139a46" + }, + { + "path": "pyproject.toml", + "git_blob": "52491c6beebc4b17983fc66bb8765154c33cf6d8", + "bytes": 1233, + "sha256": "0cb8de1ab3dfbfed84ff16b35f3c89c6440180183ee5851d5d80da83622e53d0" + }, + { + "path": "tests/analysis/test_numeric_batch_pipeline.py", + "git_blob": "9485adb27d02ab88e65d87576a06b86869a0360b", + "bytes": 19230, + "sha256": "43369bd0fea48d2c8b7dee1d8128b3bb131b508b7b0a14512fc457fcfdb0ba3c" + }, + { + "path": "tests/conftest.py", + "git_blob": "ad9b61fd8e9c1c3d74f91710d4e82dd7d899e6b4", + "bytes": 1773, + "sha256": "f669618fad17e906c91df7a1e9393fc7a54f458c6d62a4385436ba2622beca0e" + }, + { + "path": "tests/fixtures/mini_session/events/annotations.json", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + { + "path": "tests/fixtures/mini_session/events/checkpoints.json", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + { + "path": "tests/fixtures/mini_session/events/sync_anchors.json", + "git_blob": "fe51488c7066f6687ef680d6bfaa4f7768ef205c", + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + { + "path": "tests/fixtures/mini_session/integrity.json", + "git_blob": "d10093b866427fcaed78a85e60e600d8657a86a7", + "bytes": 227, + "sha256": "af5d9bacd3eace7e831d48dee83eb5d9f578f4f4819d92218c4b55b0cb3ed556" + }, + { + "path": "tests/fixtures/mini_session/manifest.json", + "git_blob": "800dab5b41774bc043ebdee4714195770e75229b", + "bytes": 235, + "sha256": "c5254d3e4c0bc6a0ecaef124dc12d88117d647928a8e1725b71429097438d380" + }, + { + "path": "tests/fixtures/mini_session/processing/.gitkeep", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/health/gaps.jsonl", + "git_blob": "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/source.json", + "git_blob": "9528c95289b4b1b49d11d412b5ab2e3d019b4066", + "bytes": 112, + "sha256": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap", + "git_blob": "320ce3607fadf57d05cf506987d045cf5b62ad9f", + "bytes": 28, + "sha256": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.emg.main/streams/sim.emg.main.batch/stream.json", + "git_blob": "12c4db8831572fc4ab3db9ba5f784fa236078e5f", + "bytes": 216, + "sha256": "8f8c02b89fd93e55643151e5222488e1174dd97a6b7a74f3ae5da8215b4d68e1" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/source.json", + "git_blob": "fcc248c52b8319f5e7fd0067763b74640f0040dd", + "bytes": 118, + "sha256": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap", + "git_blob": "320ce3607fadf57d05cf506987d045cf5b62ad9f", + "bytes": 28, + "sha256": "3c4d91b3bf5d48dcf54a598fff5b1b4ee42260b756d6f5df3986da496c6a9649" + }, + { + "path": "tests/fixtures/mini_session/sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json", + "git_blob": "9c634d4af594372063fcc612331ba338ae95f8c9", + "bytes": 219, + "sha256": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d" + }, + { + "path": "tests/ui/test_analysis_history.py", + "git_blob": "f013473f750b515a8305e2f7f8426b6520e26a65", + "bytes": 10465, + "sha256": "48175547922125c308fa49bbb84149e3dac8903902e7cc64fa7c15b4ca40eccd" + }, + { + "path": "workers/python_host/capture_sim/__init__.py", + "git_blob": "2646a1792544ac97cba76fd7d7246c313604351e", + "bytes": 259, + "sha256": "a3c8506a26d20b0b10cd55f00b019b7ddc1e2d4cb5cffd5c155d70ef338d21ae" + }, + { + "path": "workers/python_host/capture_sim/advertise.py", + "git_blob": "c93044ce53b7a38d2e7db9fcbad83174b394ffd2", + "bytes": 15205, + "sha256": "6a41dafed67d08d4e3829c053dc5a2767ae28293d63733b4b4ae187a8d4a94b9" + } + ], + "scope": "Exact Python/fixture slice for one native scope/history composition journey; no Windows MainWindow or complete suite claim." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/37443-candidate.log b/docs/evidence/analysis-history-401c5d17da79/independent/37443-candidate.log new file mode 100644 index 00000000..d38a4b73 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/37443-candidate.log @@ -0,0 +1,18 @@ +This plugin does not support propagateSizeHints() +candidate: fresh screen reopens real prior A result into gallery and inspector: True +candidate: package switch clears prior package result and launch targets: True +candidate: same basename in package B resolves only B saved figures and metadata: True +candidate: malformed-manifest is visibly unavailable: True +This plugin does not support propagateSizeHints() +candidate: malformed-manifest refuses opening without replacing valid B view: True +candidate: missing-manifest is visibly unavailable: True +candidate: missing-manifest refuses opening without replacing valid B view: True +candidate: foreign-session is visibly unavailable: True +candidate: foreign-session refuses opening without replacing valid B view: True +candidate: foreign-directory is visibly unavailable: True +candidate: foreign-directory refuses opening without replacing valid B view: True +candidate: unavailable-row inspection leaves all saved bytes unchanged: True +candidate: Open revalidates cached row when manifest disappears: True +candidate: failed Open preserves every persisted byte after controlled fixture rename: True +This plugin does not support propagateSizeHints() +candidate: actual QThread QC result exists before deferred delivery: True diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/37443-manual-stall-receipt.json b/docs/evidence/analysis-history-401c5d17da79/independent/37443-manual-stall-receipt.json new file mode 100644 index 00000000..3bbe3755 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/37443-manual-stall-receipt.json @@ -0,0 +1,10 @@ +{ + "schema": "capturesuite.history.receiving.manual-loop-stall.v1", + "candidate": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "method_sha256": "b46094d3d823145aa07aa088371c6a63343ee7c5d8a06b254c6a4669f8c52da8", + "last_completed_assertion": "actual QThread QC result exists before deferred delivery", + "assertions_completed": 15, + "outcome": "Manual processEvents/QTest.qWait did not return to Python after release. Receiver process was stopped with Ctrl-C through its exact session; exit130. This is a non-accepting harness outcome, not a claimed native-application failure.", + "source_change": "history refresh moved out of thread cleanup, worker/cleanup AST match canonical baseline", + "log_sha256": "3e4b3290f4d02af0cf1a6461560532dffcfb8cea4c5d5349da1d49113ba48e30" +} diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/baseline-receipt.json b/docs/evidence/analysis-history-401c5d17da79/independent/baseline-receipt.json new file mode 100644 index 00000000..b668c5fd --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/baseline-receipt.json @@ -0,0 +1,162 @@ +{ + "checks": [ + { + "evidence": { + "history_loaded_job_id": null, + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": false, + "open_report_enabled": false, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-b.mmsession", + "png_count": 2, + "sync_title": "receiving-a-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + }, + "name": "baseline reproduces stale A view after switching to B", + "pass": true + }, + { + "evidence": { + "job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/late-baseline-actual-qc", + "status": "completed" + }, + "name": "actual QThread QC result exists before deferred delivery", + "pass": true + }, + { + "evidence": { + "history_loaded_job_id": null, + "inspector": "job_id=late-baseline-actual-qc\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/late-baseline-actual-qc", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/late-baseline-actual-qc", + "linked_plot_count": 0, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-b.mmsession", + "png_count": 0, + "sync_title": "Sync dashboard", + "tabs": [ + "Sync" + ] + }, + "name": "baseline reproduces foreign binding after late real completion", + "pass": true + }, + { + "evidence": null, + "name": "delivery and reopening perform no persisted writes", + "pass": true + }, + { + "evidence": null, + "name": "all captured raw package bytes remain unchanged", + "pass": true + }, + { + "evidence": [], + "name": "no Qt error dialogs or worker failures occurred", + "pass": true + } + ], + "dialog_errors": [], + "free_bytes_after": 21540864, + "harness_sha256": "a5af6de29e75e3870121a7f03b1f3675f31f34c8615eb6ca6b7ecff560c838ce", + "mode": "baseline", + "pyside6": "6.11.2", + "python": "3.12.14 (main, Aug 25 2026, 14:00:49) [Clang 22.1.3 ]", + "qt_platform": "offscreen", + "result": "expected baseline defects reproduced", + "screens": { + "after_package_switch": { + "history_loaded_job_id": null, + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": false, + "open_report_enabled": false, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-b.mmsession", + "png_count": 2, + "sync_title": "receiving-a-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + }, + "initial_a": { + "history_loaded_job_id": null, + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": false, + "open_report_enabled": false, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession", + "png_count": 2, + "sync_title": "receiving-a-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + }, + "late_after_delivery": { + "history_loaded_job_id": null, + "inspector": "job_id=late-baseline-actual-qc\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/late-baseline-actual-qc", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/late-baseline-actual-qc", + "linked_plot_count": 0, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-b.mmsession", + "png_count": 0, + "sync_title": "Sync dashboard", + "tabs": [ + "Sync" + ] + }, + "late_before_delivery": { + "history_loaded_job_id": null, + "inspector": "No job loaded", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 0, + "open_folder_enabled": false, + "open_report_enabled": false, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-b.mmsession", + "png_count": 0, + "sync_title": "Sync dashboard", + "tabs": [ + "Sync" + ] + } + }, + "screenshot": { + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/baseline-qt.png", + "sha256": "9709a37b5abd159c5eafb7d58b8fb096bda7926fe109ec1f11eb8d50a47ade0f" + }, + "source_commit": "72c15d6b623e217291a824e4e4808a385df896a9", + "source_imports": { + "capture_analysis": { + "path": "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/__init__.py", + "sha256": "14cfe6dccd33a0bda74fac3c9339e1a37a3538b2110a8ae6e307801b776eb43a" + }, + "capture_analysis.jobs": { + "path": "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/jobs.py", + "sha256": "e7e9dda44eb014d18192563f1e2c0ae78cece850fbc853b0be3919daaf5ee276" + }, + "capture_desktop.screen_analysis": { + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/pins/baseline-screen_analysis.py", + "sha256": "1437b02b942f44378870540f12c5494d08693329abb5d00ca64c0c264f57633e" + }, + "capture_desktop.state": { + "path": "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/state.py", + "sha256": "97fc98498f4553fc7f052d0dc4db992cf2fc136ba7c4405cd275bd156c74e314" + }, + "capture_desktop.widgets_analysis_plots": { + "path": "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/widgets_analysis_plots.py", + "sha256": "85c73f881ee7d60ef2f868f7ff73fc57c0a4ef99a717f7f5015534db23e1ab86" + } + } +} diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/baseline.log b/docs/evidence/analysis-history-401c5d17da79/independent/baseline.log new file mode 100644 index 00000000..1af6374c --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/baseline.log @@ -0,0 +1,10 @@ +This plugin does not support propagateSizeHints() +This plugin does not support propagateSizeHints() +baseline: baseline reproduces stale A view after switching to B: True +This plugin does not support propagateSizeHints() +baseline: actual QThread QC result exists before deferred delivery: True +baseline: baseline reproduces foreign binding after late real completion: True +baseline: delivery and reopening perform no persisted writes: True +baseline: all captured raw package bytes remain unchanged: True +baseline: no Qt error dialogs or worker failures occurred: True +{"mode": "baseline", "result": "expected baseline defects reproduced", "checks": 6, "free_bytes": 21540864} diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-candidate.log b/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-candidate.log new file mode 100644 index 00000000..fd4b850c --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-candidate.log @@ -0,0 +1,38 @@ +This plugin does not support propagateSizeHints() +candidate: fresh screen reopens real prior A result into gallery and inspector: True +candidate: package switch clears prior package result and launch targets: True +candidate: same basename in package B resolves only B saved figures and metadata: True +candidate: malformed-manifest is visibly unavailable: True +This plugin does not support propagateSizeHints() +candidate: malformed-manifest refuses opening without replacing valid B view: True +candidate: missing-manifest is visibly unavailable: True +candidate: missing-manifest refuses opening without replacing valid B view: True +candidate: foreign-session is visibly unavailable: True +candidate: foreign-session refuses opening without replacing valid B view: True +candidate: foreign-directory is visibly unavailable: True +candidate: foreign-directory refuses opening without replacing valid B view: True +candidate: unavailable-row inspection leaves all saved bytes unchanged: True +candidate: Open revalidates cached row when manifest disappears: True +candidate: failed Open preserves every persisted byte after controlled fixture rename: True +This plugin does not support propagateSizeHints() +candidate: actual QThread QC result exists before deferred delivery: True +Fatal Python error: Segmentation fault + +Current thread 0x00007f68537fe6c0 (most recent call first): + + +Thread 0x00007f6889b6f740 (most recent call first): + File "", line 468 in _joinrealpath + File "", line 424 in realpath + File "/opt/codex/runtimes/codex-primary-runtime/dependencies/python/lib/python3.12/pathlib.py", line 1240 in resolve + File "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/analysis_history.py", line 41 in _jobs_root + File "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/analysis_history.py", line 124 in list_saved_jobs + File "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/widgets_analysis_history.py", line 129 in refresh + File "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/screen_analysis.py", line 439 in _on_thread_finished + File "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/methods/receive_history.py", line 224 in pump + File "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/methods/receive_history.py", line 231 in until + File "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/methods/receive_history.py", line 373 in receive + File "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/methods/receive_history.py", line 433 in main + File "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/methods/receive_history.py", line 437 in + +Extension modules: numpy._core._multiarray_umath, numpy.linalg._umath_linalg, PIL._imaging, kiwisolver._cext, pyarrow.lib, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._pcg64, numpy.random._generator, numpy.random._mt19937, numpy.random._philox, numpy.random._sfc64, numpy.random.mtrand, _cyutility, pandas._libs._cyutility, pandas._libs.tslibs.ccalendar, pandas._libs.tslibs.np_datetime, pandas._libs.tslibs.dtypes, pandas._libs.tslibs.base, pandas._libs.tslibs.nattype, pandas._libs.tslibs.timezones, pandas._libs.properties, pandas._libs.tslibs.fields, pandas._libs.tslibs.timedeltas, pandas._libs.tslibs.tzconversion, pandas._libs.tslibs.timestamps, pandas._libs.tslibs.offsets, pandas._libs.tslibs.strptime, pandas._libs.tslibs.parsing, pandas._libs.tslibs.conversion, pandas._libs.tslibs.period, pandas._libs.tslibs.vectorized, pandas._libs.ops_dispatch, pandas._libs.missing, pandas._libs.hashtable, pandas._libs.algos, pandas._libs.interval, pandas._libs.lib, pyarrow._compute, pandas._libs.ops, pandas._libs.hashing, pandas._libs.arrays, pandas._libs.tslib, pandas._libs.sparse, pandas._libs.internals, pandas._libs.indexing, pandas._libs.index, pandas._libs.writers, pandas._libs.join, pandas._libs.window.aggregations, pandas._libs.window.indexers, pandas._libs.reshape, pandas._libs.groupby, pandas._libs.json, pandas._libs.parsers, pandas._libs.testing, google._upb._message, shiboken6.Shiboken, PySide6.QtCore, PySide6.QtGui, PySide6.QtWidgets, PySide6.QtTest, PySide6.QtSvg, PySide6.QtOpenGLWidgets, PySide6.QtOpenGL, scipy._cyutility, scipy._lib._ccallback_c, yaml._yaml (total: 69) diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-eventloop-receipt.json b/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-eventloop-receipt.json new file mode 100644 index 00000000..89965851 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-eventloop-receipt.json @@ -0,0 +1,74 @@ +{ + "candidate": { + "baseline": "72c15d6b623e217291a824e4e4808a385df896a9", + "commit": "c0b5530c03cce3e42a0430e5411cddf1df716e19", + "focused_tests": "7 passed in 2.61s; no skips", + "harness_notes": "Replaced QTest.qWait polling with QEventLoop plus settling cleanup after a timeout/unsafe teardown; production worker and signal wiring remain baseline bytes.", + "inputs": { + "desktop/capture_desktop/analysis_history.py": { + "bytes": 6375, + "sha256": "2e0db8cee59ef268d3c91ea0beac7d761d83a3003862841cc9d7f1782fd3543c" + }, + "desktop/capture_desktop/screen_analysis.py": { + "bytes": 16407, + "sha256": "4a2e3eaee50fba5236b5567be993582a557de6fe2c62cc0bf3f424483beefb2b" + }, + "desktop/capture_desktop/widgets_analysis_history.py": { + "bytes": 8458, + "sha256": "a3b77c87483c1412b50de7ddde1498f6bfd3968002fc3ac3bfa474a2477d9bc4" + }, + "tests/ui/test_analysis_history.py": { + "bytes": 9023, + "sha256": "eabe6a4e663307965ce00a1f9032325bfc7be6357b7a3a91b79820cafc4c0a97" + } + }, + "runtime": "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "tree": "c384c9553757fb1614405d124a5026ae49b4be71" + }, + "checks": [ + { + "detail": { + "job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/late-eventloop-actual-qc", + "status": "completed" + }, + "label": "real QC was persisted before release", + "pass": true + }, + { + "detail": null, + "label": "selected B is unbound before A completion", + "pass": true + }, + { + "detail": { + "inspector": "No job loaded", + "last_job_dir": "", + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-b.mmsession" + }, + "label": "native event loop settles without binding previous-package result", + "pass": true + }, + { + "detail": null, + "label": "completion preserves all bytes after actual job persistence", + "pass": true + }, + { + "detail": [], + "label": "no native error dialogs", + "pass": true + } + ], + "errors": [], + "events": [ + "actual QThread started in native application loop", + "selected B, released real A completion", + "native event loop accepted exact completion boundary" + ], + "loop": "QApplication.exec with QTimer; no manual processEvents or QTest.qWait", + "method_sha256": "f05476354e1d1e40478bcc4ed3e5e753bb3baa99fe1a822e3f12e15018236d7d", + "pass": true, + "process_return": 0, + "schema": "capturesuite.history.native-eventloop-control.v1", + "seconds": 0.24924598599318415 +} diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-eventloop.log b/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-eventloop.log new file mode 100644 index 00000000..aa4ce3ed --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-eventloop.log @@ -0,0 +1,7 @@ +This plugin does not support propagateSizeHints() +real QC was persisted before release True +selected B is unbound before A completion True +native event loop settles without binding previous-package result True +completion preserves all bytes after actual job persistence True +no native error dialogs True +{"pass": true, "checks": 5, "seconds": 0.24924598599318415, "code": 0} diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-failure-receipt.json b/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-failure-receipt.json new file mode 100644 index 00000000..87060a24 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/c0b5530-failure-receipt.json @@ -0,0 +1,345 @@ +{ + "archives": { + "candidate-reopened-a.png": { + "bytes": 204136, + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/c0b5530-candidate-reopened-a.png", + "sha256": "a4e78ff532b45507142b2053db0b2391994cb51f9120eeaebb5135cf76755b8c" + }, + "candidate-reopened-b.png": { + "bytes": 217136, + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/c0b5530-candidate-reopened-b.png", + "sha256": "a87a869be6e6f65ed50af9e63f386d54edcef524f3f1e44072d1f2318824d6a7" + }, + "candidate.log": { + "bytes": 4375, + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/c0b5530-candidate.log", + "sha256": "6aae6bbe36f9f7070a42910ecbbf2297a3dd222d5834cbeabbd816e4003f39b4" + }, + "eventloop-receipt.json": { + "bytes": 2679, + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/c0b5530-eventloop-receipt.json", + "sha256": "17a363b7ffee224a1f65f1eea6a61c4e83d47e8b30ae68aab07ccb2298c425d1" + }, + "eventloop.log": { + "bytes": 375, + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/c0b5530-eventloop.log", + "sha256": "42724fb02c89311d1a34d82672cbc9c9034c7ac9a376ec365c4f6c53bc01ed52" + } + }, + "assertions_completed": 15, + "candidate_commit": "c0b5530c03cce3e42a0430e5411cddf1df716e19", + "candidate_tree": "c384c9553757fb1614405d124a5026ae49b4be71", + "crash_location": "native thread has no Python frame; main thread in AnalysisScreen._on_thread_finished -> AnalysisHistory.refresh -> Path.resolve", + "fixture_files": { + "package-a.mmsession/events/annotations.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-a.mmsession/events/checkpoints.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-a.mmsession/events/sync_anchors.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-a.mmsession/integrity.json": { + "bytes": 225, + "sha256": "2fb4194b22d4b1c373f25f9ecab51d0c80e14f42a52f53293fd727ce5418f140" + }, + "package-a.mmsession/manifest.json": { + "bytes": 250, + "sha256": "6cc54886cc63fa1263a4077fec322454fdfa133a408836a75451fd77eb7c5243" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/job_manifest.json": { + "bytes": 2400, + "sha256": "bbb88191cb522d3314139b6ebcb4cd2e6b8aa6c6b7df362d0653a0a75dcba7bc" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/logs/job.log": { + "bytes": 187, + "sha256": "59f307f1af8f7e20fe908e17afdf3047f6d7eda3d04d2d7e5153f258b6377d37" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/params.json": { + "bytes": 260, + "sha256": "88f55fe8dddb0794c98f693dd21fdd7764a6bac45203e11ba52eab3ebaa40fc3" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/reports/qc.html": { + "bytes": 1629, + "sha256": "db815562d270dc133bce019f0c0791bea4e9af52fc62ce7107a41ea6a8485d20" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/reports/qc.json": { + "bytes": 1296, + "sha256": "2a1addc8accb001643f81a4b1061458f8fa27de6ffcc157fbed5ddb837c9cf27" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/job_manifest.json": { + "bytes": 2401, + "sha256": "b8e5cceef8c8cc17430606013cc72df5e779880bb77ffaedd9fa043c908fd171" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/logs/job.log": { + "bytes": 188, + "sha256": "c2b223c3686c245380c6b3788d45deb8f4a56ca9d420039af2ff598f6eb66cc1" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/params.json": { + "bytes": 261, + "sha256": "9aad1ac26d07fdbf51e882ad70c97ae15942b3057755083b0a8b063506d23fe8" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/reports/qc.html": { + "bytes": 1629, + "sha256": "db815562d270dc133bce019f0c0791bea4e9af52fc62ce7107a41ea6a8485d20" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/reports/qc.json": { + "bytes": 1296, + "sha256": "2a1addc8accb001643f81a4b1061458f8fa27de6ffcc157fbed5ddb837c9cf27" + }, + "package-a.mmsession/processing/jobs/late-eventloop-actual-qc/job_manifest.json": { + "bytes": 2401, + "sha256": "612f56635415e2ab8882b9545257b1b2cf50401bb0b3a45358e98904ac908f41" + }, + "package-a.mmsession/processing/jobs/late-eventloop-actual-qc/logs/job.log": { + "bytes": 188, + "sha256": "1fe30cd8c3f36e5370ac406741decd78802073fb793d43b6d5cba99722d346dd" + }, + "package-a.mmsession/processing/jobs/late-eventloop-actual-qc/params.json": { + "bytes": 261, + "sha256": "be905b67387880dbfa478ee1a90def66691d600c2ca2a348ef518e99bd82384f" + }, + "package-a.mmsession/processing/jobs/late-eventloop-actual-qc/reports/qc.html": { + "bytes": 1629, + "sha256": "db815562d270dc133bce019f0c0791bea4e9af52fc62ce7107a41ea6a8485d20" + }, + "package-a.mmsession/processing/jobs/late-eventloop-actual-qc/reports/qc.json": { + "bytes": 1296, + "sha256": "2a1addc8accb001643f81a4b1061458f8fa27de6ffcc157fbed5ddb837c9cf27" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/_schema.json": { + "bytes": 2880, + "sha256": "c80f7d1e05378bf2399098e9887fc463edda22e366236eab3e9b1b0526d1f0f0" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/emg/sim.emg.main/windows.csv": { + "bytes": 501, + "sha256": "0c9b8016e1295976eb10eabdb913efff752cf9936bf4a7cab1d3107a85ca97ff" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/emg/sim.emg.main/windows.parquet": { + "bytes": 7411, + "sha256": "c5d6d1727acd151ca0b1430eecb0dd0491fe2863a9f7c163d7524bfed584e60f" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/imu/sim.imu.upper/windows.csv": { + "bytes": 628, + "sha256": "62212faf4179e9050c4d7a2e3530a461c70d0e56b227138e31b0c273bb21a277" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/imu/sim.imu.upper/windows.parquet": { + "bytes": 7645, + "sha256": "ff4ca0fbfed45e13e95f73d03d8ba56ce0f8305868012ecb5101df277a449ba9" + }, + "package-a.mmsession/processing/jobs/retained-prior/figures/emg_sim.emg.main_channels.png": { + "bytes": 91869, + "sha256": "4c7a4aee76c4895cf99e38874de271e83a52c0e7389093c14a93344e9dc43853" + }, + "package-a.mmsession/processing/jobs/retained-prior/figures/imu_sim.imu.upper_accel.png": { + "bytes": 24298, + "sha256": "8cc603bf604d8925ba13be2c77e0bd8d8f8efbce9529e7d459a449fd61e6a8a4" + }, + "package-a.mmsession/processing/jobs/retained-prior/figures/sync_dashboard.png": { + "bytes": 37253, + "sha256": "bda125c256b17dbd688ec825c2a5b9b8542f346ce95209faf15efadad5c78d48" + }, + "package-a.mmsession/processing/jobs/retained-prior/figures/sync_dashboard_series.json": { + "bytes": 1963, + "sha256": "ba1181c30b0a3ab1b26b716e56bf0787f2e67aa4178cd511f0106486d04aa8e6" + }, + "package-a.mmsession/processing/jobs/retained-prior/job_manifest.json": { + "bytes": 4508, + "sha256": "21471f1ee0cae441202b4b704c6cd1359558ac1bf27f077668508eb1368ae6e7" + }, + "package-a.mmsession/processing/jobs/retained-prior/logs/job.log": { + "bytes": 179, + "sha256": "3cf99c71a0e4e3046b791ad2c04e388adfe452959b315d8dd5df6d278a5aaf63" + }, + "package-a.mmsession/processing/jobs/retained-prior/params.json": { + "bytes": 252, + "sha256": "9c0e1ab18949727f29352f1a602ae65d74db48f8453a49faa72fbc95c518b35b" + }, + "package-a.mmsession/processing/jobs/retained-prior/reports/qc.html": { + "bytes": 1629, + "sha256": "db815562d270dc133bce019f0c0791bea4e9af52fc62ce7107a41ea6a8485d20" + }, + "package-a.mmsession/processing/jobs/retained-prior/reports/qc.json": { + "bytes": 1296, + "sha256": "2a1addc8accb001643f81a4b1061458f8fa27de6ffcc157fbed5ddb837c9cf27" + }, + "package-a.mmsession/sources/sim.emg.main/health/gaps.jsonl": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "package-a.mmsession/sources/sim.emg.main/source.json": { + "bytes": 112, + "sha256": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10" + }, + "package-a.mmsession/sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap": { + "bytes": 1095, + "sha256": "6f3b9bd4ce01238f122649a1139a290ea6193893938a95f3ac61dd61a447d997" + }, + "package-a.mmsession/sources/sim.emg.main/streams/sim.emg.main.batch/stream.json": { + "bytes": 224, + "sha256": "5307697f957309eaca816fa0e20c4799c900e2598a8acf66a59928aa83b305b2" + }, + "package-a.mmsession/sources/sim.imu.upper/source.json": { + "bytes": 118, + "sha256": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8" + }, + "package-a.mmsession/sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap": { + "bytes": 1678, + "sha256": "c477a0e0865086fbb4154c977def4d93ea5fb38cc098a4862c45b21b966014c9" + }, + "package-a.mmsession/sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json": { + "bytes": 219, + "sha256": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d" + }, + "package-b.mmsession/events/annotations.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-b.mmsession/events/checkpoints.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-b.mmsession/events/sync_anchors.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-b.mmsession/integrity.json": { + "bytes": 225, + "sha256": "2fb4194b22d4b1c373f25f9ecab51d0c80e14f42a52f53293fd727ce5418f140" + }, + "package-b.mmsession/manifest.json": { + "bytes": 250, + "sha256": "26ea1e6f375028575b0c72477dddff58248a6ab0f1d63a91c797c9c5d44c2af8" + }, + "package-b.mmsession/processing/jobs/foreign-directory": { + "symlink": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior" + }, + "package-b.mmsession/processing/jobs/foreign-session/job_manifest.json": { + "bytes": 4509, + "sha256": "95066d530c9a56380fd58679dae6680d6e3f678064405438c5985e37526aff7a" + }, + "package-b.mmsession/processing/jobs/malformed-manifest/job_manifest.json": { + "bytes": 9, + "sha256": "69cb18c1151284aa03aa4e6840be1940f366267b30a7e9a64330cd76c68d8bb4" + }, + "package-b.mmsession/processing/jobs/missing-manifest/params.json": { + "bytes": 3, + "sha256": "ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/_schema.json": { + "bytes": 2880, + "sha256": "c80f7d1e05378bf2399098e9887fc463edda22e366236eab3e9b1b0526d1f0f0" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/emg/sim.emg.main/windows.csv": { + "bytes": 504, + "sha256": "d7244bae8dab4e4e8ef00cf72cf387343720e31a25499c3f4741741209d1e9ad" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/emg/sim.emg.main/windows.parquet": { + "bytes": 7411, + "sha256": "60858ced982730b51829ae8080bd4217f9289373b65b501cc28411fdd1d83af0" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/imu/sim.imu.upper/windows.csv": { + "bytes": 628, + "sha256": "62212faf4179e9050c4d7a2e3530a461c70d0e56b227138e31b0c273bb21a277" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/imu/sim.imu.upper/windows.parquet": { + "bytes": 7645, + "sha256": "ff4ca0fbfed45e13e95f73d03d8ba56ce0f8305868012ecb5101df277a449ba9" + }, + "package-b.mmsession/processing/jobs/retained-prior/figures/emg_sim.emg.main_channels.png": { + "bytes": 93063, + "sha256": "87a315c7e23f334c9c8065cdab60ca26b8af8b965bd0ebaf33645864d0048124" + }, + "package-b.mmsession/processing/jobs/retained-prior/figures/imu_sim.imu.upper_accel.png": { + "bytes": 24298, + "sha256": "8cc603bf604d8925ba13be2c77e0bd8d8f8efbce9529e7d459a449fd61e6a8a4" + }, + "package-b.mmsession/processing/jobs/retained-prior/figures/sync_dashboard.png": { + "bytes": 37408, + "sha256": "07ebc1ff60a592f2086dcdfe63652666946329dbadf29dece5b6c84f87dd6082" + }, + "package-b.mmsession/processing/jobs/retained-prior/figures/sync_dashboard_series.json": { + "bytes": 1964, + "sha256": "01cdce9f387ad77ac1ea7632cee3c1d84fc879671cbf46e195c64bf1ec4a8c52" + }, + "package-b.mmsession/processing/jobs/retained-prior/job_manifest.json": { + "bytes": 4508, + "sha256": "95acf1efa8439e47fc5b011813f2fc5313a92de692f25459e3d56e68533a0389" + }, + "package-b.mmsession/processing/jobs/retained-prior/logs/job.log": { + "bytes": 179, + "sha256": "f0c184fbf12257a9ad4e41329ab95a5578ca769ca5fb84d9b9a32a18df8d7f46" + }, + "package-b.mmsession/processing/jobs/retained-prior/params.json": { + "bytes": 252, + "sha256": "9c0e1ab18949727f29352f1a602ae65d74db48f8453a49faa72fbc95c518b35b" + }, + "package-b.mmsession/processing/jobs/retained-prior/reports/qc.html": { + "bytes": 1629, + "sha256": "93671b7b67b1bf290a50a7a8d69e6fee6968caa1e540bf0615add4d0d1127671" + }, + "package-b.mmsession/processing/jobs/retained-prior/reports/qc.json": { + "bytes": 1296, + "sha256": "0c3647238cffb1ae94177f950a9b1407a88e0730b4503cffd27118c4634bc706" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/job_manifest.receiver-held.json": { + "bytes": 2400, + "sha256": "92e19a48f6c45e672d82c898f3827c8f353bf9e4a705c50f0012ddb033f2e845" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/logs/job.log": { + "bytes": 187, + "sha256": "75632168a67884e1ae52815a3ea0d9d3826f2d57f6ea8c23f1fa3f72a7591938" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/params.json": { + "bytes": 260, + "sha256": "564c6f9ab9fc6eed20ffe5a8de9fd55533f59d2783e38b1217cb65f88358b20a" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/reports/qc.html": { + "bytes": 1629, + "sha256": "93671b7b67b1bf290a50a7a8d69e6fee6968caa1e540bf0615add4d0d1127671" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/reports/qc.json": { + "bytes": 1296, + "sha256": "0c3647238cffb1ae94177f950a9b1407a88e0730b4503cffd27118c4634bc706" + }, + "package-b.mmsession/sources/sim.emg.main/health/gaps.jsonl": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "package-b.mmsession/sources/sim.emg.main/source.json": { + "bytes": 112, + "sha256": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10" + }, + "package-b.mmsession/sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap": { + "bytes": 1094, + "sha256": "9e997481c9b39b6a6b2d647df873fea26b04337c41571e77427a7f8ca9cda63b" + }, + "package-b.mmsession/sources/sim.emg.main/streams/sim.emg.main.batch/stream.json": { + "bytes": 224, + "sha256": "5307697f957309eaca816fa0e20c4799c900e2598a8acf66a59928aa83b305b2" + }, + "package-b.mmsession/sources/sim.imu.upper/source.json": { + "bytes": 118, + "sha256": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8" + }, + "package-b.mmsession/sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap": { + "bytes": 1678, + "sha256": "c477a0e0865086fbb4154c977def4d93ea5fb38cc098a4862c45b21b966014c9" + }, + "package-b.mmsession/sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json": { + "bytes": 219, + "sha256": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d" + } + }, + "fixture_path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-c0b5530-failure", + "harness_sha256": "b46094d3d823145aa07aa088371c6a63343ee7c5d8a06b254c6a4669f8c52da8", + "last_completed_assertion": "actual QThread QC result exists before deferred delivery", + "native_loop_control": "QApplication.exec control on same source passed 5 checks, exit 0, 0.249 s; this receipt does not claim a native application-loop failure", + "no_timeout_occurred": true, + "result": "manual-pump receiving process exited 139 after real result persistence and release; full candidate acceptance withheld", + "schema": "capturesuite.history.receiving.native-failure.v1" +} diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_history.py b/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_history.py new file mode 100644 index 00000000..79c8393f --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_history.py @@ -0,0 +1,437 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""Independent real Qt receiving of saved-job/package lifetime boundaries. + +Uses the project's genuine analysis pipeline. Only return delivery is delayed for +one actual QThread QC result; the analysis algorithm and worker are unmodified. +All writable fixtures are confined to this receiver's unique RAM directory. +""" +from __future__ import annotations + +import argparse +import dataclasses +import hashlib +import importlib +import importlib.util +import json +import os +from pathlib import Path +import shutil +import sys +import threading +import time +import traceback + +ROOT = Path('/dev/shm/hamon-401c5d17da79-capturesuite-receiving') +DEFAULT_SOURCE = Path('/dev/shm/capturesuite-history-401c5d17da79/source') +BASE_COMMIT = '72c15d6b623e217291a824e4e4808a385df896a9' + + +def digest(path: Path) -> str: + return hashlib.sha256(path.read_bytes()).hexdigest() + + +def snapshot(path: Path) -> dict: + result = {} + for item in sorted(path.rglob('*')): + if item.is_symlink(): + result[str(item.relative_to(path))] = {'symlink': os.readlink(item)} + elif item.is_file(): + result[str(item.relative_to(path))] = {'bytes': item.stat().st_size, 'sha256': digest(item)} + return result + + +def save_json(path: Path, doc: dict) -> None: + path.write_text(json.dumps(doc, indent=2, sort_keys=True) + '\n') + + +def bootstrap(source: Path) -> None: + for part in ('tmp', 'mpl', 'evidence', 'pins'): + (ROOT / part).mkdir(parents=True, exist_ok=True) + os.environ['QT_QPA_PLATFORM'] = 'offscreen' + os.environ['PYTHONDONTWRITEBYTECODE'] = '1' + os.environ['TMPDIR'] = str(ROOT / 'tmp') + os.environ['MPLCONFIGDIR'] = str(ROOT / 'mpl') + os.environ['MPLBACKEND'] = 'Agg' + sys.dont_write_bytecode = True + sys.path[:0] = [str(source / rel) for rel in ( + 'desktop', 'libs/python/capture_analysis', 'libs/python/capture_session', + 'libs/python/capture_protocol')] + import capture_analysis, capture_session, capture_protocol, capture_desktop + for module in (capture_analysis, capture_session, capture_protocol, capture_desktop): + if not Path(module.__file__).resolve().is_relative_to(source): + raise AssertionError(f'Editable dependency escaped source: {module.__file__}') + + +def make_package(source: Path, dest: Path, session: str, amplitude: float) -> Path: + """The existing phase-B native fixture shape, without deleting placeholders.""" + import numpy as np + from mcap.writer import Writer + from capture_protocol.generated.capture.v1.data import emg_batch_pb2, imu_frame_pb2 + if dest.exists(): + raise RuntimeError(f'Refusing to replace existing fixture {dest}') + shutil.copytree(source / 'tests/fixtures/mini_session', dest, + ignore=shutil.ignore_patterns('*.mcap', 'processing', '__pycache__')) + manifest_path = dest / 'manifest.json' + manifest = json.loads(manifest_path.read_text()) + manifest['sessionId'] = session + save_json(manifest_path, manifest) + samples = (amplitude * np.sin(2 * np.pi * 40.0 * np.arange(400) / 2000.0)).astype(np.float32) + emg = emg_batch_pb2.EmgBatch() + emg.timing.session_time_ns = 0 + emg.timing.sequence_number = 1 + emg.first_sample_index = 0 + emg.sample_count = 400 + emg.channel_ids.extend(['ch0', 'ch1']) + emg.samples_f32_le = np.stack([samples, samples * 0.5]).astype(' None: + from capture_analysis import JobParams, run + fixture_root = ROOT / 'fixtures' + if fixture_root.exists(): + raise RuntimeError('Receiving fixtures already exist; use the saved receipt, do not regenerate.') + if shutil.disk_usage(ROOT).free < 2_000_000: + raise RuntimeError('Less than the bounded 2 MB fixture budget is available.') + fixture_root.mkdir() + result_doc = {'source_commit': BASE_COMMIT, 'fixtures': {}, 'method': + 'Real protobuf EMG/IMU MCAP, synchronous native all jobs, same job basename in distinct sessions.'} + for letter, amplitude in (('a', 1.5), ('b', 0.75)): + package = make_package(source, fixture_root / f'package-{letter}.mmsession', + f'receiving-{letter}-401c5d17da79', amplitude) + raw_before = snapshot(package) + result = run(package, JobParams(command='all', overwrite_job_id='retained-prior')) + assert result.status in ('completed', 'completed_with_warnings'), result.status + raw_after = {key: value for key, value in snapshot(package).items() if not key.startswith('processing/')} + assert raw_before == raw_after + figures = sorted((result.job_dir / 'figures').glob('*.png')) + assert len(figures) >= 2, 'Need genuine images beyond the linked Sync view' + series = json.loads((result.job_dir / 'figures/sync_dashboard_series.json').read_text()) + assert series.get('series'), 'Need genuine linked plot data' + result_doc['fixtures'][letter] = { + 'package': str(package), 'job_dir': str(result.job_dir), 'job_id': result.job_id, + 'status': result.status, 'session_id': f'receiving-{letter}-401c5d17da79', + 'figures': [p.name for p in figures], 'sync_series_count': len(series['series']), + 'raw_unchanged_by_analysis': True, 'files': snapshot(package), + } + print(f'Prepared real {letter} result: {len(figures)} PNGs, {len(series["series"])} linked series', flush=True) + # These intentionally unavailable rows are admitted only to our private fixture. + b = fixture_root / 'package-b.mmsession/processing/jobs' + (b / 'malformed-manifest').mkdir() + (b / 'malformed-manifest/job_manifest.json').write_text('{not JSON') + (b / 'missing-manifest').mkdir() + (b / 'missing-manifest/params.json').write_text('{}\n') + (b / 'foreign-session').mkdir() + foreign = json.loads((fixture_root / 'package-a.mmsession/processing/jobs/retained-prior/job_manifest.json').read_text()) + foreign['jobId'] = 'foreign-session' + save_json(b / 'foreign-session/job_manifest.json', foreign) + (b / 'foreign-directory').symlink_to(fixture_root / 'package-a.mmsession/processing/jobs/retained-prior', target_is_directory=True) + # A valid real QC result lets the UI hold a catalog row before its manifest is moved. + result = run(b.parents[1], JobParams(command='qc', overwrite_job_id='selected-before-missing')) + assert result.status in ('completed', 'completed_with_warnings') + result_doc['selected_before_missing'] = str(result.job_dir) + result_doc['fixture_files'] = snapshot(fixture_root) + result_doc['total_bytes'] = sum(row.get('bytes', 0) for row in result_doc['fixture_files'].values()) + result_doc['free_bytes_after'] = shutil.disk_usage(ROOT).free + save_json(ROOT / 'evidence/fixtures.json', result_doc) + print(json.dumps({key: result_doc[key] for key in ('total_bytes', 'free_bytes_after')}, sort_keys=True)) + + +def load_screen(mode: str, source: Path): + if mode == 'baseline': + name = 'capture_desktop.screen_analysis' + spec = importlib.util.spec_from_file_location(name, ROOT / 'pins/baseline-screen_analysis.py') + module = importlib.util.module_from_spec(spec) + sys.modules[name] = module + spec.loader.exec_module(module) + return module.AnalysisScreen + pins = json.loads((ROOT / 'pins/candidate-inputs.json').read_text()) + for rel, record in pins['inputs'].items(): + assert digest(source / rel) == record['sha256'], f'Candidate bytes changed: {rel}' + return importlib.import_module('capture_desktop.screen_analysis').AnalysisScreen + + +def receive(mode: str, source: Path) -> int: + from PySide6 import __version__ as qt_version + from PySide6.QtCore import QCoreApplication, QEvent, Qt + from PySide6.QtTest import QTest + from PySide6.QtWidgets import QApplication, QComboBox, QLabel, QMessageBox, QPushButton + import capture_analysis + from capture_desktop.state import CaptureState + Screen = load_screen(mode, source) + app = QApplication.instance() or QApplication([]) + a = ROOT / 'fixtures/package-a.mmsession' + b = ROOT / 'fixtures/package-b.mmsession' + job_a, job_b = (p / 'processing/jobs/retained-prior' for p in (a, b)) + receipt = {'mode': mode, 'source_commit': BASE_COMMIT, 'python': sys.version, + 'pyside6': qt_version, 'qt_platform': app.platformName(), 'checks': [], + 'screens': {}, 'dialog_errors': [], 'source_imports': {}} + for name in ('capture_analysis', 'capture_analysis.jobs', 'capture_desktop.screen_analysis', + 'capture_desktop.widgets_analysis_plots', 'capture_desktop.state'): + module = importlib.import_module(name) + receipt['source_imports'][name] = {'path': module.__file__, 'sha256': digest(Path(module.__file__))} + if mode == 'candidate': + receipt['candidate_inputs'] = json.loads((ROOT / 'pins/candidate-inputs.json').read_text()) + fixture_before = snapshot(ROOT / 'fixtures') + raw_before = {key: val for key, val in fixture_before.items() if '/processing/' not in key} + release, ready = threading.Event(), threading.Event() + holder = {} + real_run = capture_analysis.run + screen = Screen(CaptureState()) + screen.resize(1200, 900) + screen.show() + + def pump() -> None: + app.processEvents() + for widget in app.topLevelWidgets(): + if isinstance(widget, QMessageBox) and widget.isVisible(): + receipt['dialog_errors'].append(widget.text()) + widget.accept() + QTest.qWait(5) + + def until(predicate, message: str, seconds: float = 25.0) -> None: + deadline = time.monotonic() + seconds + while not predicate(): + if time.monotonic() > deadline: + raise AssertionError(message) + pump() + pump() + + def state() -> dict: + tabs = screen._gallery._tabs + png_count = 0 + for i in range(1, tabs.count()): + for label in tabs.widget(i).findChildren(QLabel): + image = label.pixmap() + if image is not None and not image.isNull(): + png_count += 1 + return {'package': screen._package, 'last_job_dir': screen._last_job_dir, + 'inspector': screen._inspector._meta.text(), + 'tabs': [tabs.tabText(i) for i in range(tabs.count())], + 'png_count': png_count, 'sync_title': screen._gallery._sync._title.text(), + 'linked_plot_count': len(screen._gallery._sync._linked), + 'history_loaded_job_id': screen._history.loaded_job_id if hasattr(screen, '_history') else None, + 'open_folder_enabled': screen._btn_open_job.isEnabled(), + 'open_report_enabled': screen._btn_open_report.isEnabled()} + + def check(name: str, condition: bool, evidence=None) -> None: + receipt['checks'].append({'name': name, 'pass': bool(condition), 'evidence': evidence}) + print(f'{mode}: {name}: {bool(condition)}', flush=True) + if not condition: + raise AssertionError(name) + + def open_history(job_id: str) -> None: + combo = screen.findChild(QComboBox, 'analysisHistoryJob') + button = screen.findChild(QPushButton, 'analysisHistoryOpen') + assert combo is not None and button is not None + matches = [i for i in range(combo.count()) if getattr(combo.itemData(i), 'job_id', None) == job_id] + assert len(matches) == 1, (job_id, matches) + combo.setCurrentIndex(matches[0]) + pump() + assert button.isEnabled(), f'Cannot open {job_id}' + QTest.mouseClick(button, Qt.MouseButton.LeftButton) + pump() + + try: + screen.set_package(str(a)) + pump() + if mode == 'candidate': + open_history('retained-prior') + loaded_a = state() + check('fresh screen reopens real prior A result into gallery and inspector', + loaded_a['last_job_dir'] == str(job_a) and str(job_a) in loaded_a['inspector'] + and loaded_a['png_count'] >= 1 and loaded_a['linked_plot_count'] >= 1 + and 'receiving-a-401c5d17da79' in loaded_a['sync_title'], loaded_a) + else: + # Baseline already lacks history. Bind the existing renderer directly as + # the established control, then challenge only package/lifetime behavior. + screen._gallery.load_job_dir(job_a) + screen._inspector.load_job_dir(job_a) + screen._last_job_dir = str(job_a) + pump() + receipt['screens']['initial_a'] = state() + if mode == 'candidate': + visual_path = ROOT / 'evidence/candidate-reopened-a.png' + assert screen.grab().save(str(visual_path)) + receipt['screens']['initial_a_screenshot'] = {'path': str(visual_path), 'sha256': digest(visual_path)} + screen.set_package(str(b)) + pump() + switched = state() + receipt['screens']['after_package_switch'] = switched + cleared = switched['last_job_dir'] == '' and switched['inspector'] == 'No job loaded' and switched['png_count'] == 0 and switched['linked_plot_count'] == 0 + if mode == 'candidate': + check('package switch clears prior package result and launch targets', + cleared and not switched['open_folder_enabled'] and not switched['open_report_enabled'], switched) + open_history('retained-prior') + loaded_b = state() + check('same basename in package B resolves only B saved figures and metadata', + loaded_b['last_job_dir'] == str(job_b) and str(job_b) in loaded_b['inspector'] + and loaded_b['png_count'] >= 1 and loaded_b['linked_plot_count'] >= 1 + and 'receiving-b-401c5d17da79' in loaded_b['sync_title'], loaded_b) + visual_path = ROOT / 'evidence/candidate-reopened-b.png' + assert screen.grab().save(str(visual_path)) + receipt['screens']['reopened_b_screenshot'] = {'path': str(visual_path), 'sha256': digest(visual_path)} + before_refusals = snapshot(ROOT / 'fixtures') + combo = screen.findChild(QComboBox, 'analysisHistoryJob') + button = screen.findChild(QPushButton, 'analysisHistoryOpen') + for bad_id in ('malformed-manifest', 'missing-manifest', 'foreign-session', 'foreign-directory'): + matches = [i for i in range(combo.count()) if getattr(combo.itemData(i), 'job_id', None) == bad_id] + check(f'{bad_id} is visibly unavailable', len(matches) == 1, matches) + combo.setCurrentIndex(matches[0]); pump() + disabled = not button.isEnabled() + QTest.mouseClick(button, Qt.MouseButton.LeftButton); pump() + check(f'{bad_id} refuses opening without replacing valid B view', disabled and state() == loaded_b, + {'status': screen._history._status.text(), 'view': state()}) + check('unavailable-row inspection leaves all saved bytes unchanged', snapshot(ROOT / 'fixtures') == before_refusals) + # Deliberate private fixture rename simulates a disappearing manifest + # after catalog selection. Keep the exact bytes, never delete them. + missing_id = 'selected-before-missing' + selected = [i for i in range(combo.count()) if getattr(combo.itemData(i), 'job_id', None) == missing_id] + assert len(selected) == 1 + combo.setCurrentIndex(selected[0]); pump() + assert button.isEnabled() + manifest = b / 'processing/jobs' / missing_id / 'job_manifest.json' + held = manifest.with_name('job_manifest.receiver-held.json') + assert not held.exists() + manifest.rename(held) + mutated_fixture = snapshot(ROOT / 'fixtures') + QTest.mouseClick(button, Qt.MouseButton.LeftButton); pump() + check('Open revalidates cached row when manifest disappears', + state() == loaded_b and 'Could not open' in screen._history._status.text(), + screen._history._status.text()) + check('failed Open preserves every persisted byte after controlled fixture rename', snapshot(ROOT / 'fixtures') == mutated_fixture) + else: + check('baseline reproduces stale A view after switching to B', not cleared and str(job_a) in switched['inspector'], switched) + + screen.set_package(str(a)); pump() + qc_index = screen._command.findData('qc') + assert qc_index >= 0 + screen._command.setCurrentIndex(qc_index) + late_id = f'late-{mode}-actual-qc' + assert not (a / 'processing/jobs' / late_id).exists() + + def held_real_run(package, params, **kwargs): + try: + actual_params = dataclasses.replace(params, overwrite_job_id=late_id) + result = real_run(package, actual_params, **kwargs) + holder['result'] = result + ready.set() + if not release.wait(30): + raise TimeoutError('Receiving completion gate not released') + return result + except BaseException as exc: + holder['error'] = repr(exc) + ready.set() + raise + + capture_analysis.run = held_real_run + screen._btn_run.click() + until(ready.is_set, 'Actual native QC never reached completion hold') + assert 'error' not in holder, holder.get('error') + actual = holder['result'] + check('actual QThread QC result exists before deferred delivery', + actual.status in ('completed', 'completed_with_warnings') and (actual.job_dir / 'job_manifest.json').is_file(), + {'job_dir': str(actual.job_dir), 'status': actual.status}) + persisted_at_hold = snapshot(ROOT / 'fixtures') + screen.set_package(str(b)); pump() + receipt['screens']['late_before_delivery'] = state() + release.set() + until(lambda: screen._thread is None, 'Native worker completion did not finish its Qt lifecycle') + late_state = state() + receipt['screens']['late_after_delivery'] = late_state + if mode == 'candidate': + check('prior-package real completion cannot bind current B gallery or inspector', + late_state['package'] == str(b) and late_state['last_job_dir'] == '' + and late_state['inspector'] == 'No job loaded' and late_state['png_count'] == 0 + and late_state['linked_plot_count'] == 0 and not late_state['open_folder_enabled'], late_state) + check('late result remains discoverable by explicit package selection', + 'Result saved for the previous package' in screen._log.toPlainText(), screen._log.toPlainText()) + open_history('retained-prior') + check('current B result reopens after native thread completion', state()['last_job_dir'] == str(job_b), state()) + screen.set_package(str(a)); pump() + open_history(late_id) + check('returning to A explicitly opens its genuine late saved QC', + state()['last_job_dir'] == str(actual.job_dir) and str(actual.job_dir) in state()['inspector'], state()) + else: + check('baseline reproduces foreign binding after late real completion', + late_state['package'] == str(b) and late_state['last_job_dir'] == str(actual.job_dir) + and str(actual.job_dir) in late_state['inspector'], late_state) + check('delivery and reopening perform no persisted writes', snapshot(ROOT / 'fixtures') == persisted_at_hold) + raw_after = {key: val for key, val in snapshot(ROOT / 'fixtures').items() if '/processing/' not in key} + check('all captured raw package bytes remain unchanged', raw_after == raw_before) + check('no Qt error dialogs or worker failures occurred', not receipt['dialog_errors'], receipt['dialog_errors']) + screenshot = ROOT / 'evidence' / f'{mode}-qt.png' + assert screen.grab().save(str(screenshot)) + receipt['screenshot'] = {'path': str(screenshot), 'sha256': digest(screenshot)} + receipt['result'] = 'expected baseline defects reproduced' if mode == 'baseline' else 'candidate independent receiving passed' + code = 0 + except BaseException: + receipt['result'] = 'receiving failure' + receipt['traceback'] = traceback.format_exc() + print(receipt['traceback'], flush=True) + code = 1 + finally: + release.set() + capture_analysis.run = real_run + if screen._thread is not None: + try: + until(lambda: screen._thread is None, 'Worker did not settle during receiving close', 10) + except BaseException: + receipt['close_error'] = traceback.format_exc() + receipt['harness_sha256'] = digest(Path(__file__)) + receipt['free_bytes_after'] = shutil.disk_usage(ROOT).free + save_json(ROOT / 'evidence' / f'{mode}-receipt.json', receipt) + screen.close() + app.processEvents() + print(json.dumps({'mode': mode, 'result': receipt['result'], 'checks': len(receipt['checks']), 'free_bytes': receipt['free_bytes_after']}), flush=True) + return code + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument('mode', choices=('prepare', 'baseline', 'candidate')) + parser.add_argument('--source', type=Path, default=DEFAULT_SOURCE) + args = parser.parse_args() + bootstrap(args.source.resolve()) + if args.mode == 'prepare': + prepare(args.source.resolve()) + return 0 + return receive(args.mode, args.source.resolve()) + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_history_native.py b/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_history_native.py new file mode 100644 index 00000000..72eae6b5 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_history_native.py @@ -0,0 +1,239 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""Complete independent receiving in the real QApplication event loop. + +Actions advance from QTimer callbacks; no manual processEvents/qWait pumping, +no retained worker/thread references, no production source or worker edits. +""" +from __future__ import annotations +import dataclasses +import importlib.util +import json +from pathlib import Path +import sys +import threading +import time +import traceback + +ROOT = Path('/dev/shm/hamon-401c5d17da79-capturesuite-receiving') +FIXTURES = ROOT / 'fixtures-native' +spec = importlib.util.spec_from_file_location('receiving_helpers', ROOT / 'methods/receive_history.py') +helpers = importlib.util.module_from_spec(spec) +spec.loader.exec_module(helpers) +helpers.bootstrap(helpers.DEFAULT_SOURCE) +from PySide6 import __version__ as pyside_version +from PySide6.QtCore import QTimer +from PySide6.QtWidgets import QApplication, QComboBox, QLabel, QMessageBox, QPushButton +from capture_desktop.state import CaptureState +import capture_analysis + +Screen = helpers.load_screen('candidate', helpers.DEFAULT_SOURCE) +app = QApplication([]) +screen = Screen(CaptureState()) +screen.resize(1200, 900) +screen.show() +a, b = (FIXTURES / f'package-{letter}.mmsession' for letter in ('a','b')) +job_a, job_b = (p / 'processing/jobs/retained-prior' for p in (a,b)) +release, ready = threading.Event(), threading.Event() +holder = {} +real_run = capture_analysis.run +started = time.monotonic() +settling_failure = False +before = helpers.snapshot(FIXTURES) +raw_before = {key:value for key,value in before.items() if '/processing/' not in key} +receipt = {'schema':'capturesuite.history.independent-native-receiving.v1', + 'candidate':json.loads((ROOT / 'pins/candidate-inputs.json').read_text()), + 'runtime':{'python':sys.version,'pyside6':pyside_version,'qt_platform':app.platformName()}, + 'loop':'QApplication.exec; state-machine actions via QTimer; no manual processEvents, QTest.qWait, source edits, worker replacement, or retained worker/thread reference', + 'method_sha256':helpers.digest(Path(__file__)), 'helper_sha256':helpers.digest(ROOT / 'methods/receive_history.py'), + 'fixture_root':str(FIXTURES),'checks':[],'screens':{},'errors':[], 'source_imports':{}} +for module in (capture_analysis, sys.modules['capture_analysis.jobs'],sys.modules['capture_desktop.screen_analysis'],sys.modules['capture_desktop.widgets_analysis_plots']): + receipt['source_imports'][module.__name__] = {'path':module.__file__,'sha256':helpers.digest(Path(module.__file__))} + + +def persist(): + helpers.save_json(ROOT / 'evidence/native-candidate-receipt.json', receipt) + + +def check(name, condition, evidence=None): + receipt['checks'].append({'name':name,'pass':bool(condition),'evidence':evidence}) + persist() + print(name, bool(condition), flush=True) + if not condition: + raise AssertionError(name) + + +def view(): + tabs = screen._gallery._tabs + png_count = 0 + for index in range(1,tabs.count()): + for label in tabs.widget(index).findChildren(QLabel): + pixmap = label.pixmap() + if pixmap is not None and not pixmap.isNull(): png_count += 1 + return {'package':screen._package,'last_job_dir':screen._last_job_dir, + 'inspector':screen._inspector._meta.text(), + 'tabs':[tabs.tabText(i) for i in range(tabs.count())], + 'png_count':png_count,'linked_plot_count':len(screen._gallery._sync._linked), + 'sync_title':screen._gallery._sync._title.text(), + 'history_loaded_job_id':screen._history.loaded_job_id, + 'open_folder_enabled':screen._btn_open_job.isEnabled(), + 'open_report_enabled':screen._btn_open_report.isEnabled()} + + +def select(job_id): + combo = screen.findChild(QComboBox,'analysisHistoryJob') + matches = [i for i in range(combo.count()) if getattr(combo.itemData(i),'job_id',None) == job_id] + assert len(matches) == 1, (job_id,matches) + combo.setCurrentIndex(matches[0]) + return screen.findChild(QPushButton,'analysisHistoryOpen') + + +def open_saved(job_id): + button = select(job_id) + assert button.isEnabled(), job_id + button.click() + + +def capture(name): + path = ROOT / 'evidence' / name + assert screen.grab().save(str(path)) + return {'path':str(path),'sha256':helpers.digest(path)} + + +def held_actual_run(package, params, **kwargs): + try: + actual = real_run(package,dataclasses.replace(params,overwrite_job_id='late-native-candidate-qc'),**kwargs) + holder['result'] = actual + ready.set() + if not release.wait(30): raise TimeoutError('Receiving gate was not released') + return actual + except BaseException as exc: + holder['error'] = repr(exc) + ready.set() + raise + + +def flow(): + screen.set_package(str(a)); yield + open_saved('retained-prior'); yield + current = view() + check('fresh screen reopens real prior A result into native gallery and inspector', + current['last_job_dir']==str(job_a) and str(job_a) in current['inspector'] + and current['png_count']==2 and current['linked_plot_count']==2 + and 'receiving-a-401c5d17da79' in current['sync_title'],current) + receipt['screens']['reopened_a']=capture('native-reopened-a.png') + screen.set_package(str(b)); yield + current = view() + check('package switch clears prior result and both launch targets', + current['last_job_dir']=='' and current['inspector']=='No job loaded' + and current['png_count']==0 and current['linked_plot_count']==0 + and not current['open_folder_enabled'] and not current['open_report_enabled'],current) + open_saved('retained-prior'); yield + loaded_b = view() + check('same basename in B resolves B figures and metadata only', + loaded_b['last_job_dir']==str(job_b) and str(job_b) in loaded_b['inspector'] + and loaded_b['png_count']==2 and loaded_b['linked_plot_count']==2 + and 'receiving-b-401c5d17da79' in loaded_b['sync_title'],loaded_b) + receipt['screens']['reopened_b']=capture('native-reopened-b.png') + before_refusals=helpers.snapshot(FIXTURES) + for bad_id in ('malformed-manifest','missing-manifest','foreign-session','foreign-directory'): + button=select(bad_id); yield + disabled=not button.isEnabled() + button.click(); yield + check(f'{bad_id} is visibly unavailable and refuses Open without replacing B', + disabled and view()==loaded_b, + {'status':screen._history._status.text(),'view':view()}) + check('unavailable-row actions leave every saved byte unchanged',helpers.snapshot(FIXTURES)==before_refusals) + button=select('selected-before-missing'); yield + assert button.isEnabled() + manifest=b/'processing/jobs/selected-before-missing/job_manifest.json' + held=manifest.with_name('job_manifest.receiver-held.json') + assert not held.exists() + manifest.rename(held) + at_missing=helpers.snapshot(FIXTURES) + button.click(); yield + check('Open revalidates a cached row after its manifest disappears', + view()==loaded_b and 'Could not open' in screen._history._status.text(),screen._history._status.text()) + check('refused cached Open preserves all bytes after the controlled rename',helpers.snapshot(FIXTURES)==at_missing) + screen.set_package(str(a)); yield + screen._command.setCurrentIndex(screen._command.findData('qc')) + assert not (a/'processing/jobs/late-native-candidate-qc').exists() + capture_analysis.run=held_actual_run + screen._btn_run.click() + while not ready.is_set(): yield + assert 'error' not in holder,holder.get('error') + actual=holder['result'] + check('real QThread QC completed and persisted before receiving release', + actual.status in ('completed','completed_with_warnings') and (actual.job_dir/'job_manifest.json').is_file(), + {'job_dir':str(actual.job_dir),'status':actual.status}) + at_hold=helpers.snapshot(FIXTURES) + screen.set_package(str(b)); yield + receipt['screens']['before_late_delivery']=view() + release.set() + while screen._thread is not None: yield + current=view() + check('prior-package real completion cannot bind current B gallery or inspector', + current['package']==str(b) and current['last_job_dir']=='' + and current['inspector']=='No job loaded' and current['png_count']==0 + and current['linked_plot_count']==0 and not current['open_folder_enabled'],current) + check('prior-package result is explicitly retained for later inspection', + 'Result saved for the previous package' in screen._log.toPlainText(),screen._log.toPlainText()) + open_saved('retained-prior'); yield + check('current B saved result reopens after actual Qt thread completion',view()['last_job_dir']==str(job_b),view()) + screen.set_package(str(a)); yield + open_saved(actual.job_id); yield + check('returning to A explicitly opens the genuinely completed late QC', + view()['last_job_dir']==str(actual.job_dir) and str(actual.job_dir) in view()['inspector'],view()) + check('late delivery and later reopenings perform no persisted writes',helpers.snapshot(FIXTURES)==at_hold) + raw_after={key:value for key,value in helpers.snapshot(FIXTURES).items() if '/processing/' not in key} + check('all captured raw data remains unchanged',raw_before==raw_after) + check('no Qt error dialog or native worker failure',not receipt['errors'],receipt['errors']) + for rel,pin in receipt['candidate']['inputs'].items(): + assert helpers.digest(helpers.DEFAULT_SOURCE/rel)==pin['sha256'],rel+' changed during receiving' + check('frozen source bytes remained exact throughout native receiving',True) + receipt['screens']['late_qc']=capture('native-late-qc.png') + receipt['fixture_files_after']=helpers.snapshot(FIXTURES) + receipt['source_unchanged']=True + receipt['seconds']=time.monotonic()-started + receipt['pass']=True + receipt['result']='All independent native QApplication receiving checks passed on exact corrected candidate' + persist() + + +iterator=flow() + +def advance(): + global settling_failure + try: + for widget in app.topLevelWidgets(): + if isinstance(widget,QMessageBox) and widget.isVisible(): + receipt['errors'].append(widget.text());widget.accept() + if settling_failure: + if screen._thread is None:app.exit(1) + return + if time.monotonic()-started>35:raise TimeoutError('Native receiving exceeded its bounded deadline') + next(iterator) + except StopIteration: + app.exit(0) + except BaseException: + receipt['errors'].append(traceback.format_exc()) + receipt['pass']=False + receipt['result']='Independent native receiving failed' + release.set() + settling_failure=True + persist() + if screen._thread is None:app.exit(1) + + +timer=QTimer() +timer.setInterval(10) +timer.timeout.connect(advance) +timer.start() +persist() +code=app.exec() +release.set() +capture_analysis.run=real_run +screen.close() +receipt['process_return']=code +persist() +print(json.dumps({'pass':receipt.get('pass'),'checks':len(receipt['checks']),'seconds':receipt.get('seconds'),'code':code}),flush=True) +raise SystemExit(code) diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_qt_eventloop.py b/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_qt_eventloop.py new file mode 100644 index 00000000..8c4dbe4a --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/methods/receive_qt_eventloop.py @@ -0,0 +1,155 @@ +# SPDX-License-Identifier: GPL-3.0-only +"""One disjoint native QApplication.exec control of actual prior-package completion.""" +from __future__ import annotations +import dataclasses +import importlib.util +import json +from pathlib import Path +import sys +import threading +import time +import traceback + +root = Path('/dev/shm/hamon-401c5d17da79-capturesuite-receiving') +spec = importlib.util.spec_from_file_location('receiving_helpers', root / 'methods/receive_history.py') +helpers = importlib.util.module_from_spec(spec) +spec.loader.exec_module(helpers) +source = helpers.DEFAULT_SOURCE +helpers.bootstrap(source) +from PySide6.QtCore import QTimer +from PySide6.QtWidgets import QApplication, QComboBox, QMessageBox, QPushButton +from capture_desktop.state import CaptureState +import capture_analysis +Screen = helpers.load_screen('candidate', source) +app = QApplication([]) +screen = Screen(CaptureState()) +screen.resize(1200, 900) +screen.show() +a = root / 'fixtures/package-a.mmsession' +b = root / 'fixtures/package-b.mmsession' +ready, release = threading.Event(), threading.Event() +holder = {} +real_run = capture_analysis.run +started = time.monotonic() +phase = 'starting' +receipt = {'schema':'capturesuite.history.native-eventloop-control.v1', + 'candidate':json.loads((root / 'pins/candidate-inputs.json').read_text()), + 'method_sha256':helpers.digest(Path(__file__)), + 'loop':'QApplication.exec with QTimer; no manual processEvents or QTest.qWait', + 'events':[], 'checks':[], 'errors':[]} + + +def persist(): + helpers.save_json(root / 'evidence/eventloop-receipt.json', receipt) + + +def check(label, ok, detail=None): + receipt['checks'].append({'label':label,'pass':bool(ok),'detail':detail}) + persist() + print(label, bool(ok), flush=True) + if not ok: + raise AssertionError(label) + + +def held_run(package, params, **kwargs): + try: + actual = real_run(package, dataclasses.replace(params, overwrite_job_id='late-eventloop-actual-qc'), **kwargs) + holder['result'] = actual + ready.set() + if not release.wait(30): + raise TimeoutError('Receiving completion gate was not released') + return actual + except BaseException as exc: + holder['error'] = repr(exc) + ready.set() + raise + + +def start(): + global phase + try: + screen.set_package(str(a)) + combo = screen.findChild(QComboBox, 'analysisHistoryJob') + matches = [i for i in range(combo.count()) if getattr(combo.itemData(i),'job_id',None) == 'retained-prior'] + assert len(matches) == 1 + combo.setCurrentIndex(matches[0]) + screen.findChild(QPushButton,'analysisHistoryOpen').click() + assert screen._last_job_dir == str(a / 'processing/jobs/retained-prior') + assert len(screen._gallery._sync._linked) == 2 + screen.set_package(str(b)) + screen.set_package(str(a)) + assert not (a / 'processing/jobs/late-eventloop-actual-qc').exists() + screen._command.setCurrentIndex(screen._command.findData('qc')) + capture_analysis.run = held_run + screen._btn_run.click() + phase = 'awaiting_result' + receipt['events'].append('actual QThread started in native application loop') + persist() + except BaseException: + fail() + + +def fail(): + global phase + receipt['errors'].append(traceback.format_exc()) + receipt['pass'] = False + release.set() + phase = 'failed_settling' + persist() + if screen._thread is None: + app.exit(1) + + +def tick(): + global phase + try: + for widget in app.topLevelWidgets(): + if isinstance(widget, QMessageBox) and widget.isVisible(): + receipt['errors'].append(widget.text()) + widget.accept() + if phase == 'awaiting_result' and ready.is_set(): + assert 'error' not in holder, holder.get('error') + actual = holder['result'] + check('real QC was persisted before release', (actual.job_dir / 'job_manifest.json').is_file(), + {'job_dir':str(actual.job_dir),'status':actual.status}) + holder['at_hold'] = helpers.snapshot(root / 'fixtures') + screen.set_package(str(b)) + check('selected B is unbound before A completion', screen._package == str(b) and screen._last_job_dir == '' and screen._inspector._meta.text() == 'No job loaded') + phase = 'awaiting_thread_finish' + receipt['events'].append('selected B, released real A completion') + persist() + release.set() + elif phase == 'awaiting_thread_finish' and screen._thread is None: + check('native event loop settles without binding previous-package result', + screen._package == str(b) and screen._last_job_dir == '' and screen._inspector._meta.text() == 'No job loaded', + {'package':screen._package,'last_job_dir':screen._last_job_dir,'inspector':screen._inspector._meta.text()}) + check('completion preserves all bytes after actual job persistence', helpers.snapshot(root / 'fixtures') == holder['at_hold']) + check('no native error dialogs', not receipt['errors'], receipt['errors']) + receipt['seconds'] = time.monotonic() - started + receipt['pass'] = True + receipt['events'].append('native event loop accepted exact completion boundary') + persist() + phase = 'done' + app.exit(0) + elif phase == 'failed_settling' and screen._thread is None: + app.exit(1) + elif time.monotonic() - started > 35 and phase not in ('done', 'failed_settling'): + raise TimeoutError('Native event-loop control exceeded its bounded completion deadline') + except BaseException: + fail() + + +timer = QTimer() +timer.setInterval(10) +timer.timeout.connect(tick) +timer.start() +QTimer.singleShot(0, start) +persist() +code = app.exec() +capture_analysis.run = real_run +release.set() +screen.close() +receipt['process_return'] = code +persist() +print(json.dumps({'pass':receipt.get('pass'),'checks':len(receipt['checks']),'seconds':receipt.get('seconds'),'code':code}),flush=True) +raise SystemExit(code) diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/native-candidate-receipt.json b/docs/evidence/analysis-history-401c5d17da79/independent/native-candidate-receipt.json new file mode 100644 index 00000000..7348a89e --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/native-candidate-receipt.json @@ -0,0 +1,653 @@ +{ + "candidate": { + "baseline": "72c15d6b623e217291a824e4e4808a385df896a9", + "commit": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "correction": "Refresh failed retained jobs in the failure slot; successful completion already refreshes there. Restore original thread-finished cleanup, eliminating added filesystem work after releasing worker references. Native worker and signal wiring are unchanged.", + "focused_and_retained_tests": "14 passed in3.21s; no skips", + "inputs": { + "desktop/capture_desktop/analysis_history.py": { + "bytes": 6375, + "sha256": "2e0db8cee59ef268d3c91ea0beac7d761d83a3003862841cc9d7f1782fd3543c" + }, + "desktop/capture_desktop/screen_analysis.py": { + "bytes": 16407, + "sha256": "98a704e31b14497e012fe5618ad47cc8a772bd2d59775826d71a5bdf41533211" + }, + "desktop/capture_desktop/widgets_analysis_history.py": { + "bytes": 8458, + "sha256": "a3b77c87483c1412b50de7ddde1498f6bfd3968002fc3ac3bfa474a2477d9bc4" + }, + "tests/ui/test_analysis_history.py": { + "bytes": 10465, + "sha256": "48175547922125c308fa49bbb84149e3dac8903902e7cc64fa7c15b4ca40eccd" + } + }, + "previous_candidate": "c0b5530c03cce3e42a0430e5411cddf1df716e19", + "runtime": "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "tree": "3b3184b931a2aaf91beec36c953bff909a77f2f5", + "worker_and_thread_cleanup_ast_identical_to_baseline": true + }, + "checks": [ + { + "evidence": { + "history_loaded_job_id": "retained-prior", + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession", + "png_count": 2, + "sync_title": "receiving-a-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + }, + "name": "fresh screen reopens real prior A result into native gallery and inspector", + "pass": true + }, + { + "evidence": { + "history_loaded_job_id": "", + "inspector": "No job loaded", + "last_job_dir": "", + "linked_plot_count": 0, + "open_folder_enabled": false, + "open_report_enabled": false, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 0, + "sync_title": "Sync dashboard", + "tabs": [ + "Sync" + ] + }, + "name": "package switch clears prior result and both launch targets", + "pass": true + }, + { + "evidence": { + "history_loaded_job_id": "retained-prior", + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 2, + "sync_title": "receiving-b-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + }, + "name": "same basename in B resolves B figures and metadata only", + "pass": true + }, + { + "evidence": { + "status": "malformed-manifest: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)", + "view": { + "history_loaded_job_id": "retained-prior", + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 2, + "sync_title": "receiving-b-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + } + }, + "name": "malformed-manifest is visibly unavailable and refuses Open without replacing B", + "pass": true + }, + { + "evidence": { + "status": "missing-manifest: Saved file is unavailable: job_manifest.json", + "view": { + "history_loaded_job_id": "retained-prior", + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 2, + "sync_title": "receiving-b-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + } + }, + "name": "missing-manifest is visibly unavailable and refuses Open without replacing B", + "pass": true + }, + { + "evidence": { + "status": "foreign-session: Saved job belongs to a different session.", + "view": { + "history_loaded_job_id": "retained-prior", + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 2, + "sync_title": "receiving-b-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + } + }, + "name": "foreign-session is visibly unavailable and refuses Open without replacing B", + "pass": true + }, + { + "evidence": { + "status": "foreign-directory: Saved analysis paths must stay inside this package: /dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/foreign-directory", + "view": { + "history_loaded_job_id": "retained-prior", + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 2, + "sync_title": "receiving-b-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + } + }, + "name": "foreign-directory is visibly unavailable and refuses Open without replacing B", + "pass": true + }, + { + "evidence": null, + "name": "unavailable-row actions leave every saved byte unchanged", + "pass": true + }, + { + "evidence": "Could not open selected-before-missing: Saved file is unavailable: job_manifest.json. Refresh the job list.", + "name": "Open revalidates a cached row after its manifest disappears", + "pass": true + }, + { + "evidence": null, + "name": "refused cached Open preserves all bytes after the controlled rename", + "pass": true + }, + { + "evidence": { + "job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession/processing/jobs/late-native-candidate-qc", + "status": "completed" + }, + "name": "real QThread QC completed and persisted before receiving release", + "pass": true + }, + { + "evidence": { + "history_loaded_job_id": "", + "inspector": "No job loaded", + "last_job_dir": "", + "linked_plot_count": 0, + "open_folder_enabled": false, + "open_report_enabled": false, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 0, + "sync_title": "Sync dashboard", + "tabs": [ + "Sync" + ] + }, + "name": "prior-package real completion cannot bind current B gallery or inspector", + "pass": true + }, + { + "evidence": "Starting qc on /dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession\nstart (0%)\nqc (15%)\nwrite_qc (25%)\nmanifest (90%)\ndone (100%)\nDone status=completed job_id=late-native-candidate-qc\ndir=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession/processing/jobs/late-native-candidate-qc\nResult saved for the previous package; select that package to inspect it.", + "name": "prior-package result is explicitly retained for later inspection", + "pass": true + }, + { + "evidence": { + "history_loaded_job_id": "retained-prior", + "inspector": "job_id=retained-prior\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession/processing/jobs/retained-prior", + "linked_plot_count": 2, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 2, + "sync_title": "receiving-b-401c5d17da79 \u00b7 gap_policy=mask", + "tabs": [ + "Sync", + "emg sim.emg.main channel", + "imu sim.imu.upper accel" + ] + }, + "name": "current B saved result reopens after actual Qt thread completion", + "pass": true + }, + { + "evidence": { + "history_loaded_job_id": "late-native-candidate-qc", + "inspector": "job_id=late-native-candidate-qc\nstatus=completed\ngap_policy=mask\nplugin_manifest=1.0.0\npath=/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession/processing/jobs/late-native-candidate-qc", + "last_job_dir": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession/processing/jobs/late-native-candidate-qc", + "linked_plot_count": 0, + "open_folder_enabled": true, + "open_report_enabled": true, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-a.mmsession", + "png_count": 0, + "sync_title": "Sync dashboard", + "tabs": [ + "Sync" + ] + }, + "name": "returning to A explicitly opens the genuinely completed late QC", + "pass": true + }, + { + "evidence": null, + "name": "late delivery and later reopenings perform no persisted writes", + "pass": true + }, + { + "evidence": null, + "name": "all captured raw data remains unchanged", + "pass": true + }, + { + "evidence": [], + "name": "no Qt error dialog or native worker failure", + "pass": true + }, + { + "evidence": null, + "name": "frozen source bytes remained exact throughout native receiving", + "pass": true + } + ], + "errors": [], + "fixture_files_after": { + "package-a.mmsession/events/annotations.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-a.mmsession/events/checkpoints.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-a.mmsession/events/sync_anchors.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-a.mmsession/integrity.json": { + "bytes": 225, + "sha256": "2fb4194b22d4b1c373f25f9ecab51d0c80e14f42a52f53293fd727ce5418f140" + }, + "package-a.mmsession/manifest.json": { + "bytes": 250, + "sha256": "6cc54886cc63fa1263a4077fec322454fdfa133a408836a75451fd77eb7c5243" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/job_manifest.json": { + "bytes": 2400, + "sha256": "bbb88191cb522d3314139b6ebcb4cd2e6b8aa6c6b7df362d0653a0a75dcba7bc" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/logs/job.log": { + "bytes": 187, + "sha256": "59f307f1af8f7e20fe908e17afdf3047f6d7eda3d04d2d7e5153f258b6377d37" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/params.json": { + "bytes": 260, + "sha256": "88f55fe8dddb0794c98f693dd21fdd7764a6bac45203e11ba52eab3ebaa40fc3" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/reports/qc.html": { + "bytes": 1629, + "sha256": "db815562d270dc133bce019f0c0791bea4e9af52fc62ce7107a41ea6a8485d20" + }, + "package-a.mmsession/processing/jobs/late-baseline-actual-qc/reports/qc.json": { + "bytes": 1296, + "sha256": "2a1addc8accb001643f81a4b1061458f8fa27de6ffcc157fbed5ddb837c9cf27" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/job_manifest.json": { + "bytes": 2401, + "sha256": "d63428766698ba71d56f9797340cc2e4f870cded0e04708b98ee991200e5d88e" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/logs/job.log": { + "bytes": 188, + "sha256": "c2b223c3686c245380c6b3788d45deb8f4a56ca9d420039af2ff598f6eb66cc1" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/params.json": { + "bytes": 261, + "sha256": "9aad1ac26d07fdbf51e882ad70c97ae15942b3057755083b0a8b063506d23fe8" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/reports/qc.html": { + "bytes": 1629, + "sha256": "db815562d270dc133bce019f0c0791bea4e9af52fc62ce7107a41ea6a8485d20" + }, + "package-a.mmsession/processing/jobs/late-candidate-actual-qc/reports/qc.json": { + "bytes": 1296, + "sha256": "2a1addc8accb001643f81a4b1061458f8fa27de6ffcc157fbed5ddb837c9cf27" + }, + "package-a.mmsession/processing/jobs/late-native-candidate-qc/job_manifest.json": { + "bytes": 2408, + "sha256": "995796fd6b5f52e89ea25a0c45fd769b6352b5f2b1d8984b250971c691ad8658" + }, + "package-a.mmsession/processing/jobs/late-native-candidate-qc/logs/job.log": { + "bytes": 195, + "sha256": "b9c0d4a5e6fc748c0a4b60187926f7e9885a2a386a7ed8e85c37a261e053a87d" + }, + "package-a.mmsession/processing/jobs/late-native-candidate-qc/params.json": { + "bytes": 261, + "sha256": "e09345ba9ebd7b6f59a9b70cff3af7406c1424237cb5e27a05a80f755b270cb9" + }, + "package-a.mmsession/processing/jobs/late-native-candidate-qc/reports/qc.html": { + "bytes": 1636, + "sha256": "2917196a7446847355f7443ab5bde8be96dbc71e2b48927f4e60fe064affce6e" + }, + "package-a.mmsession/processing/jobs/late-native-candidate-qc/reports/qc.json": { + "bytes": 1303, + "sha256": "2d98f837e78a3866402a3f4f9dc765a262168f36d8fe8b2235e02ee17efd3551" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/_schema.json": { + "bytes": 2880, + "sha256": "c80f7d1e05378bf2399098e9887fc463edda22e366236eab3e9b1b0526d1f0f0" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/emg/sim.emg.main/windows.csv": { + "bytes": 501, + "sha256": "0c9b8016e1295976eb10eabdb913efff752cf9936bf4a7cab1d3107a85ca97ff" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/emg/sim.emg.main/windows.parquet": { + "bytes": 7411, + "sha256": "c5d6d1727acd151ca0b1430eecb0dd0491fe2863a9f7c163d7524bfed584e60f" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/imu/sim.imu.upper/windows.csv": { + "bytes": 628, + "sha256": "62212faf4179e9050c4d7a2e3530a461c70d0e56b227138e31b0c273bb21a277" + }, + "package-a.mmsession/processing/jobs/retained-prior/features/imu/sim.imu.upper/windows.parquet": { + "bytes": 7645, + "sha256": "ff4ca0fbfed45e13e95f73d03d8ba56ce0f8305868012ecb5101df277a449ba9" + }, + "package-a.mmsession/processing/jobs/retained-prior/figures/emg_sim.emg.main_channels.png": { + "bytes": 91869, + "sha256": "4c7a4aee76c4895cf99e38874de271e83a52c0e7389093c14a93344e9dc43853" + }, + "package-a.mmsession/processing/jobs/retained-prior/figures/imu_sim.imu.upper_accel.png": { + "bytes": 24298, + "sha256": "8cc603bf604d8925ba13be2c77e0bd8d8f8efbce9529e7d459a449fd61e6a8a4" + }, + "package-a.mmsession/processing/jobs/retained-prior/figures/sync_dashboard.png": { + "bytes": 37253, + "sha256": "bda125c256b17dbd688ec825c2a5b9b8542f346ce95209faf15efadad5c78d48" + }, + "package-a.mmsession/processing/jobs/retained-prior/figures/sync_dashboard_series.json": { + "bytes": 1963, + "sha256": "ba1181c30b0a3ab1b26b716e56bf0787f2e67aa4178cd511f0106486d04aa8e6" + }, + "package-a.mmsession/processing/jobs/retained-prior/job_manifest.json": { + "bytes": 4508, + "sha256": "21471f1ee0cae441202b4b704c6cd1359558ac1bf27f077668508eb1368ae6e7" + }, + "package-a.mmsession/processing/jobs/retained-prior/logs/job.log": { + "bytes": 179, + "sha256": "3cf99c71a0e4e3046b791ad2c04e388adfe452959b315d8dd5df6d278a5aaf63" + }, + "package-a.mmsession/processing/jobs/retained-prior/params.json": { + "bytes": 252, + "sha256": "9c0e1ab18949727f29352f1a602ae65d74db48f8453a49faa72fbc95c518b35b" + }, + "package-a.mmsession/processing/jobs/retained-prior/reports/qc.html": { + "bytes": 1629, + "sha256": "db815562d270dc133bce019f0c0791bea4e9af52fc62ce7107a41ea6a8485d20" + }, + "package-a.mmsession/processing/jobs/retained-prior/reports/qc.json": { + "bytes": 1296, + "sha256": "2a1addc8accb001643f81a4b1061458f8fa27de6ffcc157fbed5ddb837c9cf27" + }, + "package-a.mmsession/sources/sim.emg.main/health/gaps.jsonl": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "package-a.mmsession/sources/sim.emg.main/source.json": { + "bytes": 112, + "sha256": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10" + }, + "package-a.mmsession/sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap": { + "bytes": 1095, + "sha256": "6f3b9bd4ce01238f122649a1139a290ea6193893938a95f3ac61dd61a447d997" + }, + "package-a.mmsession/sources/sim.emg.main/streams/sim.emg.main.batch/stream.json": { + "bytes": 224, + "sha256": "5307697f957309eaca816fa0e20c4799c900e2598a8acf66a59928aa83b305b2" + }, + "package-a.mmsession/sources/sim.imu.upper/source.json": { + "bytes": 118, + "sha256": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8" + }, + "package-a.mmsession/sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap": { + "bytes": 1678, + "sha256": "c477a0e0865086fbb4154c977def4d93ea5fb38cc098a4862c45b21b966014c9" + }, + "package-a.mmsession/sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json": { + "bytes": 219, + "sha256": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d" + }, + "package-b.mmsession/events/annotations.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-b.mmsession/events/checkpoints.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-b.mmsession/events/sync_anchors.json": { + "bytes": 3, + "sha256": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570" + }, + "package-b.mmsession/integrity.json": { + "bytes": 225, + "sha256": "2fb4194b22d4b1c373f25f9ecab51d0c80e14f42a52f53293fd727ce5418f140" + }, + "package-b.mmsession/manifest.json": { + "bytes": 250, + "sha256": "26ea1e6f375028575b0c72477dddff58248a6ab0f1d63a91c797c9c5d44c2af8" + }, + "package-b.mmsession/processing/jobs/foreign-directory": { + "symlink": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures/package-a.mmsession/processing/jobs/retained-prior" + }, + "package-b.mmsession/processing/jobs/foreign-session/job_manifest.json": { + "bytes": 4509, + "sha256": "95066d530c9a56380fd58679dae6680d6e3f678064405438c5985e37526aff7a" + }, + "package-b.mmsession/processing/jobs/malformed-manifest/job_manifest.json": { + "bytes": 9, + "sha256": "69cb18c1151284aa03aa4e6840be1940f366267b30a7e9a64330cd76c68d8bb4" + }, + "package-b.mmsession/processing/jobs/missing-manifest/params.json": { + "bytes": 3, + "sha256": "ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/_schema.json": { + "bytes": 2880, + "sha256": "c80f7d1e05378bf2399098e9887fc463edda22e366236eab3e9b1b0526d1f0f0" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/emg/sim.emg.main/windows.csv": { + "bytes": 504, + "sha256": "d7244bae8dab4e4e8ef00cf72cf387343720e31a25499c3f4741741209d1e9ad" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/emg/sim.emg.main/windows.parquet": { + "bytes": 7411, + "sha256": "60858ced982730b51829ae8080bd4217f9289373b65b501cc28411fdd1d83af0" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/imu/sim.imu.upper/windows.csv": { + "bytes": 628, + "sha256": "62212faf4179e9050c4d7a2e3530a461c70d0e56b227138e31b0c273bb21a277" + }, + "package-b.mmsession/processing/jobs/retained-prior/features/imu/sim.imu.upper/windows.parquet": { + "bytes": 7645, + "sha256": "ff4ca0fbfed45e13e95f73d03d8ba56ce0f8305868012ecb5101df277a449ba9" + }, + "package-b.mmsession/processing/jobs/retained-prior/figures/emg_sim.emg.main_channels.png": { + "bytes": 93063, + "sha256": "87a315c7e23f334c9c8065cdab60ca26b8af8b965bd0ebaf33645864d0048124" + }, + "package-b.mmsession/processing/jobs/retained-prior/figures/imu_sim.imu.upper_accel.png": { + "bytes": 24298, + "sha256": "8cc603bf604d8925ba13be2c77e0bd8d8f8efbce9529e7d459a449fd61e6a8a4" + }, + "package-b.mmsession/processing/jobs/retained-prior/figures/sync_dashboard.png": { + "bytes": 37408, + "sha256": "07ebc1ff60a592f2086dcdfe63652666946329dbadf29dece5b6c84f87dd6082" + }, + "package-b.mmsession/processing/jobs/retained-prior/figures/sync_dashboard_series.json": { + "bytes": 1964, + "sha256": "01cdce9f387ad77ac1ea7632cee3c1d84fc879671cbf46e195c64bf1ec4a8c52" + }, + "package-b.mmsession/processing/jobs/retained-prior/job_manifest.json": { + "bytes": 4508, + "sha256": "95acf1efa8439e47fc5b011813f2fc5313a92de692f25459e3d56e68533a0389" + }, + "package-b.mmsession/processing/jobs/retained-prior/logs/job.log": { + "bytes": 179, + "sha256": "f0c184fbf12257a9ad4e41329ab95a5578ca769ca5fb84d9b9a32a18df8d7f46" + }, + "package-b.mmsession/processing/jobs/retained-prior/params.json": { + "bytes": 252, + "sha256": "9c0e1ab18949727f29352f1a602ae65d74db48f8453a49faa72fbc95c518b35b" + }, + "package-b.mmsession/processing/jobs/retained-prior/reports/qc.html": { + "bytes": 1629, + "sha256": "93671b7b67b1bf290a50a7a8d69e6fee6968caa1e540bf0615add4d0d1127671" + }, + "package-b.mmsession/processing/jobs/retained-prior/reports/qc.json": { + "bytes": 1296, + "sha256": "0c3647238cffb1ae94177f950a9b1407a88e0730b4503cffd27118c4634bc706" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/job_manifest.receiver-held.json": { + "bytes": 2400, + "sha256": "92e19a48f6c45e672d82c898f3827c8f353bf9e4a705c50f0012ddb033f2e845" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/logs/job.log": { + "bytes": 187, + "sha256": "75632168a67884e1ae52815a3ea0d9d3826f2d57f6ea8c23f1fa3f72a7591938" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/params.json": { + "bytes": 260, + "sha256": "564c6f9ab9fc6eed20ffe5a8de9fd55533f59d2783e38b1217cb65f88358b20a" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/reports/qc.html": { + "bytes": 1629, + "sha256": "93671b7b67b1bf290a50a7a8d69e6fee6968caa1e540bf0615add4d0d1127671" + }, + "package-b.mmsession/processing/jobs/selected-before-missing/reports/qc.json": { + "bytes": 1296, + "sha256": "0c3647238cffb1ae94177f950a9b1407a88e0730b4503cffd27118c4634bc706" + }, + "package-b.mmsession/sources/sim.emg.main/health/gaps.jsonl": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "package-b.mmsession/sources/sim.emg.main/source.json": { + "bytes": 112, + "sha256": "4e7626e51bfb804c27f83bf98ee186a47ec9f36fec0cbd7863ea8ecb1ecfbd10" + }, + "package-b.mmsession/sources/sim.emg.main/streams/sim.emg.main.batch/segments/000000.mcap": { + "bytes": 1094, + "sha256": "9e997481c9b39b6a6b2d647df873fea26b04337c41571e77427a7f8ca9cda63b" + }, + "package-b.mmsession/sources/sim.emg.main/streams/sim.emg.main.batch/stream.json": { + "bytes": 224, + "sha256": "5307697f957309eaca816fa0e20c4799c900e2598a8acf66a59928aa83b305b2" + }, + "package-b.mmsession/sources/sim.imu.upper/source.json": { + "bytes": 118, + "sha256": "a6198f509edc557c1e1d8583a767a540962977751c80a1b6491e3d594b60c7a8" + }, + "package-b.mmsession/sources/sim.imu.upper/streams/sim.imu.upper.frames/segments/000000.mcap": { + "bytes": 1678, + "sha256": "c477a0e0865086fbb4154c977def4d93ea5fb38cc098a4862c45b21b966014c9" + }, + "package-b.mmsession/sources/sim.imu.upper/streams/sim.imu.upper.frames/stream.json": { + "bytes": 219, + "sha256": "ec39026bed1b833d4decb0ef7b0efb94c5557a5647bc50addc060bef3a30d50d" + } + }, + "fixture_root": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native", + "helper_sha256": "b46094d3d823145aa07aa088371c6a63343ee7c5d8a06b254c6a4669f8c52da8", + "loop": "QApplication.exec; state-machine actions via QTimer; no manual processEvents, QTest.qWait, source edits, worker replacement, or retained worker/thread reference", + "method_sha256": "cb2e6486fc13e6e180fc6e8f83d690f3b3cab84faffce6a7c7b0e3fde791a3cd", + "pass": true, + "process_return": 0, + "result": "All independent native QApplication receiving checks passed on exact corrected candidate", + "runtime": { + "pyside6": "6.11.2", + "python": "3.12.14 (main, Aug 25 2026, 14:00:49) [Clang 22.1.3 ]", + "qt_platform": "offscreen" + }, + "schema": "capturesuite.history.independent-native-receiving.v1", + "screens": { + "before_late_delivery": { + "history_loaded_job_id": "", + "inspector": "No job loaded", + "last_job_dir": "", + "linked_plot_count": 0, + "open_folder_enabled": false, + "open_report_enabled": false, + "package": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/fixtures-native/package-b.mmsession", + "png_count": 0, + "sync_title": "Sync dashboard", + "tabs": [ + "Sync" + ] + }, + "late_qc": { + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/native-late-qc.png", + "sha256": "eea35e5b9fa6babf0971927bbb6d4365847d7181d55ec2b99334fe56b4ab5131" + }, + "reopened_a": { + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/native-reopened-a.png", + "sha256": "3250ff333afde60db4195c0a3df7132008cd74601d5e52ae66acbb5c7da9396e" + }, + "reopened_b": { + "path": "/dev/shm/hamon-401c5d17da79-capturesuite-receiving/evidence/native-reopened-b.png", + "sha256": "810766243e7848e2aa966a588c1c4e2245ad74526870a810232ce89db56635e8" + } + }, + "seconds": 0.9143500069985748, + "source_imports": { + "capture_analysis": { + "path": "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/__init__.py", + "sha256": "14cfe6dccd33a0bda74fac3c9339e1a37a3538b2110a8ae6e307801b776eb43a" + }, + "capture_analysis.jobs": { + "path": "/dev/shm/capturesuite-history-401c5d17da79/source/libs/python/capture_analysis/capture_analysis/jobs.py", + "sha256": "e7e9dda44eb014d18192563f1e2c0ae78cece850fbc853b0be3919daaf5ee276" + }, + "capture_desktop.screen_analysis": { + "path": "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/screen_analysis.py", + "sha256": "98a704e31b14497e012fe5618ad47cc8a772bd2d59775826d71a5bdf41533211" + }, + "capture_desktop.widgets_analysis_plots": { + "path": "/dev/shm/capturesuite-history-401c5d17da79/source/desktop/capture_desktop/widgets_analysis_plots.py", + "sha256": "85c73f881ee7d60ef2f868f7ff73fc57c0a4ef99a717f7f5015534db23e1ab86" + } + }, + "source_unchanged": true +} diff --git a/docs/evidence/analysis-history-401c5d17da79/independent/native-candidate.log b/docs/evidence/analysis-history-401c5d17da79/independent/native-candidate.log new file mode 100644 index 00000000..ee6a1fb8 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/independent/native-candidate.log @@ -0,0 +1,23 @@ +This plugin does not support propagateSizeHints() +fresh screen reopens real prior A result into native gallery and inspector True +package switch clears prior result and both launch targets True +This plugin does not support propagateSizeHints() +same basename in B resolves B figures and metadata only True +malformed-manifest is visibly unavailable and refuses Open without replacing B True +missing-manifest is visibly unavailable and refuses Open without replacing B True +foreign-session is visibly unavailable and refuses Open without replacing B True +foreign-directory is visibly unavailable and refuses Open without replacing B True +unavailable-row actions leave every saved byte unchanged True +Open revalidates a cached row after its manifest disappears True +refused cached Open preserves all bytes after the controlled rename True +This plugin does not support propagateSizeHints() +real QThread QC completed and persisted before receiving release True +prior-package real completion cannot bind current B gallery or inspector True +prior-package result is explicitly retained for later inspection True +current B saved result reopens after actual Qt thread completion True +returning to A explicitly opens the genuinely completed late QC True +late delivery and later reopenings perform no persisted writes True +all captured raw data remains unchanged True +no Qt error dialog or native worker failure True +frozen source bytes remained exact throughout native receiving True +{"pass": true, "checks": 19, "seconds": 0.9143500069985748, "code": 0} diff --git a/docs/evidence/analysis-history-401c5d17da79/publication-composition.json b/docs/evidence/analysis-history-401c5d17da79/publication-composition.json new file mode 100644 index 00000000..d80c118f --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/publication-composition.json @@ -0,0 +1,469 @@ +{ + "schema": "hamon.current-source-composition.v1", + "repository": "Jacob-Met/CaptureSuite", + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "canonical_tree": "18e97093f04de23de5e9878fd22c1f5ed986d5f3", + "author_base": "72c15d6b623e217291a824e4e4808a385df896a9", + "author_final": "495b8d45b0b9aa2231bccb315bd68e762a240143", + "author_tree": "08a4a99b6c7556be50d77bb4d5368fa484802b1c", + "original_accepted_runtime": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "current_qualified_runtime_tree": "167bbac3bba862cc1532d954fe2d503e561a00df", + "current_screen_blob": "6893f119593f8ff6551167efcb1939d014a081e6", + "current_screen_sha256": "1475764b8453ed870174fcaf98bc02370db76b5001c4175feb93263ad33d5b70", + "merge": { + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "author_parent": "495b8d45b0b9aa2231bccb315bd68e762a240143", + "base": "72c15d6b623e217291a824e4e4808a385df896a9", + "returncode": 1, + "stdout": "355c4353dc72525d6b2955818b8016588d411953\n100644 ef608ddb93c86c0d0c057b703e40b897e16f8a4a 1\tdesktop/capture_desktop/screen_analysis.py\n100644 78905bbde5de536dad125b6e4e48a475e9b14272 2\tdesktop/capture_desktop/screen_analysis.py\n100644 966f89f8cfad679a4a461900569365c50476581b 3\tdesktop/capture_desktop/screen_analysis.py\n100644 b62d86046bd072f09fc2d3c9df4f77b711a8a214 1\tdocs/design/research/PROGRESS.md\n100644 99c812ac6b3776c41e3244a90f46f2e9f366be08 2\tdocs/design/research/PROGRESS.md\n100644 0be69fb4f408dfa93e0f39364c6702c4fe9646e2 3\tdocs/design/research/PROGRESS.md\n\nAuto-merging desktop/capture_desktop/screen_analysis.py\nCONFLICT (content): Merge conflict in desktop/capture_desktop/screen_analysis.py\nAuto-merging docs/design/research/PROGRESS.md\nCONFLICT (content): Merge conflict in docs/design/research/PROGRESS.md\n", + "stderr": "", + "conflict_paths": [ + "desktop/capture_desktop/screen_analysis.py", + "docs/design/research/PROGRESS.md" + ], + "screen_resolution": "Preserve the current scope owner's normalized identity, conditional reset, summary/enabled refresh and package_loaded signal; pass the same resolved path to history.", + "additional_runtime_change": "After the concrete startup negative, treat a retained _thread handle as busy until unchanged cleanup clears it.", + "progress_resolution": "Prepend the new receiving entry and exact original 25-line author entry to the complete current PROGRESS bytes." + }, + "runtime_boundary": [ + "desktop/capture_desktop/analysis_history.py", + "desktop/capture_desktop/widgets_analysis_history.py", + "desktop/capture_desktop/screen_analysis.py" + ], + "unchanged_current_scope_hooks": [ + "_AnalysisWorker", + "_on_thread_finished", + "set_scope", + "_scope_error", + "refresh_from_state", + "_refresh_summary" + ], + "authored_history_modules_and_test_bytes_unchanged": true, + "progress": { + "author_entry_lines": 25, + "author_entry_sha256": "cfc83c07fdcc381d7997bf2ccd5d413498ce03500cb6ee2f6f76c29ae05f562e", + "receiving_entry_sha256": "05d12052347587b051f4dff32b4e38ddf8bcfa055936078dbe735ee035a9e79d", + "complete_current_bytes": 41867, + "complete_current_sha256": "67ac05cfb502beeeb48bbaf89952426a5cd389c3c0529dcdb6e1669ba72e72ec", + "current_is_exact_suffix": true, + "merged_sha256": "02a1b11ba531c2093107dead9e6472bb516ff3863e294234c2da122d061a13af" + }, + "qualification": { + "author_and_retained_tests": { + "source": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "base": "72c15d6b623e217291a824e4e4808a385df896a9", + "passed": 14, + "skipped": 0 + }, + "independent_native_history": { + "source": "37443f0d4d5ffa684b5423d58501856cadbe0655", + "base": "72c15d6b623e217291a824e4e4808a385df896a9", + "checks_passed": 19 + }, + "historical_qc2_successor": { + "parent": "e43da3b855475c8aacf815c201fa03eddaeec0f1", + "runtime_tree": "ba5b4b925b00ecb17895a8c8ad29410e787f97dc", + "checks_passed": 14 + }, + "current_scope_history": { + "schema": "hamon.current-scope-history-receiving.v1", + "canonical_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "runtime_tree": "167bbac3bba862cc1532d954fe2d503e561a00df", + "screen_git_blob": "6893f119593f8ff6551167efcb1939d014a081e6", + "screen_sha256": "1475764b8453ed870174fcaf98bc02370db76b5001c4175feb93263ad33d5b70", + "receiver_sha256": "c45eb2b2b02b8c9423565d811ae7782eff576b1313bf5cef366c4af8bf4e3802", + "process_exit_code": 0, + "seconds": 3.534, + "checks_passed": 24, + "checks_failed": 0, + "source_files": 142, + "source_bytes_unchanged": true, + "raw_package_bytes_unchanged": true, + "frame_sha256": "c8ec0afb810a76da3254e035cdac3a5e0ec46097976743e1917e672441a550f5", + "visual_review": "The current native scope picker and saved-history row are legible together. The very long private package path wraps and clips in the existing narrow left control column; this is not a complete layout or Windows MainWindow acceptance.", + "startup_control": { + "source_blob": "ee2db9acacdc92d3aa8ba0bfe12f638e9418f9b4", + "runtime_tree": "07d78241dca691015bb3e4d8d260b109672b7de0", + "method_sha256": "44c24508e4e4aa9d14d1771be486bb953f8b3719652183c2e9d7c3bb81ac2b17", + "passed_before_stop": 2, + "failed": 1, + "receipt": "startup-negative/receipt.json" + }, + "receiver_adjustments": [ + "Accept the existing completed_with_warnings status only with both exact expected fixture metadata warnings and exact saved range.", + "Explicitly verify Run/history controls restore after each completed worker.", + "Emit complete receipt and native PNG in stdout so artifact transport is independent of the native journey." + ], + "nonaccepting_continuation": { + "method_sha256": "1f7029cb84c999feed1b5b636d65551a75938f5875d09bbff20065aa9d1cc0b2", + "cause": "ENOSPC while writing frame/receipt and supervisor artifacts", + "receipt_bytes": 0, + "native_outcome": "not accepted; no complete result claimed" + }, + "qualification_limits": "Original 14 tests / 19 checks remain on 37443 and 72c15; QC/2 remains e43; current numeric nested-gallery limitation remains separate. No full Windows, MainWindow, daemon, hardware or installed-release acceptance." + }, + "current_numeric_gallery_limit": "The existing top-level PNG discovery gap is preserved at its exact 0ed+history input. Root assigned its separate gallery repair to production_discovery; no gallery source is edited here.", + "not_claimed": "Full Windows MainWindow, full suite, daemon, hardware, installed release or complete latest d43 main acceptance" + }, + "ownership": { + "history": "estate-401c5d17da79/production_discovery; issue #55", + "independent_original_history_receiver": "estate-401c5d17da79/estate_coordination", + "current_parent_composition_and_receiver": "estate-401c5d17da79/integration_discovery", + "scope_picker": "Merged PR #58 / issue #53; every current scope hook and unrelated byte preserved", + "gallery": "Separate production_discovery repair; unchanged in this source" + }, + "freshness": { + "schema": "hamon.capture-history-publication-freshness.v1", + "repository": "Jacob-Met/CaptureSuite", + "qualified_parent": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "latest_observed_main": "d43bdea867d6198a707a5f55e29216c76054517e", + "source_url": "https://api.github.com/repos/Jacob-Met/CaptureSuite/compare/3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e...d43bdea867d6198a707a5f55e29216c76054517e", + "compare_html_url": "https://github.com/Jacob-Met/CaptureSuite/compare/3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e...d43bdea867d6198a707a5f55e29216c76054517e", + "base_commit": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "merge_base_commit": "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "status": "ahead", + "ahead_by": 3, + "behind_by": 0, + "total_commits": 3, + "commits": [ + { + "sha": "0dd591b41bea35ce0639bba312d6f56b77f68088", + "parents": [ + "e43da3b855475c8aacf815c201fa03eddaeec0f1" + ], + "message": "Preserve missing pose evidence in kinematic labels\n\nMask non-simulated landmarks by each joint's required finite geometry and confidence instead of selecting synthetic fallback angles. Retain independent limb validity and NaN velocity/AFR values at invalid frames, with unchanged complete-geometry and explicit-sim Parquet bytes.\n\nReceive the frozen 21-test native author result, independent four-workflow/36-assertion CLI review, and one current-QC/report CLI composition check. Preserve all 777 unrelated current-main leaves and the complete current progress log. Existing supported Windows CI remains required before merge.\n\nCloses #56" + }, + { + "sha": "711e8ec22d462b7588e52727cf3d6524d7524c7a", + "parents": [ + "0dd591b41bea35ce0639bba312d6f56b77f68088", + "284d168d7614e2465bafba1092d8cbe4b6e13b40" + ], + "message": "Merge current main and retain both kinematics and storage progress entries\n\nPreserve all37 frozen non-PROGRESS contribution leaves and all815 unrelated current-main leaves. Resolve only the concurrent PROGRESS prepend, retaining the exact current log plus the original1527-byte entry. Runtime, regression tests and receiving evidence are unchanged." + }, + { + "sha": "d43bdea867d6198a707a5f55e29216c76054517e", + "parents": [ + "3e3ecc5ecc1cfc79c79901eb5cffe10b0ec5852e", + "711e8ec22d462b7588e52727cf3d6524d7524c7a" + ], + "message": "Preserve missing pose evidence in kinematic labels\n\nKeep absent or invalid non-simulated pose geometry masked independently for each elbow and shoulder. Preserve complete-input and explicit-simulation math; only explicit sim_ models select fixture equations.\n\nQualified source head 711e8ec22d462b7588e52727cf3d6524d7524c7a with the current desktop scope and Windows atomic-write changes in actual CI checkout dc9ab33f4b3f3aefbb6308bbffb4e3f041d4b524, tree fea0e03773742d330963b89e0ceb72a22c7ad495. Windows run 37786404581 passed 400 Python tests with six missing-daemon skips, all 30 CTests, and all six separate native daemon/recovery cases without skips. All existing workflow gates remain unchanged.\n\nIndependent real CLI receiving passed 4/4 cases and36 assertions; baseline complete geometry and explicit sim Parquet bytes remain exact. All37 non-progress contribution leaves, all current unrelated leaves and the complete prior progress log were received from current3e3ecc5e. Original negative evidence and both CI generations are preserved. No installed release or physical measurement claim.\n\nCloses #56." + } + ], + "files": [ + { + "filename": "docs/design/KINEMATICS_PIPELINE.md", + "status": "modified", + "sha": "4206818b8834c56db530ca939b04cfe59e73aff6", + "additions": 24, + "deletions": 0, + "changes": 24 + }, + { + "filename": "docs/design/research/PROGRESS.md", + "status": "modified", + "sha": "36b05b80604935e3c70d1f076be5150e8639c164", + "additions": 24, + "deletions": 0, + "changes": 24 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/README.md", + "status": "added", + "sha": "5eee94afdfc2af12ad806fb816c3a9bf7f56f480", + "additions": 113, + "deletions": 0, + "changes": 113 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/author-receipt.json", + "status": "added", + "sha": "c51c2acc07ef57aae579c908f1fe3c31bb4b472c", + "additions": 60, + "deletions": 0, + "changes": 60 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-native-readback.json", + "status": "added", + "sha": "2110facf1a59ad9c1656aed76a09fad3cf8496cf", + "additions": 7, + "deletions": 0, + "changes": 7 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-runtime.tar.gz", + "status": "added", + "sha": "e973cff1bb0a0bffd768bf9fcef5400834ab2280", + "additions": 0, + "deletions": 0, + "changes": 0 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-source-manifest.json", + "status": "added", + "sha": "90416594a540a5227a70071b7597c87b291ff8de", + "additions": 812, + "deletions": 0, + "changes": 812 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-tests.json", + "status": "added", + "sha": "dc03cfdffaabb0209fd855482e78abb21179a658", + "additions": 298, + "deletions": 0, + "changes": 298 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-tests.log", + "status": "added", + "sha": "16860275d5331b2398cf48b0a2dca14601534df8", + "additions": 289, + "deletions": 0, + "changes": 289 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/baseline-tests.xml", + "status": "added", + "sha": "ed4db6467dd4d1410cc51e45097269ced09ef5c6", + "additions": 232, + "deletions": 0, + "changes": 232 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-native-readback.json", + "status": "added", + "sha": "369ab414496f49d86b28afa8a7a78b6b1e7a4e92", + "additions": 12, + "deletions": 0, + "changes": 12 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-source-manifest.json", + "status": "added", + "sha": "4fb157009d615aef9c7e000355df2d1750d56392", + "additions": 35, + "deletions": 0, + "changes": 35 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-tests.json", + "status": "added", + "sha": "15e3c7ebfc9af89e52f7d9ad5c31aaac0bf22d9f", + "additions": 301, + "deletions": 0, + "changes": 301 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-tests.log", + "status": "added", + "sha": "c124b9b2ffcbebd9cc3e5f87ac061017abf78741", + "additions": 12, + "deletions": 0, + "changes": 12 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/candidate-tests.xml", + "status": "added", + "sha": "6c202590a276a097c6b037d7939dce273fc5aaf2", + "additions": 1, + "deletions": 0, + "changes": 1 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/environment.json", + "status": "added", + "sha": "345664d3eb842ccc52018d36bd81cd9e892463ff", + "additions": 19, + "deletions": 0, + "changes": 19 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/manifest.json", + "status": "added", + "sha": "e96529b2c4475276c8483ca62414875ff049b596", + "additions": 100, + "deletions": 0, + "changes": 100 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/product.patch", + "status": "added", + "sha": "5f5581fb530ed1ee5f45ae89116dd772b2c00ca8", + "additions": 430, + "deletions": 0, + "changes": 430 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/static-checks.json", + "status": "added", + "sha": "fb1093707700a5fbbc746d7fcb3d4d6a29f6f0c6", + "additions": 28, + "deletions": 0, + "changes": 28 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/test-artifact-manifest.json", + "status": "added", + "sha": "b84b3cbc9bc474efa700cc7e1d632b162628ef1a", + "additions": 1665, + "deletions": 0, + "changes": 1665 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/test-artifacts.tar.gz", + "status": "added", + "sha": "692f10a8452e12ef0060177a89648ba0e247e9fc", + "additions": 0, + "deletions": 0, + "changes": 0 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/author/test_kinematics_validity.py", + "status": "added", + "sha": "7cf66857bcbeb9b72851ad53ce7c08f97d528fc8", + "additions": 202, + "deletions": 0, + "changes": 202 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/README.md", + "status": "added", + "sha": "5e3b6e546922665e6639b3a4f49c837983fc56f5", + "additions": 43, + "deletions": 0, + "changes": 43 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/junit.xml", + "status": "added", + "sha": "e574c6fab6ed3890ac856040421e2a576f385607", + "additions": 1, + "deletions": 0, + "changes": 1 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/manifest.json", + "status": "added", + "sha": "741306eabe2798bdc0927e34773cf9f7478b312a", + "additions": 51, + "deletions": 0, + "changes": 51 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/process.log", + "status": "added", + "sha": "7e1ead8287c87a8d972a2cf50390981926c5dd1a", + "additions": 12, + "deletions": 0, + "changes": 12 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/receipt.json", + "status": "added", + "sha": "75d0d3aee60e47679da6672ee3e9c8ec07b16d8f", + "additions": 300, + "deletions": 0, + "changes": 300 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/receive-current-seam.cjs", + "status": "added", + "sha": "cdc7717acd47e6776ca9c1afc100e429cc6e5ea9", + "additions": 16, + "deletions": 0, + "changes": 16 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/source-manifest.json", + "status": "added", + "sha": "6cb4dfce021abbeaff5e7e1b36f10c5822c9cdb6", + "additions": 818, + "deletions": 0, + "changes": 818 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/test-artifact-manifest.json", + "status": "added", + "sha": "4747226f7cb788048bdf0593ad3f82911da0b4eb", + "additions": 130, + "deletions": 0, + "changes": 130 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/current/test-artifacts.tar.gz", + "status": "added", + "sha": "30a23f4ce7066ac1db085ea21179b763f3ad0829", + "additions": 0, + "deletions": 0, + "changes": 0 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/README.md", + "status": "added", + "sha": "355804bd71cd836250a57126b3fee28a47f233be", + "additions": 13, + "deletions": 0, + "changes": 13 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/independent-cli-artifacts.tar.gz", + "status": "added", + "sha": "739fc581cae5561014b45049f225a2d4abdc2a6f", + "additions": 0, + "deletions": 0, + "changes": 0 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/manifest.json", + "status": "added", + "sha": "b58ee77faebd30f53581475d4f4a931cf54c64e6", + "additions": 30, + "deletions": 0, + "changes": 30 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/receiving.json", + "status": "added", + "sha": "4e63e2efd9e71728329abf66fe283597ee8ee815", + "additions": 59, + "deletions": 0, + "changes": 59 + }, + { + "filename": "docs/evidence/kinematics-validity-20261008-406d0fb04c43/independent/source-review.json", + "status": "added", + "sha": "bbfb3c062188f4287388741cfd526d07249f5177", + "additions": 26, + "deletions": 0, + "changes": 26 + }, + { + "filename": "libs/python/capture_analysis/capture_analysis/kinematics/compute.py", + "status": "modified", + "sha": "fb8be59b00e15d9c264aad0983cf75a757c9e210", + "additions": 53, + "deletions": 43, + "changes": 96 + }, + { + "filename": "tests/analysis/test_kinematics_validity.py", + "status": "added", + "sha": "7cf66857bcbeb9b72851ad53ce7c08f97d528fc8", + "additions": 202, + "deletions": 0, + "changes": 202 + } + ], + "decision": "Retain the qualified actual 3e3 parent. This later merge changes only the kinematics compute implementation, its tests/design/evidence and shared progress. The accepted 24-check native journey exercised numeric features; no desktop/history/scope or numeric-feature source changed. These receipts do not claim complete d43 acceptance." + }, + "prior_0ed_composition": "Preserved immutable in its own durable source packet; its 57-file payload and receipts are not relabelled as current 3e3 acceptance.", + "publication": "Prepared source handoff only. The final actual tree/parents are recorded by the external publication manifest; no GitHub acceptance or installed state is inferred.", + "current_start_job_hook": { + "difference": "The authored history integration replaces the two direct gallery/inspector clears with _clear_result_view().", + "proof": "The entire current _start_job AST equals the qualified one after only that explicit two-statement-to-helper substitution. The method is exact between the initial composition and the busy correction.", + "worker_and_cleanup": "The current worker class and thread cleanup ASTs are exact." + }, + "documentation_precision": "Correct the initial prepared packet wording about _start_job before publication. The qualified runtime and every native method and receipt remain exact." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/publication-license-check.json b/docs/evidence/analysis-history-401c5d17da79/publication-license-check.json new file mode 100644 index 00000000..b74620ab --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/publication-license-check.json @@ -0,0 +1,11 @@ +{ + "command": [ + "/workspace/scratch/234cae4aee53/capturesuite-venv/bin/python", + "tools/check_licenses.py", + "--enforce-spdx" + ], + "exit": 0, + "observed_stdout": "license check OK\n", + "runtime_changes": false, + "correction": "Only two copied evidence scripts received required GPL-3.0-only SPDX headers; original tested bytes are preserved in1ce96118 and recorded separately." +} diff --git a/docs/evidence/analysis-history-401c5d17da79/publication-method-adjustments.json b/docs/evidence/analysis-history-401c5d17da79/publication-method-adjustments.json new file mode 100644 index 00000000..5cb192a5 --- /dev/null +++ b/docs/evidence/analysis-history-401c5d17da79/publication-method-adjustments.json @@ -0,0 +1,20 @@ +{ + "schema": "capturesuite.history.evidence-publication-adjustments.v1", + "original_methods_preserved_in_commit_and_durable_packet": "1ce96118aac40f6747b75d39ff7d72e8693c8946", + "changes": [ + { + "path": "visual/details-visual.py", + "original_commit": "1ce96118aac40f6747b75d39ff7d72e8693c8946", + "original_sha256": "f934e4db27257eb5e66c1dbb341a4b0949a3c3fd15cdaaf144493d7df7ad55d9", + "publication_sha256": "c747bcb5bf519b765186e93b4689666148f6bae1b4c45014adda424371c694ab", + "difference": "Prepend only the GPL-3.0-only SPDX comment required by the unchanged repository license gate; executable bytes otherwise unchanged." + }, + { + "path": "author/baseline-history.py", + "original_commit": "1ce96118aac40f6747b75d39ff7d72e8693c8946", + "original_sha256": "0425023978d39e9bfd1dd3765781220962328d6a309be3005c9a2f1fd3f5214b", + "publication_sha256": "ae3d803367e60939f9b777f2196bd4e59e0e2ed169929b1260ec391279f66538", + "difference": "Prepend only the GPL-3.0-only SPDX comment required by the unchanged repository license gate; executable bytes otherwise unchanged." + } + ] +} diff --git a/docs/evidence/analysis-history-401c5d17da79/visual/details-log.png b/docs/evidence/analysis-history-401c5d17da79/visual/details-log.png new file mode 100644 index 0000000000000000000000000000000000000000..9ef1136cf724a387dcfce2c02ed046127b96bf63 GIT binary patch literal 35244 zcmce-b8w_z&_6n{u`xHct&KJ|Cbn%m*<_P!Y}>YN+qO2gb+h01{oQ|W-Ktx+YNqCy zbIv@~PfwrjPj`P#h`g*A0xS+J002Oc5EoVi0Knh@08mC~(65pFSx?!o4;VXfbw>aI zvH#y2B!LDI7XTmxNC*omxuu_N7;B+v;sUNrOE@Oy(x}fLVXT^6BdlCi$?_|m8kJtsvjexwpdf%l#FJm6SxQ_+u zrvXN;wh6w>#j`ED6WvuGiy+~%B+^aF!j(4~gCkq5mbqo+;Eqcu2&mUB&W@3aCY6i_ znw4IUm%+WI3y2_asP&fWEkkM3gileltJ|2B9Mj1l6X4dZx@emDk*qB9lOwTUD5mS} z)kO2j<;ztSE@a9C5B#1}!?c$(ufi2j_T@`|0V{=`MeTp!2ByzVi{1=L*JRT-3keG( z3m%}DHx8}R2|bNRkhjt?4B0O>S$Vx@Kd`?0RdZ7P_3HM%6`@J}_7^787Pn?s9~&T# zCdlf+G%`A##DS!({Jp_aAY)4G0%yjRAqWH@?v(E9lA$F&-_$5a{2XuDRhP?(1xY`I z*ofq=BmK*0=s4}D0bYaGen!)bNB=!2f*#wZC^m2_`AIH_#V(ex>#|PC-QlVuD;_Dl zr~A+4gg8EDWE|;pK*w>}_5^ogE%I$CGm2~S+5>xNH$LCC%LM4^lLTcvuv zkD!lA8$`EJ+ciTt(`K>8N#P;pI>oTv|rHNi`e>2=<{%;o>E%a>GhU8~w)JJW0Zi^ra z`CLoePMTQFf?rL97_IKHMTy`+N9%Jocy{rjAG^>YL-KS{0`a7bkCWFL$fr}z#cx9~ z>B?|ze0fn2Kv|!ESXoWQq^BWx7O+p5&a^z8V_GRiL zelzfbhXPwUmTOuLGf}hXxLvLszZb^$#s^=t zt?w=Hi|}f_VoM$bW?ikPEsuCV_kUjvAJ6utX?it90VJm%7mI`q-p?nY9(H-#IStKh z(}H|Cf-U2+{yB(2c2Nt-v)*pr+&b273oZ|vrQ*J%g~rL^=MX1TD4N}vU|WY407|7B z1mfe_*0uP!Bi}RC`XlN#9Rh?rgLo`+b=JX!g=Hx@5v62Hm+Jukjus#rnn<_%Xo-hJ zsAH*o0S>Z3KdAuHQ;fy(!zX`q@6CJ9&zLuRvxk(3FeDXz<<5j}t=xhj`5(d3c}u8_-l)&!O8I7e*B>TzlTx89+|u_@8Qiqf6H!R2UkjY=6XE(_O@ zH2fqo>dLHgNEv;d)Og;SQOY#vC`w`8c-?|KH=G-MYO2k#e!Ovhv8@d91E6<*-OfgC zbJK45{8CBbiW|65Fz$(4($3Fh5B$BkgpjaRJ&4mNpf&V7{4Joak0TgWmu)rB)p?2b zn50P0{b`l*Cvv0ZZY5*Tj-R^}#ag`zxQ)ZrvG(g_#}UYwMPG;gz>(tJi_3Jmj~998 zmeaBKo=ayrBp|v$$9IHmVdLEDB*`8c_`P*%jr+jMo<<5kGS^9P`qu=7E?Vrr$HA1^ z@UC30(}Wu--T*#|!SX-Kq@JeOHeSu<-YCb(wUYqsypvF0StBD>uR%{t$n7?$24vt) z^W7N-oYs4vN!m_FP@ijD5v_SXSd)smY@6FfOzF@es4w1v=$dBhPgHxx_iQ^61B_*c zY*P4VwF1wq>rDc^KVICV>K^?XNCqHZGCWvE`K=XEu-T%*%2} zb+PS*S#bbTOZwL*E9@TQx&6T${PV01tD6YT`WujT$L;I1uSvi|-7z8%0EZo~yTIjo z^L@_&;ml;M_h49G0ot}?M#hF|R5fFC@Xfec)xD)x7}Q09xkigyN9%H1iP7N$H=Xs+ z>t-E>Y>j2nXsNj8NrPjPts(^3=y)BE5rq^lI+;n(pN7k7Sud32Uoa}d2 zPL4&E=GeI!K{%*x&J2nQ4fa;BB5s;qp5z6+^9n8&h=2Ar!zC8C%FUB9oYdLb?Cw~+ zSf4Ow1-}ybjbgFAa#c+^1N zI2$RI{>l&(4<=stcFH7ISLiC|wcQVpW(U=!g4>`JONr~+JlpT<_J<-w5=;BS)?lg) ze+!YlPk3j>a}MoPrc$I#xf_ATiABNgmn+`)*4QE(hekkz01!Uyk{ZZ_Wct1Oy;kSx zKgLMZ1IB4NGo}wG&tRHihvXI5K}bP#k2F=dxo=(*nig><^BbI8#D%b=Jkpw%)V{tu z)gMAf+A;MPWxqfGdU&S=YlBi-+U%p7KJ%&a73!I&nk*x7Q31@{_jU1@6-xD&OJVQ` zZZySlICUGGkDDn_9mcy_GU6w@!E0ekds&X;VCTj5QqRjOV`uUKjFwCgDBe8YofN_x3=s{RRi~k zO@RumYTqt9OlFax+G57umnSW?CoC2ZNylFsy&7H0`=X8I8ceOW_!V{zb9dgwY-JhK zI9l3R0pwejJtn3P9b|oHcoY{B$7eM?Ed^%Js=ehbuY;r5aT!HtQ)f-p5487H)sxZg zjRcX}fA+i)yGIk1o&%O6);sO5{~Q@fA&>(Al}yuy1;&G$Fkq0<>#@@{zC$LJyrUX-mvqqAVY_Up&6`bLwbiTlmqQ_LPrs!=x>dp8152<@#(a6FvE^19Yfp;|S)kUq z;Zs`gFJ2{K87V#79YSse);{*wMNg(Qm|9)vl5;Helj}`C!b?y$s-)y}I7WWQxD4E? zNh|LQChhczwX&sWc6G={y}2CZJ98fXv#0IX*9!aD&GZ9m6i+fAZy z_`J?48GjiCn`<8a6>*DfXd0cJ6c>4aF6 z!ZHqQE=qD>M*QVBx?uAf58}c&6K#!c_QG*hfZO17Jb4N^HCPQh@t<*cYlWaAS&DSQ z*>}lrZhJp^9WwB6&49FftkI3ntdNoU6@F$F-}_E73gY*L7l+<38A2(wO#5GCWEWI1 zBdhE1Iqe%RqvZ_zbjQ(E~Q7 z1=0Bt+~#HnHMCiIu~zSty}w=M;w|M`?j(B=xK0Tw>##s_MLxKd+inHOxCYmTq=0_G ztJNm&(aI26Fw>XXbl%UDEpn^#<`1F7-)5~7^~$|Ch=inmPDMc#5Ww1uox-y&z2tz7 zy=baaTT)f|=8Nr?zCg?(glbniJU+`{UD1xNOS}7DG)p}3?h{yM9D0K(iab-wU~G2R z)?mQD7CFx^?*7FnsdyF!PJ@+?jB*>NyG9&N*VZL9X_)shLw^VHR`vWU=baLkmEs23 zAU)ljyt~F$%)6gtY6@L+$(yJ8wi%|&2}6u6^dFdrYvTy*7`uAtcbmGTI(u zkpO;FcX-PruP-rB1fvqUtUE8y@+~^N&i2eaoRkd#)^doDgex)A*Pt z7%8vrQIyby-(i1YTbBm;KR%hnIO5>f93B4r*TW}KQJ|aDI1TYbfZ;RDkEuCHa8mWe zzm9a$wcegG?GM|xQ?+FyH&5ADUMcfpn0aszy}6izO!HjxrF1;wSMso6=T zrKO*a>I?&bgO|Y&41EDRsNks4ztlJVlMhAce~t zh2Ei4D_341$_YN7ZvoOZ0T$X=MMZfc=Fz(4#q0y5KkW^{gyP`bN!1fBj_~Cz3{2!X zI-}VyZ3jGF1nMzFy#BbU8}RkE#4(2ztlO`fNwJgDktlzzGOlqiJN}f-bW5Db6Zg4( z<+zlhBvj0L7BNkPqtsUzH_lSSX904}6cz6lbw)Y-1_;|kU$U(5Es9R~i2vH{Xg^Nt z1*<`5=%MJZ7f`Uci)gfIu_`Ae@YMFu{E1v(pEL<6p|KX~Z^}IJ>EZSTlF+VqX7b)H z9yW{si~~B2`267D#%$>gzpo!{2bARnl*!jyv-CHc!e}7@M*783zJ&l`7O{*@2}j<6 zvbYovbAwfOS#nzjJh+kl82{eCx0_WO_l@$s0Kaj#2ZTvqy3SLbCbZYu67ahLUAAaR;Kd$~#42WH`H_1b9Tlu347y$uWWzW8Wl29R zMyVQIea!&^34yO7#gBC}10czRF5WA0?|Efk8*+N1{X|3IbJiTP6)D4UizSLs#G2xECCdO-*dGC36H89T>wfr-_Bl z>W+T86pwW`;`1GaY2Z6ptEmpJ6HAS-_&0QQTa;Rywny!w(1kHT-*QdY%^ZsNtn`55Z=;G@$9i=J#;fxnt?63|SMHZJXG%;C*fays8XX-yw;kmt(ST7cB%aD|gCXSY{V1@{OsOm^xegPQ>IKWRrN=isMp&1J+PC+4dIBev-6b44I4@?mR zKzMqyhS2#gGbGy*6-f~qBoi)_1x-F@GF^_{ zM+eU-9cwg9ssC%%c~DRtE_kzdnoWVNU|WPh(|O)|r}Q?@n0hXg5B7Olqo&^9K;7D{ zc|`>WjQC)FKjkt39Twq8TCD&8d37yd&K-jCtVQ3(R7blI$KKlEt$Iu6Ve;3_ULTrC9*70x|y^u2tty{Nt84=mX>SWWN0X~hf9wnCr7@{ z&;aF_EY;VT-u0j6-jVU)tk$ZfzA&dHlvTwedC|zs>a_4l%CQV1BNg}?x3#wt_y9n7 zqbpFp2m~N-Ak}3GceIS7a~E4zHz>r>SqV8ahdo~WeoVR@N}WDio-T^HbD}fQ>U@15 zoLpWS8ZO#|fLUSbGZL#WyjU)+l$3(cfV!qQHP8^)_*lvmYL#ZvjmJnsIF5>Fp^j- zISZ%+^xIwk!6z0H04A};p3m*V;f~o^R@vDEtIBO-G_y9m1q*2JQf~rtIdI^N5u&Ti=Y4w`o7&CZ7(C_*8WV0tRuSlOjkZ_uX^e zF`G+$2Mr|k8q0>C>tKk z{tepAi5F->i?)mN{*qSsd|B!JT~wMlJke0Kxnxs=(fv5s!GFf2bqR4YiIq`y>SIGH z0AtAKf?i1^_A)W0697n#or{#hw%r}26dYdl=~!IUNkfDnlhin&6@R@^%`0D6U+B19 znjpYc?=D(?Sn~?@nJlOcN(CoX1_4NE3)R#Y{{|1uJyFW`V*n@5JG^v|U{6yovME{3 zo#B{YW@rI5J3%D#&MN?vaS?p&{nFyXUO!e80G0*LsIdquo7f@vGg;g6J(Eg}CA#NY z-5=0Wn=ue+Y=G*V{18zFc=rP9ys%?}Mh8S-t9M=V&OJEtRUo{{IS2I$bA1!?i53x{ zwmG|)_G~@=p6EW;rI7f2=tN1dBN53DOpm#=lo`v83Lvd6Q&O5dR<=FkLiUr;h!I=2 zc15j?Oe$2;xE>t~@DtFDj)u}$*?#OP+k*nSmD^nQgtNTG z0NWxETF;F*R%gx`-T5(v_xHtGs3n!PM=?Hr}_lQ(YDj z5o|X>o$w)Q_CDV>m8Bqp&$zKspdp+qTgzE>iblQ!fs*QYnNm7}5lR4fZ|8-)-pOJyoQhcET9 zDFv?YGVAv-iCHmD+bxG%$cGd;rZqdQ@1nr4D7(YMQUSC?l-1|+P9V{{1m@}}D~)FY z(XnG>LH!tso~TUNmi+_37#r{*T`}K7)Zfl79KnvCI{A!HYRv(x!Hy-n0vmghX zuy@s-U-Xz?xDvR}2=3f~kt0nf4JMCjYf(5&_~4~3ro(>ga*3j3Xl&G0^j4QA44{0E5~V;r;SL zjB_i}DG<%^7Pvrd_Mn=zyW=H6Igv=ZGLzkXz810L+v>-krBCj5UY13_UcO44Gw zx)%~V@EB4*V*|kk^(4frle5AiPgmBOq}{Nh)iu8}h3L&%QR#dPojHKo$tDSUYtFa0 zHHRh`9<>8L`x&I3;3pdK@0E>KV7ax^RhzK`v$}5YNjQ4ld_QCPY=CqNWK7`$Ojf4F zek?0iq9aA&#C#AaFJS51-tKegcr+UU&?p^8`^}%_a0`Cps&I8uAF1+DzfDl(($hc$o;9fwSm5 zPBuND-3hc%kJc}iheo2?9go`NQ?-i;Js_qdO@F7yq_x+JPEy!waseQIG>EW z-8fI#Hh`AywPypjMMy;m>+?##<=kn>=0p)|J2n(jn^uO?fL|mrL2201Vw9EBZ@k(4 z?7QXuYJ$+je1SSjs3^N5`y{h0x9>9~WX@zUztH96=yrxcMoTo%215Hkb!)rLUSHVJNEWh}f z?O*s7tAsXsJl3K2O^B$wGw_7<6@fYHo26|;VxSadQgBl4;1bczh3;FEtq!!|<+N0^ zW#p&c0kPDGNa1XFOf5}?;N&?go}|Yd-(Ult_i2` z0bM`mXe6k$+o(hr_?U-1oekcdqYA{Pq^W6XWPM(l#ZUo$)Ud0aS|$(c5lQRHYQ44V zt}&`eKf+KFPSm?`AK5nMK2~A{K><1(Y|@1Vd%MO`^#@o+%9CZ9Ye-!fy^milgM~)V z;HYmyxY|jFV(I)=9VTPXI)M-cf!86naCfOGoXR+@t__E=fv+|#V<>_4NUoJ_$v;^w z(IwSJ=t@J@)QlI72Q_SzbK~>Tt^F}mI zUS8u|Y>){x@>O{~Pt}stVOIROEbZM#@9gSYBKaW6(PN(Xo^h}ip~@xQbMB5b9{S2e z36CBcH|T0}mU{jV7eK|9d#x(JnU#n8q(Y$Ma9=y|=?t4Vv`r4Y71{uad#W>C1e8&e zXW6`~6-~>OC^KJ17|Zouy!j}$PG{hmjEulwtI$^+uZPVFZ?)k0{6oGdhMCo4QirX! zp;Xv-@lww?N0 z+bj6Ig_$uic$9{Xw;#7?IBcHrE~z+Ty~URQj&^M8>&G9j(uJrxfeKK%jzhkv=H*Lc zRfkYW`hmn>1%UnAih|5A`Q58Qf1<^aEKuaKPiF{D33r4j#=(5=dVuC39e3~`v9QbI zITP@dxG6)*4@-;9ukJ=HQ13xKSK>L=oUJy4!}>fkG*$!z}f+whqWzFdXVXpRD=W--+y6eO2~A@{ve&jlfmHL8=%Cvi1XQ{m8b1 zJt{!?kX&o4m6eF*^&)31L-l(nV|y_t1vfdlZqbMVOl-S~706?Xn5}ifKxyc#;k)dG z2mOT}GjBJ~xW|WcmvOIZuvX$0{nPqrNiF8p=R-moX5Sp~uq;9K5Km^Pvzi9fFJ6%HY@HY-8B@u|< zBbRvc_Rr$!W*ecMfj}~%S9Y9A9hY5c5e4;+G7hE$YY>26jy0Eq+WqNm4}tF_uCy5x za_SdEqinr&Q%LdyR{Z@935VCgbGMml9=%baN9_|2&#O{_nyKoK+RZ!NU@A_VwjY!hC+lS^q<%_K z37EnC()VuN@4o`i_@}m*Ne!6KHy&(j!quC$?e41FFEE~AHx1r)Dqx`~@FP*_R9JcE z-(s*T3NtoK+|2Im7i79zu&g}LYe-LiPnBgkd4#{S0L$VkNfS;yBQM~7Lf-`UqSFRH z=6&CYc;39YD)X50&G`M1O=P{bjxhXHsk6h@XgXcu(-Pm&9>7U-XXvn`FmhT#@)VsB_z4Ab?Ek+;}((-IC+MO}Rgl zRGAC*W+^59__)`NruTnCX?`g7E-Jz{T3>OX+-cMO_WDl%>@kDmg^9)mhNucJB}cGi z+VD>ISB|3-%%`*Bdh(($$?KKL5t~w`K^qQ%ilDvDTg&ad9+||>M=_kZ>TDQ zid`O9Rxd8N{)Eu}gu|aXCO_)8`uX~jZ>HaU(q1J(pV|IrW~&%ma5n0UMS2fuBLU|> zW>bEpNxSq7)B|=Q&rVh|&HpY`P5nm7)b+KnDS!h2ATQy!TaY-?X`MB;=Ww;=e$I`~ zUn@>|6LKwp1cY1vFnE?+x;QcVDAPoeI>!rJY{Qcv#4%xRY3$zHC#=1oFH(z$jM>4tHEu88Xr1UZwG=#*4( z_kjjhNj#{)dF8w(i@5a4qTws}+u3N%ZQLjs+uF&`xHiQpoxiEQV2KMs2iA1X^y8_W zWzpTqqH&Q`tWj6#wcM@J4M*+gmYBw}I+$vpx!NU1^vN;uR7-t(cR!CPP!R*q@7vb~ zgqnSJcb*`1ed5m;t=~ykPT_){^Cg|qI}O{&UBCdsnx-5aasQsi|1HUDY;AGia+^-N z)02-fOb(`2Xmb6{>|Y62v~B1ztA&OQP-nfh8J>O10i>4j$MyaQ{d?fEl`Qd(U?%t> z)u~Sg6Q_{B(US%zfU%D;Zbq8rR;iU}!82unL4%QMQ+3ne#46U2P z6y@Jfqd%i(@>z@8lv7(bdasxbfLAY8Vr(dPh{g32xu@1k915jJB; zFH#TzMG<9?G4O0NmXQCkjzHU%4biTD|7+cSHjGLtZFs?^>FhMdOq6co-1+tE(1j#I z@9*uR{D~)`pjoWSY5QI*I4b0%{}rC!Yph%@VfK7G0tE1BEZ{IDvpJ?wJ+^0Sy}GX} z{!1$$A{E;@_`Re}5$tjSX6p7k4dQ01=zd4%JtOCuf)#n!jz7_VM)7Dd*ho75a7*t7 z{X;vF{9`)O&3CMF9x(3W$WTuB&xoFAngGK8Xm|UjW?$A_nZ5S2ld zKidMGXxVVNxVfuMOACPYVQhU)b14x0kE&-rc+UQxzN0_+w{HILYg|h4pa0G0{PHLL zZyp)v|NkL)uE>+iNicse4(ZbOrxca&rE4y5K;?W**R61HXU9GGHH>=uRtCqvhrfIX z3m}!=a5#x&ihTFDYi#_xI3OOU92=uR{1ixmmV|VSh-!M@BLY0u4O_6x*ea-C5iK6n z_Dq%dxLAJ!h{C;!*ce*Px6FjN=Pvq{-KVg4x95GobbjN2zE#dfZ~?`6k`+_;h@D5EG(xf(!TSpV2Qd`My*Ad2DiBk33>IKxjk4KR1eVJds7| z3W?h06pih2ob6?Vr-YSB>q4$7)>@bsey}#;g6N)RXEL#C*+PB#7AR2@nEPowJSvgY z!GQ8H??wD&2cJzJfrK!Wgc7majzFEEBNtZXxP)R>tmQ64IAv@M^-T2FyI;BvOd#D> zY)sv?Q)KCZt44tdr^#m2@nRV*Su3qsh6F;!5`?8v zThCkVpM_^g5nsvw2Kl%PuF;H!OsZ}?&YtT<)?5@zDG1{;;vR1zm+O-M_*I#!)aw*> zInd4fqnLNbR{%>8hObj%&U{OQkGl1@!AUZSD!Q zFd2T(ouVeeEX2$by)gRQ1dY>|@`vT_ZNVkj)JjF^lmiEL(9sl9pRP_e#+em6 zjk{nF5%KG)gcB6L=n?fwKK38N0$ebJc@=2qz7G~YWQEH%!&icc?qXG4Wsm^9zfH<5 z&c}CPnW^{tJ0#ltoh?VVQAoy&c4q*~_kCOf=m;BLN<-0!&PhXrR(fHc#m2CYbmld|=yPid9 z|HV6+H@I7Jp)H>t+Q$P&OxercPy~3{atx!6uuru?3c=xbA&j<>e?1#B(5ek zol&YOiIrxKI3*zi&*6eit-hO%^)DSV;OI2nwcvSZaY-A$`+DWVpsG6Xl;+pB5*tx7VdzOXH0pK_(nD|WlO<7M7ob) z6$J0dEc580{BpG6kVg%7GbX-Wd}<-}QxqL2CI<%!ER zpn(BML?D{rgrlT}NdELEqokwXiSd&-O>0u@w#+5O;9D?Y=c|PpGsDg3FHKQbP4w3+_@S6APVpt5J)F#eH9Cx^lED z>QeCitXpjk>BdL@KDx25d}$PEx#swygLMc7GO`S*Hp^S-VpSEB;uiGccY>;3R3@4_ z&)@J>H?>>kmd?PIecMS+gwWT~M~z6~<01=y%Q;fo(oY;Q%>i?CYJ`*cUFDl(yhwP& zg1<4=Um-R>)0bbII7}C+{{+F#rH;0&e7Df_5T%wC%9zjh#wY(gekH*;LHQYbC2%6M z`_I{*Q;wcRo3kJ265Fa6#{I#YG7!jxU4NJf_#A$bseJc7?e7ckhRacjbOBbNt0_6V zZx&&Fj?Y)27!030Uaa`W)1v+pI$P z(}5oWE^@4&G=6U_D1)=}^C!t0+{pWar%JyxtUy!=EoX5R0kdqLKX#)|eMR zoZt0_=hmd!*wJIy_|^Ym)@R?lp{1SNIF>5gQr8y>zuxXlT} zmF&TvQn~vZdv%(K5a{ggg|?Cy|Mc*INnFOw@$j*OKa_Qd(tXl!F-iLnCkGpJ0y~TTZHVJL{3Ov=lR0YQjIfN5#L)h% zl|{m2OXJ`oLD)Qk%c*u^fCx7e#!r9W#UgF}qsG(lH$Zxh>qxcEb{%MkXI4%OrQlg) z3r%ToygI3~YhqjKkKWNyXFE1y>b~m_8ZJ09-!qL@b|4-|D5DC#x=Vww?%qS>Rof;<593FLwCS9)6(<2_d-%&Ei>vIA zyK!gR%VsqXj0Ta9t`M+35T(`74_H^}jvk_kB?MbVEi{NwxGfuC5{cd z#c9P&O54TxaEzwSRm)4ekn3Bk4s_=5f_XN2_8bmcZjE zV}#Ih1+(qY>T0UbtP~P!kY&nx9>#Z&`CKoXEW^eAJhg0O;R}x(+&PB@Hzw>1Zu*kV zxp5B7)@W9{RCa)nyt)gd{*pQP^=(ZD`fu3u6WhN%{xRh}bOTa(SZ{EPJZm}w4fRS? z7b%*=0$_xkjQCMwb_UQaq7u8QP-$5kHvF>G>6t?vHO_?v<9o+Akz4Bo#?V)@_vCMe zEzJyFqIXoA2ybAm6B{Cm36NKN z|AGO>fWs`2gR9pu5ds&$7_!b2wl0gVabL>4-_9w}*O`Qf=(j_KX-a?9gU?-9fnRs+ z4E1VrliXYiB3;48<8^yBvWNLx(ky#M1?D$$pV>CsxLqB#m(8_Qz+G=mTRXInfk9{S z>GEFu(Z}1X#B;J6fd=w#$Kl+bf6;;F=X!qJpUjAvqmx3z>hSxdh=3}8oLod;Vi$l) zMiX3MD&*u<5lN=J-O*BZ!U{xVypc8;%CU@Gj*#--yc8^>p!j7yG6fG=nc5B^@;QDe z$3)YHJ+`FHcA8R{+Y^wXytfMhLrW$6Uk5KG3KM@tnz@wwymPW9OtX<6_KtZ=?>m6QI;{2RmQZa5RWg4fsBld-0c-|E1uRmf<;3^W4Pn0<2@&|{A2$T zRnqC)d>oumin(qqw6>PUfzL$c&=_-=%H9r8OGs13OhMB`eQGFcEGrw*o(oFeXi>bI z6qP4Mg>2MM0ms&$Y^T@QaHjbDBx;r^p!T#r^a%z6=&sc|^!)q?fYSYFb2V_lg={lK znv?tJtZD}5r`Z-YBO>dB{&Kd^v&FVu8$mSGG&i>nE%y}I65egcbwl?SBl;lK`|;FX zmMG*jk|H&r$_gqyv8sB8-Ik;-*&_D0H_y(s<@vok$?oYKn4uq36TSqagE{^#i-s0= zP8p}OQ^Lw9d05Pn<q8pmI*%MpHurIgbsga)?y+)y^gzj!hoBj#`P*ci&gPWuBmTzabLR{Hvzm z3@DIlkIKaD1m9bTw;m&NOS~jtGz|?k23=IldamM1;tdu6`KzXb@)ZOGkkJCZ8X=*C z;-RDxisAqf6w-iSVHG%l?^Wb9KZ$;^U;(7v-OX)0m|y?`=$L3R)&K!yXQ$QtI=77B zNE8(epacH?b?h$67qq6Oq9;-w!1y0?z5g;-buBeo{ldu}qR-p-080e**6F9`Tyq)} zDHxL@5!Ix{N$uv`T4F>3iEd6wyxjWwS`+d@O4za{2f=94Nh5=sN&7I zJ1h|OrSZs_J+z}shm`_sAfltu@tRGKDs5`L!`P!Mo6NOkml(-M^y<2yXUM*>XPfQy zC<-xx^G-$FHJ$L*Ff-H!j!L`|pe553D7@G=e)$@^?n)u0x+jpB5I<6C_mB3Fo=2*y zpeXsv!*MFgTWGW>wNByEN3tD{fQj$xDJ% zesK=N7(oAl7}k?D+a?8(sW$_7v8nn6!@X`r=7y8pzyMOs)U33Jl5l|5%4|*W&CxTW z>Lt&(WX6E}8FRnN`TgzkNvg19^TA2bi*6xj>?@U&o|!>EXf%6G?X=l`%(tF3u_$#} zU{GU>DS*DjXg<#ts%DC`X4$Hok*-4Rt3UqwvG@`}O4A4}kYH?*h?|-+x|lIQLjp!T z4@HN)apJsvn@SOC#~bEz&X#Xa2o6dlapm^2MvAXlv5gM{5)VTZWdSs{^iVmBC;kZ; zC3eZU|B9Vix}ee!@}vU>mZp>oBd$r^`MTEhlUp4keIzzoj|pJNNJgqQKD896f95d! zx?KM-UKnTX*EksRIHjxNLcq5yfD<>}h&vOEjh!isdk}JqpiB~u6c%4sZ$k#tJ=@gC zYyb*?*7;y@e(Q%p?R?{~A4x#VB_{tNJLF>r1(9B0%u??<(U3#;zq;k=+z>tFU2adU zvzz4GDqseG6q^1vMPamhZiuur!SC+krLTS*oS)Co6#1J#Ct>-#2HZ|BW&dEhDilwurO zqLb|>8rY1u5)T5C+?Ew&2`)5 z76tZo7_3G2@~rtj2fd4j2AXbt`hH(0B9El0*MG%6t_c|1X_?^5-y<&H7qf2f zcBIgV{-prJzO$|!(l=27G|u0d^W$b!zY$y?hcxLjUmj&409Yjt~G{^jiCR@C@5ZpY@2p83?qN6&Nr33tA65tm6h8WCRsn6FLh0@rrQ7VR=qz~ zE!W^TzMg+CzS?7memkx9sA%yu8b|U%I8Rc&&@G4w`b~wnxz{zIaz>*bqYJlW&*x&A zaKM0vV!r`HVdJj$h8^(L#F6=k%9MybX*_!gOc~^Vh9s$*xN}_MrS*Auy9tYZCyKQ; zbqoBR>B3fQ&MJNGBNh4d!{hDm;s`nzJSjk+UUl=Mj^jHoOb26y^4?5HdEdi!wW)sY z=T8@;T~-vRucI5*U3AS4d-_woz5Y=Vb03L^-l8j*phOe%lvulc7M>DK_Q0uBocyy{${6E-n5u zIov`!@1?m;skV=_8p6SvHLus#o9=(p%;uTX)P^FqT9(V91tuYugUu98b{h?b6V3hRI+rk#@>dTZH9R{cu1Hp*ss2Z6 zV&!gXq9F45^3%)o^sFN)5ao?<7#;Swz`spBmdk0TD_b{olElaPWfRylG&0x~g_+Bp zO}%UXhYL`O_o4wvcK8&b@i4N^tl#JAsu)|WC>tV|=1F?deRDC;Qeyi4< zANpqRGxPV6qsKX2G`X|0aj$Ca5PAu_)4~1d@sylCB%x8g#&*Mh9_G})Io@ckWNqpG z&&CDc4_dj|?6SaFU-oX>PFtkdWRqJ4_mi%WxcRxAVU+75j`Q}UK`8S&7|TP1^Wvi6 z(#ePpU$>#_qLwd4uTVqVX|H;~L_@(d1WeOoInT5ID;ZT#;d$vs+|J$Z1PGTv6U7g` z+CoFs3WwuT#T2(A?5z^z{&_CdTJh-VhK!E>iA^O48V^s?tYu!_lkR&ccw1C={k*@{ z0*azSNmVYV6(WVfKPC+YJY-zv>56Dmc$)Kqgxw{(XC_|Xn89loGn0l$C)4*bBtZ2> z10K_xU{jm-WzSDD?UdJI63sc*h1)_vDmP6hOIsqXIXS-~*x&BZ0J$(K06?q9>*Qjg zkDEF{Btxy?(4tnra=eG+y@VKDsAQNY1}73x<1(_1p(9g8^G{VQg!IoT^M&IY?|Urs z$40uX$9g|-$cY039;@3F$}DQb>_jhy-z%=!5;2dnEvCDrOzLqlQeS!4ys@fjXM3&Z z(7+NIS~Y&-7M_M3omi2SrFKIpMH}w}FP+&w@op-Z$)g0fW0}S2)#{IjYIcd14yMvS zau~WT-*_yf2|8{s`J<2JYzx80R*%d6h~)-O+yw&hSIg>3YYiD}H9h~Y_P#5isjh1i zKbFmo8mIK)Ql}NRt{$0O`_uhhU*s=@6RqUZe#GML~Ke^bkVtB$R~ELMHxg z=AU_IuIBQ);R4P%oW0N9Ypv&b)>>OUmYjr^gZAL;vZdGD&3YA3`Ovuvm>eLh`X1W! zCWDWgHhfyfg-*q&j_S%^HliBXa-w|i`sb}%bwlR{D$;Xw1~-4&!TRf8dMN8>fBG~7 z2tYw9tyt? zW5~a{zl}xATL??`@$~iSGeS|S33Cv=W`7P%LyNmv4(_gfp*Gh)JZ#RI=Y$09Ek0yf zk{D5neH@lqg%U1H43%2N+u{mk9_e=}^0w34J|`*1mqV`CF?q@a{GRn+0RMb`i)1Fl=aM;}(qe`z z6}Fy)a=TaGKl1X4DNJn#=SmW7Avzt1da6QdkZ>V$P_wz%+kBgniW#EeZUgN5`}KtN zan>)vUj9~tx7W&hc}xMQ?WbM2qBkNPKx2wTiRiR`Gmlmx+GtN^UM_BU&}XN?vDjIQ zqx)I5uT#GIsc?!dIVt~keU$wSP_2sIyZQI8Wd2PigO%BLEr0KrZvsA|d$zCKl0x16Q-ZtiH0K6Az!44CHcd z#9{Un5;Y2`Nq(Z*ru_$c$+SlUN}Aj6gqGe2WRd^c&H>A`mw$Cn0YG`(Yxfr=eT#mB z7WIarF}z`lH&lh_!R}_&zCEgRure#CeDC61*ISzA*1A6_&v4^oKR565Xi`BJ!F_W{m^cD(+jTr)CK-rmxg=fBi>CiE{@M$dshkOe|vLb_Er3~QO@LE^D8l= zvZRA^S_R1#R9M;HO8?HLB)wWp)FX|L$X8+IxIO#JtC6DcR-XHpRe!0^JHkSq(7rN= ze$2z%ggRK&VIpC_fuw_*5aI%63?EljXq;DOiq2X6avX_X?=oEaB;?|>7NKB4J}aRn zp5WXtfKX&2B>@Hvg*LPus}C_cY(BFa?_S%HFme={s!Ty=b{-hEaQq!caxT4WP?V@A zSr=eUwI{pnQW#+{oEP~<5>iQN*fuZv>ldhgbN56g^<^Zn#Gb!2wu}4+voRHKF$swn zBh_a-(oyaOIZ}}AsjX2h9IXytEUynAR zueCj@`b$`{nIW;*IB(CH)!G1XBn-2w?U2@->(v5L8XU1%izXX&O=a~ zyD~MP*?ivSj;(ufJM{|g-HV7xD)d9J#EK~)w%<@-R!En_67iD!;&Y;R@S24_+ot)} zM|VNK%$=Ru^XC4%v&MG>3$)B?e#yDa-JEoUTJ3fSXB&={=kM-MZ9^caCG2O`9Rs4% zV)EhjcE`gbziEV9$m;DLjlqA>?F&F=cGr+nd4aEvi?V`dX&m2D8TPW1C)~s0Y#gsk zXo&kE_u+$Y7t#02*~nA)x# zd?ilx7s}g*CecCQ%mKYubur?~GRYVd3Yt?jo$t`a`wjc4N@pH~$Netq^yE>}*j{Y3 zf=!dAn6$PrFzKg&^OtJ`GiK=nCt96WQO61yn#@VcrbZk}t~1i6CzngagupsaJ5$8) z_=ekC*Xs9t)>^$coN@Z*cEXomYw1}gI~^5IxcyuvB|RCuz>LeX=C6#ALw*I6^iz7V zTZ=ysTU~|F#;OnZMU1cZa3-%{^wKt2 zZ{JBgY=U*B&;y# z*>qKiV%pKhU@7=klE8L==+>n0>ATa8S(*@bHq_6ez#pMwRnBm~M*S&3AT8VS){fOh z_3ydc@L}m)9LENKnhKp9zYY}iS>7Fl@a3O+rqzjamZbN*kPkP-ULmRYn?R?t*yZif z9xIV$wUBaM>@3s)+f6IIJb5(LE6g*WQVE#x+;w)3Q=G$|CaM5(cmZvBQ?J!dF@@YR zBBXYRQ~NXS3~IR&abDei=2pM6?KjeAmjmk;2@^&-re6?dy6<)Nzx-*!)f5mWnOS^nIui}aYFCow;Y zL-rBg;!5ocoa7lQ6l@}_m(~Hl8%h`e@-$VZ(Cy{j%CtzG%9S5MX9JY|es)`-h46-V zQ^GwCAB!Q5cN%W8$*{lVvpIJtq{R&wOZZ%h*aP;YN404ml)D?24MXG*kX^mL?34t% zTEi!I$eyKE5>h;mE5wyp9pyAyn=F*x)>5-#hib>=Z`|3MvcYun7WxGt2zN9T(ry7N zR~pgPBB|P#QyLX#^x;q`+3u8}iw8dTY1i@y-O=jt$xhp1iQh`monN9X!8JKDkM~xQ z1%`KRqMSoS)dn*%Gqauu%ol2r5>9ntsiD8^I+@)4jXaw7 zTJ>)nypY~rh@>MAEY}+jf|40-orf@VO$3k8RD~+;`u(2%8AZ2Pu~SMR5~N1h^CzX^ zw5qMTD>g$~H$3|sm$fSQw0&x~!|!mkltGYVr_*b9Hia~9i(1Is`?C2Gn7|UfR>Ldi zj5I=-rW}-yFD0v}6p@*zPs6Gljcbi7wJK|rDOjSnNR96HKI-&ZUrUE?`b^KpR+-Qz zd@lx?9M4=E9nif6o&+YBZ%~;uv%fTfAQswu@YqNZo~D;q{`dh@rA-QA`Z{}ml?{TxPzg-f5fSu_@ZZ4nC zXH=WOYu8b1Q{;l$6Yea+RD8S$QvY9u&7XrhcT549u`_$|af_(9pO5!D+U;Z{W`XI2%}{35lM7W;(kNq#`^gNFPcm!KKR)eS+7-Z76l(YUrWuVKOoYWl z4faCqBiQVDI^(b&g|v`N;El!?{yo99!yLh5`(SEt)trdh7PtzmDu+Ed3XdC@rS((Q z$@Gtp=3?-B=N8ElObs@M)&(@U6sLCt=`8SJ4iwtv)o;~O7EkO$>5!tJ6%peF;a9M? z%IcnOjX+{W&^}owun|(1lDW5~XLo`vY}AOml7XCY9<+vajBjakv02IW*nBvq9q0s zNR5Pt+f0X6F5s9ZK(0)|3Ib!xnl--4+X z?L1V^HOsqy|AzYemPPgt3iESH1cp5l8h7QS5(M;$$+3xSpUgRksd6U1H*S@h+%nq6 z+44&~pMP8Zcx`DSzCDRS49(D%vieWwR-hWVQOa1HaRNSvgNIb*MClc;L7f)VkLCJn211fa2^kyM5_bD}#3; z&S1yg;7V`nty9qE#}Qo42qeglkP^R$)?t}jHAnzw+Ih9(D`{5@|;Fv?XYNx8Mg@yd5OJ!@nes&R?b!?hODJ*#2|YxCoPpT8Z-Lm7RQs?JNrE`&T6ZTTKbeK^`b7K7D7d1m#>1Q^Ww*1`awC~->yZU^5plYw2gDGMu z08^8MqGgOjBUPfafVi}b=%RE6M419gT?VPPG2iRjT$fHXJ;jp}kZ9u+r5_0)Du8oG zc-SM^gB(ci!9i$FPRo6ip>R%I3n8?sX?+mwzOPe~9~XO4(&y6woKssV``Yk)4_pMM zWx+J1{Z*ct!9yHvdDulhmB!|+JG=VcpgO@-ibOO}7Zh-dB^X@i)paXX^wQ-_9ae7- z2c28OHRLF|A%|ke0_c{c>^W8drnF(@%8`!wk=1BCZy3)Cs<}oIn6k6FnIBo+^1d~& zt)Zz2ZhSk`Yyl~fyWL_ZT1=(v{bLb_c_oG-wjR4{Xa*PEseGKz)Qn}Es6uC4thYBu z9;-CmP-mR{ag-wHRcQ4>FWleAJ}OG>5Oer$RKc2=84}EU2oWpHB~}dqwjf>(5_q%y z$LsEA7kk;DwUbrSi}(nBJJo=io3WxZU3GL+L=U(%9zU+W?(SEWy;r-#s;lzqX;_Y0xNS(-PtBb3vTP7G2Jo^$c)ul#vv*kTPY9i-_C20E@ z(?V?{O-5rz=p<-ewGmL|luhr-^+m=bJt3Pi{YgKSATPccha!`f;gJyX(XMVEbV5kl zTF1rQUj4Pde+u+jdNm=UmNvAVF+F!)ve_D`)bOcAx%}cuTSmkh4mxCAJ}CN&)JV~< zgC?c(uF=UD_KhMX^gc?5S3^`62n*o`ECLN@lXqLJgEQ4C0qseH=cJe>#Gxe;?H<(T zyZS|-%)fNwj!Gud``LhtS3{9;2kqnPn^VI?lF=U7r`b&_9QXbul8dd9vZMdqO*v`PF~ ztzs{Z_tYTR{BVe1nDy=va!2)L&HBe>$VKB*?~Uws(Nut8+kUNUf3|d4Rs|U<>XIF}R};JZ8T7S0>b^UTM`Fwi?h?GnE1^FtShvy; zYd2K}@VCdDtifRLDTaorBIH7wNWn*#sGxraLWR7(#Km*>WRPgKg$(%AN9c8*az-U~ zo9l&8pDf+UNU--ty&oTC)v>>_n^G|hSuw2DYXjV}!nt6FjG6;CB?QR5bLuJgFBkFL z)zf8LRTLsNm12X4?VpK656iN^BUVxBjC46Y;pQiLus>UGG64ISUbX>rERBp3?$D`q zFmV=(%Un0QbNT)BmoA+32`YN+>#n!Yi|zT^;9}(xCI$O;ld+_^TDSJOJZtr+{>=t! zPd7$5Lz1hfh`GgmH+lgdv87$1+~vm3!brp5nv^nw?!#{-s(0rJ%-sz>4Px(3#mhsj z>+D%YIIt(2W2@#X_*?X?l6iwnt()Jm!=L7x`OECbH->o?&~X1b*Pmi}UVmlt9WVY2 zU4)80@&C=`L=5Yv7s80hGrGihH;&c`(WZV4psOD+I2phX;R*KI--*dAeCNk2H>{a& zy>AdM2~Ly5ieWIjhw4_@&r4Na3Z=qJtF7fUeAujyd zP(wwu9lgL4ISMmLx+b;Osp3KVR8hwcnh48O?z!fJQ>9wce)4Jb2y7=`f^0#@%&lLu ztSG2|Xj=c_q0nI!*)41TylTriBIw%?)E&~LQ28uY_Mkt2$*$_W(nPY&0bA%VoP`0U z7S0WTIiN_Z=Xm)U8g6NG+_bR5V@PEtqFcliG40%fLIyn34FBC01>l!lbU( zk>~uP?401Efe7lRkyf5yiw#YF($M5D!{KltXpv$v?rF7N-ywTp*@H$a_4FFQ3_L%X zD=-DVaI0tt!kGeMy&4g>46yi;EV%{gzWoP;OKT@=jx7Fz2BdTXe9*WwXYnBBp^&5Q z%xPk|_Y*Z9+lO-Dli#5sLxayoMtf-R6@|4sa!(`cZ40P-wcD;Kw z=)z-5qYkMY9YxWWAY`HrZTh(8J$*$AGD_?%>oujEli7q0Z^O74XWiCdf_9nb8zX6s z-Nkz4;Cs9+Aq%)`CZ4<#J_p}^3Hqivj2Dw~#Uf8iK7XZ37}e_xPjC`wuD9p_$#@?u zF$26HMT(4u&#gPNi?y88sZ3=+a-Z+9J#fanZLc{i7NpOf38pS$Wgfb$bU#mCno-+N zBn=Z|Y?w;%3+Ne(K%7%$w~0cQjQTOB2-(|b_|)YtjlOzPyDNoiAMYQY;^(qFG-%P03E;l8>nlArOWyA5hXbEQ78&0@BNj z)guD%U9(zuAO*gsMNr8Hw~OsMdhKL56f&$WgJcP2YINEFgLAGVAii56UsFftj%7Ej zTZCb|_B}C&J8=JjNI|KjwG11a;JKMf5lptenNiJ_ol$ZZW^;n>p)@{z<_lkWRx&+9wq%->8KF&qzOD^}Wuytf3{uV+_ zC)c>Bh4Yz61XFi{tYIky-pIBFpUwTmH=y){EXtL`I7@OP4$$WBWl#<#y~d{|j)Q+^ zVwoyS&#w3@!HpE zt7!ww-zv>tKAylQ?)X4m(Fl!gmBM+H8L-HHoQmyMVmST+Hy@DLgpxPGg9c4 z*VWnLUpZv%i=p{JdwC-}!sanu*JudFf*%bMD&E(nmI5b6^C*e~Ja<#1g0|l1$vmRS zJ=bTu0yiCKQk~SjJv@knpR77VvyVhp9u3p`xR!vf`0b0F=D%&P7F7%%rf04;4Hx>< zL86!pI`AXf9s=5(YvsT+JS>uu5TR;DWh_>N-15C(yP~l_=4;(@UTCDZmvOs%(9UUO zzBOXInj-P|Z1)q$g0Lc+?UxZf`#t$M`y7}vnLkeo@zOL-ww?m1_s@Z;c zW5v7Y<}&pQcxQK0MzU@6`?>)0Fw=#d$Bv4^L}RstQJFG74v)k>t|N9p-@u?nTD`mO zFWMOn6~-inUeycFQSM+$6V876Sev7F@)-M}DLJo)GY7{C{*WAfCOQYr%jx^fTWt*FEl&(=-Xw=G zja(?k0L!T54l51oewR8z^Kbi_+4vrMk<%9MmY;j4KQgFOJX*uu_-msKz*fx@oR^(} zY(r}`Tn(lwHk_^KhxjE+)0tHrm@pF#n34AS)#H+FT#k3@Zn7{Y9i>#JzQ5e@x)}48 z&nd$0iftdvG5>m$W#1@GGvDZNfsHNjKcAn>j3K{M>1SmQz2OOu7S}5y)aac}Ku}$D zoy1%@O0=@#6BVA|LEaoL#sxQaB*T<@iQFLw(Xm!q3C+9B!oRoo-3OX~sveJ1a`a(_2!+2&N{LDj5 zEM13X@3ni+(DwX~(KYq6pmxh0gPrkKG{L%`C>=p@3Rn+ZV8DIZ= z>_(>TnF_!7f&nXaXFTTsb>}yFFFn%)I%fhwi-`JF$5x!l`RM6808ow7oqUKW6_8hO zeZS<$cRslirsSAa)k1G4an!3}=!_IQ3&yDV_{jk?m)BP-!(Ylj&6bfVI$b@~FykQR z;>xn_8p}@HTE6?|qs_Y2AHV~Rk|gUq0q0Tsg&|o_Xq`2j%~2bs{9t4U7)DcR`kBW$ zdC*EX#JXE+XP{_23L^Av2gRv$cX%dkvM3{@I-_3byC|CeLY+a-H8dTj$_ zFSuPn=wE$=LkVLNlFKORUy1C>AuheiqY9m$`IThwc|E1hUN*FZ_y=Ao^vZ4bR<5f{4TJA$r?!?O428=!hZ1K1LBcYGv1`YK6J7IBr}M+|Zh!~N7Lb%= z2^mpKtPffW8tG`@yZL8QV!sg$$ltHu5)X&?=CksxfPU|V{n__-DMLj+bQs$GcA&mY zL60IeU}&)b-Cmw7gP3^x;`)BIGEx$f(JmUByKHV~V#`JWdyP7w&bJcndz-q&u`kaYhbd&nQ^kR@YAdN_rGCHQSy({Xi_Mqm~3KnepaJ4=7_ z`S&@}GDAdw!qWFo&Qt|6FWm(uYetKW?H?RZI^C!|cU{0pi+QpHzt4)Z zkEX6lkYU)t^?G(wO2e0+$vJo8o?K5@)&bt&@)c8j)w$?9aynZb9ZX2PsXi$%3{pJa=0OB;rKLOP^X^d=id^BdW90I-e zihse{GAEB*sZASVR@{H@itWavTJ=7UsshjHUw1z)e#g#g)7`*0ry-V)qDwkt?PcCLQFZcr*w(yV{{1ih`e&63@8$GFu?Kauw{P()xBE{sL*5y1jd3KcWd`& z91Vw-*LS-Hbt}IWj!P7E>XtX{U)T??(@J0co|x+0Ct@f8_&!c#ce)CC;XKTY=P?Lw zcECd_GHiy$@7vP&t#m(;luHoKYR(I*$b{ljj4Alf?R+lx0RhENfVF==)qB9Y-!m0X z>pth_X$-j%#eGaNj+1Tnz&5*0@fK0>&Zs-XAKTF=2E29A9|>r#J27|EUM@>UoDdpN z@5-3G&FAKqqI>NPjESX!2YXV7X$2QgvrV#Xg~lU7i96#zs7!_5H*j;_(>H?=iR@V0md%HQT3)jk-9wdIix@m`u1)F1C#3)&Un=Qj4 zkfNi$qioOEobY|#T#ONs(YV261bfvYltOJrx6a@mk)`YQL%Q=JzD<>hMEeI-C@3kK znur!0SGeOEBojfh@)QaSNEK_@=RXu;B5?c?M6Qu7gNV|p%TgiUJp;3a<-|2}byK4l z`p>vqW=TJ=R8NJFNuP-09VUiAjTawN&g1Hj{c**uhUIxs*2&CMOqP6)fNgYfb#T2;15SyUKf=L^5F(ymb6X24=(oiX$_GG_dUR$wWq|HU@1*WaaXup4KYI=Bh`$I1QSWfOna zIw8FHm|c16A0S8{W>aYXEPvdy-BjpB82%E8jJ>)@*;|gGmP?ClB$x$6EpV2{mAglf z4f@Rr3NSwV*q{8}zyffW`2`+QbyFynRiLoxCQC3s%aQdLOZw7Yo7-8lm4u}^`??Hm z)-Uw2lC3J?lV2%qOqed#Ti-1MRluH0Ggx)G8HSC zkgw01i}IL97}3(D`@vnY?UQl67Nz3WY8f<7V5Yu_4Dp0db$wH95lItViHl-OU)v9c1BGM#U3(7uwokKVe7 zAt7n~kUhamauE0Lu8`ot#+1s`9;ACJi=ZGOVS*lAchZ{~CRjoTN970G(|kNUV9R!2T%%4T6HR|mtHT|%8uREaHu zx5>Y`SvS3LP1?BQWadDoPJ^Ktu9~fB4yqG^I&|vP4-OqN$u?&B{1!0K<6MPi{ez37 zH5*t*TD(Q~SmBe>U<}2v8MHpSI*)2AoPR~xUCD`wRYg@TU_>s?$EAa2Gk~Z>vYZD} zOnbn;t07P?H`J{24Dg+MJv))FgSF!&Ciyn3IzS%}y;rT7BQ%f50)&^_SWz-nBi#=K z_HAcJhqfghx!HLhzMPr>{Wy4~UG#W!& z^kZdKuh4VFPmpN#LASnAhtxyTcQ=A&N;R_-(XobfW!%K%3r%N{RC!d!&-833n6Wt1re~$eIS#Igt@%-VzWQ7TeVV8p}n$Lp$X(_H90cHUV}e zuSn59&8}e?Jkn@2{e7zKQ2!Jd^hMgYP}}_ywNTWfylA#xZ5h6B?pqA>*}Y!&UTSem zx?-f#RN{rhgnfic$V6;j**))_waQKo%Eds&%5C(dYa&*WpVdvzQb`< zB1S@^*}&Z=XFl6|rz-8%Oev#up+7uD&4^0hPm@M2?biRAEo99%*k~gMPjT#6jQ0pK z%~&yH?OkVQ{Gq@-Uf$Znlmdiqic4gwqDX#43( zV{aT1EPJk7OW{6u?rb173U+6o;KclnlJp8@r(FKOfXI1lO*j#pW@rNBEmm2p;H?2b zI+oyj-XCD?`tl!VAdb>T6+7iJk*%8319ynskq9j-9>nt{q-rb!EejtPGTy$fMcJWS z{WIQI*h{HkyZ-?I@A=ewYCv4aeY>oh!_lA-A3Ds`?7baIdABadi{muf|IplI<2qWy zK6daPN`UU=lm?n;X56GiX$sR@V$1^$o%V z4Vw!X)-Dy&6vLu}^UG8BJMP;EJBZ;bkf~{q4^@)T@o>c9=8?N{=(B{bss&=|+Icd< zXq25Yp7DM_f7f#DMB#tWwkW)%y=f^mE!Jv*yc4NMOs2=Q z4U97#42n0Yw(1u=M%!k_5-c1$_jWfQJqkE(Z_V}d@#Xn3F7zh`bR8cD7ek8g3j|l$ zhgR8wi*CxpJfV;(Nr%eR)E<@EJ5ru_r4p6lHoNmT zK0N>*U~IB4ZlRfqA+$V`Kla}FZay6a z44yaB;$GHa-swTX(FLb(h=H7gt!S5}+xuT5Zz;q*+Z-e0$h4!1Ik>B7M>F)<&n9=? z8ozu{@!zvYK;B|IkSb(He@Hwy$(#u9tRa#ndglcvNo$ygmJoZ+a%GCC!Cq+@i5{Zy zQw;D>?fGo==1Tgo9B90FX1@3g8Jx(=6)564bI0vI$>lY@mC`f*8ORR66}L z;;V$-;!$@M=9gqBOOk(QROzWdo6LdnL@{hYMY*NncC5}#%Ea3FB>;R|EHu(blw z6+hU`st%KGtqA0hP`zwCYcq`&UYU*y@a~NNPgQvb0WZ#`eqiHs=EKW6LQNFnYzPnS0<9)pLgA|{h2qYFO#?)?p= zf0{Pz;r&i5wcvnqCc(pO#JKpXT)^A8O3^`8Zlse8-M*|8ck>Q}PC$2(HMl`%n5S9w zZmJbkI;=Vnda{o?n{hlB%BUfCo=pNm-NPb5^tpz|fO3-wo;NG;(!YEeZs?o{mz%6# z2PeJkzBoRvGr&Fmr zWI&O4mVCM4X+Svu>m@>_kp)cJwdPr_;4RUb=lC zEU&dx4g`~h72I0hvr~hDxL=sil$lP2PF-g6eU_%*??g#QR6{;yA`LwG7wa{fqwnPZ zcNU0=c$lV?q{aceGL~ni1w9ro4ose8=mi8xqE3YGv)RGFtYc-ee$;01pZzRQw-Dp{ ziy!Rvak6Hv&YYDd?~7nCyB{Jw48Jze%%v2k->Ri?$4I6ghh{O{`4u887>9Q=DLg1= zDIN*4P3PnN6TBA~|6}mJ^^ergVM4wL?0*;Mnx7OqDAB8m%Qy`UyxRQzQ=bJ(%&apQTRr%41GsedVx>Zrz4 zPRuN@yvRh0QnH!NjIItu6Ay>cdl!J|HUiYEvZ~E*C#Eh8WJ}Y6-L{vkHYE%Xtkfv9 z$4_LVo#Ww_SRw)PdxzVWmzDA zQQtX``uD8pTq_31s?7t8;J+-n*Z_q!EU+p*$nY%CVtWW9Y`zKv!NX0%+-EMGsJvxD-%GEn=Joh@BpxYI7esr-x zsV_`Vd>dhn#|gmlcI3Fd6(khPP@m%_wd-8*WAZWpzosXiGZ_B#zc{!pZswx@0x7~l zBI7jAHht}vk_s6h4wv>lV?806On7o4G1%1kp-n%*}L_n6o-#)fm3rC(>QO<9FrV;?vV3+iJYOc6+*Z?0FSFdHyv*o7Pe z92e?AXZ5eK$40?_*!=l@=-l88nUi6M+X&!^>7icm`_^61N$-U0jTskSxYc|@;b4j? zO23mm7z`a2v{%xF5FJVB$5do0raWyi!bSjQzufs6UC$tCKc0|mpAw+g3%J+G9hB9c zNMDJdZE`xKk}ltLX}WLM{t0~rl&CWzo0+)~1hzQLF|THH6xf`&yaIw~`%8iJuhy z18ZdnK_@P9C+rb9kKvxDi?dSvib1lio^RvMQbP$Jmr}7N*u|5^IoAP)xk8b;}?;ab_t{kd8C$M@>4}XzoO!(U< zA{H4SUbDQ-V(--7PF84Y{JaLMg|w!5plgCh9sGnN7oMjlY6vnO!rCc+OuI1$5{8$o zUo#7~a|XXR^%EauZZiz>EdS8!%ysuB#f~UC0Rz>I^lxZil|9HN*uFv^t5*j~x%yPs zWwkFPfB1Ki1&!Q=@{VvT^{+U^LboQR&fK|7+Rb^VYW>d!RlW);b?E$Etqfd>0ura? zW%kH1rEjHwE^@XmV0irCFKG7T#}6M`^1mP3j7UlKa_Rr_UEesoo&mt7HDt9r<%u|l zFXU@_Nnfo^Ol=P6R(}k{sG@R1DopF~K%KIxZbs7%Ha_p%*6l1~#mj6udx65Oo5iWs z;s#sTnOez@l?`sBgy5-;s+Uiy=h&$D444f{6}gG1Hr+pyiAH#F>s*E5f*+D^p zS1B1Q=AP;*4QF~K7hZ^4b1*F}H9cNp_j(eaT&XOWp|rp9TUPxZvgFdzjJQz zvENPvz0L21rgSfj#K1aV|5WDZxGBsvO>6u4v;C^Fw*i-%&o+Qll33J%Ug_RQq?y}s zgTv@UVq*p+r9W_zU9opws#S{C)%a+$EUda(1UG20Ii(yln%k`=?w}j;_6}IsT74!q zkkfm><}O0~V%Iq(OZ~2q_)gbw$^}nnQ4hzX!bI(?O#ajd7$5)7&r%4hvAKV= z7sBdxFgtPPwIgtf0ZY&VjpF3g1P}XtLB0C+3(2l$C_&xoKS^%9aum5u`ePPn@4feds0nB2D+hL|n`*)=UELQiimd$93S zCmEBJ( z$#B%#q8RjkZ&7ouu?<;|zdTKLnE{^#Oyb2ny7^5(IrhbJ+@Zu16DZfWJs`x{=dE%Q zP+opO?9bPk3021fj8R3bY@(bjHp^eU{rmrSPA*Z9iX(IibZ#3LmG)P%7X)sv5K2l~Bu@R$UJRA7TA~W$G zGkwbYrhrE{_`Zfr4ahrNk9mrFspwXsO01R$UZsUsu7s?tRaYQYmkvB^J=2gx3(XC~ zi{x2Az4p;(xL?6p5$D4QBl$>C$KzVaT${(Ms9OMtQ^(LJqBdjlRAXEE+k_$R2}ch4E(u0aNw%@I3xPf$(M#--14M1M<9wKQwXxN zl(YFFCOU@dj*R>ENG--*sq0;w;R0L7|o z48G2$D6qH{A7FN@Vag{p`t{F%`I0z@q~9MWXmFo|$nw<^-pn;TfL2Hol@77IKhpT+ zXzsr$E^IGR$8}Yy7^MBc#e_7*i|5^n9Ul&0dvv^3qrE+*oz+E+>NB5CY z>yHd*;r64&z!*V?B@4WjZ|h}b zXs0E&u&S#1C-FriEYMuXIEYqNM)sPx(AGB`qRymgCfI@uP4Kh*)42fAq)wN|8mD zwfBvFLs>m+$&-?}{?9>-&%LKi*mix9MpQnzj;vrS*PlCWMtqSz5cgd%Q-Mr`S{xPS z9MtP7b6qL_YFke_{7<}-&858vQBpe}vp7zw_D6{`^S4s!RUF3>2AO(A?Fk-(Ot1b7 zaWvk3-Rp@;=IL2}4r%^vmf$9k-^Jw*IFZ}$MMMkbZ#jaMYN@8*H=_(r?{}et2+H*pC2<`3ChFZcgW5t5CUVgMVSlK>Mjwq~I6+ z#a&B}pw1uV^i5IEi~JYAu1Z4up!?rChAI`kN|%l>;CKHvg1D9C?d-=48Q^|)yY|Od zzHyi0o39EGZ(Ew2Mp~M98hBeCibAc2HJgaRr!_w}>zZ5vOD6A&lFCYg<5{UbG~2_s z>oO)n*Dfi*FU!&cLZmP@d&A>YTt=4H`GOJS>}8NRo6F%0?rj3hSz$qI@St!74oUmIGn7=rOo+k0b!~WtKRi<|9+PU&AIBCya5J3lOJ3g)q zh>bn37jZ)cA`p536TCc9Bdi~4{`OG4=>H~!{p4%r0Qz4cy7;vA93B4 zX$a+MrcCj(6aGVUl?T*yB&AW~G$1Rk&CULbh}M*|7k@s)|2tBbA_H5Cl@rIls!`Vqb f{rykB=%n1+w5H(x#ym*0StQB|>Tjy#K79Ef%%yq4 literal 0 HcmV?d00001 diff --git a/docs/evidence/analysis-history-401c5d17da79/visual/details-parameters.png b/docs/evidence/analysis-history-401c5d17da79/visual/details-parameters.png new file mode 100644 index 0000000000000000000000000000000000000000..2ea38b17814f18b448e6d06ed91e1597736170b5 GIT binary patch literal 37469 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

;aG0$i;TXdih3qU68{|$qzDx`o1(p%OH}A0M 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 h`2I(w_ dict[str, str]: + return { + path.relative_to(package).as_posix(): hashlib.sha256(path.read_bytes()).hexdigest() + for path in package.rglob("*") if path.is_file() + } + + +@pytest.fixture +def package(tmp_path: Path) -> Path: + target = tmp_path / "saved results.mmsession" + shutil.copytree(FIXTURE, target) + return target + + +def _qc(package: Path, job_id: str): + from capture_analysis import JobParams, run + + return run(package, JobParams(command="qc", overwrite_job_id=job_id)) + + +def _select(history, job_id: str) -> None: + for index in range(history._jobs.count()): + if history._jobs.itemData(index).job_id == job_id: + history._jobs.setCurrentIndex(index) + return + raise AssertionError(f"saved job not listed: {job_id}") + + +def _finish_real_job(qapp, screen) -> None: + """Run Qt's event loop and settle the worker before any widget teardown.""" + from PySide6.QtCore import QEventLoop, QTimer + + loop = QEventLoop() + deadline = QTimer() + deadline.setSingleShot(True) + deadline.timeout.connect(loop.quit) + assert screen._thread is not None + screen._thread.finished.connect(loop.quit) + deadline.start(30_000) + loop.exec() + deadline.stop() + qapp.processEvents() + try: + assert screen._thread is None, "actual analysis QThread did not finish" + finally: + if screen._thread is not None: + screen._cancel_job() + deadline.start(10_000) + loop.exec() + deadline.stop() + qapp.processEvents() + assert screen._thread is None, "worker did not settle before widget teardown" + + +def test_real_completed_and_failed_jobs_are_read_only(package: Path) -> None: + from capture_analysis import JobParams, run + from capture_desktop.analysis_history import list_saved_jobs, load_saved_job + + _qc(package, "trial-qc") + with pytest.raises(ValueError, match="requires extra.pose_job_id"): + run(package, JobParams(command="kinematics", overwrite_job_id="trial-failed")) + before = _hashes(package) + rows = {job.job_id: job for job in list_saved_jobs(package)} + assert rows["trial-qc"].status == "completed" + assert rows["trial-failed"].status == "failed" + assert not any(row.problem for row in rows.values()) + failed = load_saved_job(package, "trial-failed") + assert json.loads(failed.params_text)["command"] == "kinematics" + assert "requires extra.pose_job_id" in failed.log_text + assert "ERROR:" in failed.log_text + assert _hashes(package) == before + + +def test_copied_package_keeps_its_saved_result(package: Path, tmp_path: Path) -> None: + from capture_desktop.analysis_history import load_saved_job + + original = _qc(package, "relocated-qc") + moved = tmp_path / "renamed copy.mmsession" + shutil.copytree(package, moved) + before = _hashes(moved) + job = load_saved_job(moved, "relocated-qc") + assert job.manifest["packagePath"] == str(package) + assert job.job.directory == moved / "processing/jobs/relocated-qc" + assert job.job.directory != original.job_dir + assert _hashes(moved) == before + + +def test_catalog_explains_unreadable_rows_without_hiding_good_jobs(package: Path) -> None: + from capture_desktop.analysis_history import list_saved_jobs + + result = _qc(package, "good") + parent = result.job_dir.parent + for name, changes in ( + ("future", {"schemaId": "capture.analysis_job/99"}), + ("bad-status", {"status": []}), + ("bad-outputs", {"outputs": ["unexpected"]}), + ("foreign-session", {"sessionId": "another-session"}), + ): + dest = parent / name + dest.mkdir() + manifest = dict(result.manifest, jobId=name, **changes) + (dest / "job_manifest.json").write_text(json.dumps(manifest), encoding="utf-8") + broken = parent / "broken-json" + broken.mkdir() + (broken / "job_manifest.json").write_text("[", encoding="utf-8") + (parent / ".attempt_unfinished").mkdir() + before = _hashes(package) + rows = {job.job_id: job for job in list_saved_jobs(package)} + assert len(rows) == 6 + assert not rows["good"].problem + assert all(row.problem for name, row in rows.items() if name != "good") + assert "different session" in rows["foreign-session"].problem + assert _hashes(package) == before + + +def test_missing_details_and_long_log_are_explicit(package: Path) -> None: + from capture_desktop.analysis_history import load_saved_job + + result = _qc(package, "long-log") + log = result.job_dir / "logs/job.log" + log.write_text("x" * (300 * 1024) + "\nFINAL ORIGINAL DIAGNOSTIC", encoding="utf-8") + before = _hashes(package) + loaded = load_saved_job(package, "long-log") + assert loaded.log_text.startswith("Showing the final 262,144 bytes") + assert loaded.log_text.endswith("FINAL ORIGINAL DIAGNOSTIC") + assert _hashes(package) == before + minimal = result.job_dir.parent / "minimal-failure" + minimal.mkdir() + (minimal / "job_manifest.json").write_text(json.dumps({ + "schemaId": "capture.analysis_job/1", "jobId": minimal.name, + "sessionId": result.manifest["sessionId"], "status": "failed", "outputs": [], + }), encoding="utf-8") + loaded = load_saved_job(package, minimal.name) + assert loaded.job.status == "failed" + assert loaded.params_text.startswith("Parameters unavailable:") + assert loaded.log_text.startswith("Log unavailable:") + + +def test_native_open_and_details_leave_the_package_unchanged(qapp, package: Path) -> None: + from capture_desktop.screen_analysis import AnalysisScreen + from capture_desktop.state import CaptureState + from PySide6.QtWidgets import QPlainTextEdit + + result = _qc(package, "saved-qc") + (result.job_dir / "logs/job.log").write_text( + "Original diagnostic literal text\n", encoding="utf-8" + ) + before = _hashes(package) + screen = AnalysisScreen(CaptureState()) + screen.set_package(str(package)) + assert not screen._last_job_dir + assert screen._history._jobs.count() == 1 + screen._history._open.click() + qapp.processEvents() + assert screen._thread is None + assert screen._last_job_dir == str(result.job_dir) + assert "job_id=saved-qc" in screen._inspector._meta.text() + assert screen._btn_open_report.isEnabled() + screen._history._details.click() + qapp.processEvents() + dialog = screen._history._dialog + assert dialog is not None and dialog.isVisible() + editors = {view.objectName(): view for view in dialog.findChildren(QPlainTextEdit)} + assert all(view.isReadOnly() for view in editors.values()) + assert json.loads(editors["analysisHistoryParameters"].toPlainText())["command"] == "qc" + assert "literal text" in editors["analysisHistoryLog"].toPlainText() + assert json.loads(editors["analysisHistoryManifest"].toPlainText())["jobId"] == "saved-qc" + assert _hashes(package) == before + dialog.close() + screen.close() + + +def test_refresh_preserves_the_view_and_offers_a_new_retained_job(qapp, package: Path) -> None: + from capture_desktop.screen_analysis import AnalysisScreen + from capture_desktop.state import CaptureState + + first = _qc(package, "first") + screen = AnalysisScreen(CaptureState()) + screen.set_package(str(package)) + screen._history._open.click() + second = _qc(package, "second") + before = _hashes(package) + screen._history._refresh.click() + assert screen._history._jobs.count() == 2 + assert screen._last_job_dir == str(first.job_dir) + assert screen._history.loaded_job_id == "first" + _select(screen._history, "second") + assert screen._last_job_dir == str(first.job_dir) + screen._history._open.click() + qapp.processEvents() + assert screen._last_job_dir == str(second.job_dir) + assert screen._history.loaded_job_id == "second" + assert screen._thread is None + assert _hashes(package) == before + screen.close() + + +def test_real_threaded_completion_populates_history(qapp, package: Path) -> None: + from capture_desktop.screen_analysis import AnalysisScreen + from capture_desktop.state import CaptureState + + screen = AnalysisScreen(CaptureState()) + screen.set_package(str(package)) + before = _hashes(package) + screen._btn_run.click() + _finish_real_job(qapp, screen) + assert screen._history._jobs.count() == 1 + assert screen._history.loaded_job_id + assert screen._last_job_dir + assert screen._history._open.isEnabled() + assert "status=completed" in screen._inspector._meta.text() + after = _hashes(package) + assert {name: after[name] for name in before} == before + assert all(name.startswith("processing/") for name in after.keys() - before.keys()) + screen.close() + + +def test_real_threaded_failure_offers_its_retained_diagnostics(qapp, package: Path, + monkeypatch) -> None: + from capture_desktop.screen_analysis import AnalysisScreen + from capture_desktop.state import CaptureState + from PySide6.QtWidgets import QMessageBox + + warnings = [] + monkeypatch.setattr(QMessageBox, "warning", lambda _parent, _title, text: warnings.append(text)) + screen = AnalysisScreen(CaptureState()) + screen.set_package(str(package)) + screen._command.setCurrentIndex(screen._command.findData("kinematics")) + screen._extras._pose_job.setEditText("missing-pose") + before = _hashes(package) + screen._btn_run.click() + _finish_real_job(qapp, screen) + assert warnings and "missing-pose" in warnings[0] + assert screen._history._jobs.count() == 1 + assert screen._history._jobs.currentData().status == "failed" + assert not screen._last_job_dir + screen._history._open.click() + assert "status=failed" in screen._inspector._meta.text() + assert "missing-pose" in screen._history._loaded.log_text + after = _hashes(package) + assert {name: after[name] for name in before} == before + assert all(name.startswith("processing/") for name in after.keys() - before.keys()) + screen.close() From 8747cb95bfb2ac91aa4f1ff604ad677f3597fa12 Mon Sep 17 00:00:00 2001 From: Jacob Metoyer <150724801+Jacob-Met@users.noreply.github.com> Date: Thu, 8 Oct 2026 11:40:24 -0700 Subject: [PATCH 2/3] Diagnose retained analysis-history CI timeouts with per-test boundaries --- tests/ui/test_analysis_history.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/ui/test_analysis_history.py b/tests/ui/test_analysis_history.py index f013473f..e3810641 100644 --- a/tests/ui/test_analysis_history.py +++ b/tests/ui/test_analysis_history.py @@ -261,3 +261,17 @@ def test_real_threaded_failure_offers_its_retained_diagnostics(qapp, package: Pa assert {name: after[name] for name in before} == before assert all(name.startswith("processing/") for name in after.keys() - before.keys()) screen.close() + + +@pytest.fixture(autouse=True) +def _history_ci_boundary(request, capfd): + """Temporary timing evidence for the two retained 300-second CI timeouts.""" + import time + + started = time.perf_counter() + with capfd.disabled(): + print(f"[analysis-history:start] {request.node.nodeid}", flush=True) + yield + with capfd.disabled(): + elapsed = time.perf_counter() - started + print(f"[analysis-history:finish] {request.node.nodeid} {elapsed:.3f}s", flush=True) From c2e1d9c176ec058218e59e0cc8db07f62db1fd98 Mon Sep 17 00:00:00 2001 From: Jacob Metoyer <150724801+Jacob-Met@users.noreply.github.com> Date: Thu, 8 Oct 2026 12:15:56 -0700 Subject: [PATCH 3/3] Allow the verified Windows suite sufficient CI time and remove diagnostics --- .../README.md | 20 + .../diagnostic-receipt.json | 34 + .../diagnostic-windows-success.log | 580 ++++++++++++++++++ .../original-windows-timeout.log | 542 ++++++++++++++++ .../retry-windows-timeout.log | 542 ++++++++++++++++ tests/ui/test_analysis_history.py | 14 - tools/run_ci_tests.py | 2 +- 7 files changed, 1719 insertions(+), 15 deletions(-) create mode 100644 docs/receiving/analysis-history-ci-budget-401c5d17da79/README.md create mode 100644 docs/receiving/analysis-history-ci-budget-401c5d17da79/diagnostic-receipt.json create mode 100644 docs/receiving/analysis-history-ci-budget-401c5d17da79/diagnostic-windows-success.log create mode 100644 docs/receiving/analysis-history-ci-budget-401c5d17da79/original-windows-timeout.log create mode 100644 docs/receiving/analysis-history-ci-budget-401c5d17da79/retry-windows-timeout.log diff --git a/docs/receiving/analysis-history-ci-budget-401c5d17da79/README.md b/docs/receiving/analysis-history-ci-budget-401c5d17da79/README.md new file mode 100644 index 00000000..8fd0d8cc --- /dev/null +++ b/docs/receiving/analysis-history-ci-budget-401c5d17da79/README.md @@ -0,0 +1,20 @@ +# Analysis history: hosted CI time allowance + +The full Windows Python suite reached its existing 300-second subprocess limit twice while reviewing PR71. The retained attempts used actual proposed merge `0de94b767061ec1fe5c05d11c6baa36ec9ddf16b`, a clean unchanged source tree, and no final JUnit. Neither timeout is classified as a passing product run. + +- Original job: https://github.com/Jacob-Met/CaptureSuite/actions/runs/37811934426/job/113430721070 +- One unchanged-job retry: https://github.com/Jacob-Met/CaptureSuite/actions/runs/37811934426/job/113459881579 + +A temporary autouse fixture then recorded entry/exit around each of this PR's eight unchanged history tests. On actual proposed merge `f17f811366bc9915e0f001b42d9df86afc353213`, every history test passed in 0.073–0.158 seconds; their displayed timings sum to 0.834 seconds. The full suite passed 555 with 6 daemon-availability skips in 295.60 seconds (296.7734097 seconds including wrapper evidence processing). This left about 4.4 seconds before the existing child-process deadline. This one observation establishes little timing margin; it is not a claim about every runner's speed. + +Diagnostic job: https://github.com/Jacob-Met/CaptureSuite/actions/runs/37826104818/job/113479261945 + +## Source change + +Restore `tests/ui/test_analysis_history.py` exactly to its pre-diagnostic blob `f013473f750b515a8305e2f7f8426b6520e26a65`. Change only the Python suite subprocess allowance in `tools/run_ci_tests.py` from 300 to 600 seconds. The existing 20-minute Windows job limit remains, as do all process-exit/JUnit/source-immutability acceptance predicates and the suite's existing test selection. No test is removed, skipped or weakened. The existing runner file is byte-identical in the PR source and inspected canonical main before this single-literal change. + +All product source is unchanged by this correction. The previous native history qualifications retain their recorded inputs. The new source head still requires its own hosted gate; this record does not convert either prior timeout into success. + +## Preserved evidence + +The three complete hosted logs are adjacent to this file, along with the actual diagnostic receipt. The source owner is `estate-401c5d17da79`, working in PR71. The prepared source and raw logs are also retained under the ThinkPad estate `capturesuite-ci-a2fd-20261008` packet. The transient diagnostic-only source remains in parent commit `8747cb95bfb2ac91aa4f1ff604ad677f3597fa12`. diff --git a/docs/receiving/analysis-history-ci-budget-401c5d17da79/diagnostic-receipt.json b/docs/receiving/analysis-history-ci-budget-401c5d17da79/diagnostic-receipt.json new file mode 100644 index 00000000..db6b4814 --- /dev/null +++ b/docs/receiving/analysis-history-ci-budget-401c5d17da79/diagnostic-receipt.json @@ -0,0 +1,34 @@ +{ + "schema": "capturesuite.test-receipt.v1", + "accepted": true, + "process_exit": 0, + "counts": { + "tests": 561, + "passed": 555, + "failures": 0, + "errors": 0, + "skipped": 6 + }, + "junit_sha256": "024d03bebc15c2640a86fc8309a8a1cc2ad411f87a000f404b0ef846f0f10764", + "problems": [], + "scope": "Process and test-evidence consistency, not clinical validation", + "seconds": 296.77340969999995, + "created_at": "2026-10-08T18:47:47.824177+00:00", + "run_directory": "build/evidence/python-20261008T184250Z-e1bb4f7d", + "log_sha256": "2a6e81ac2871463414d40e41de21c2e62b93497289601fe13ae3529aa9b6a935", + "source_commit": "f17f811366bc9915e0f001b42d9df86afc353213", + "source_worktree_dirty": false, + "source_tree_sha256": "e265754e62a900bd080b409d4fa720d570003c24e6d06fb5136cf9275856a446", + "source_file_count": 1142, + "github": { + "GITHUB_ACTIONS": "true", + "GITHUB_EVENT_NAME": "pull_request", + "GITHUB_SHA": "f17f811366bc9915e0f001b42d9df86afc353213", + "GITHUB_REF": "refs/pull/71/merge", + "GITHUB_HEAD_REF": "work/analysis-history-401c5d17da79", + "GITHUB_BASE_REF": "main", + "GITHUB_RUN_ID": "37826104818", + "GITHUB_WORKFLOW_REF": "Jacob-Met/CaptureSuite/.github/workflows/ci.yml@refs/pull/71/merge" + }, + "source_unchanged_during_test": true +} diff --git a/docs/receiving/analysis-history-ci-budget-401c5d17da79/diagnostic-windows-success.log b/docs/receiving/analysis-history-ci-budget-401c5d17da79/diagnostic-windows-success.log new file mode 100644 index 00000000..14d0ccea --- /dev/null +++ b/docs/receiving/analysis-history-ci-budget-401c5d17da79/diagnostic-windows-success.log @@ -0,0 +1,580 @@ +2026-10-08T18:40:34.0783039Z Current runner version: '2.337.0' +2026-10-08T18:40:34.0807212Z ##[group]Runner Image Provisioner +2026-10-08T18:40:34.0808007Z Hosted Compute Agent +2026-10-08T18:40:34.0808535Z Version: 20261002.596 +2026-10-08T18:40:34.0809116Z Commit: c3d12f3313a95f25162a1503be624f3b0617f8c0 +2026-10-08T18:40:34.0809785Z Build Date: 2026-10-02T22:28:27Z +2026-10-08T18:40:34.0810407Z Worker ID: {9ac89e71-83c9-42fc-8de2-cbc2de3b62ac} +2026-10-08T18:40:34.0811058Z Region: centralus +2026-10-08T18:40:34.0811554Z Cloud: Azure +2026-10-08T18:40:34.0812046Z ##[endgroup] +2026-10-08T18:40:34.0813407Z ##[group]Operating System +2026-10-08T18:40:34.0814008Z Microsoft Windows Server 2022 +2026-10-08T18:40:34.0814563Z 10.0.20348 +2026-10-08T18:40:34.0815033Z Datacenter +2026-10-08T18:40:34.0815504Z ##[endgroup] +2026-10-08T18:40:34.0815980Z ##[group]Runner Image +2026-10-08T18:40:34.0816503Z Image: windows-2022 +2026-10-08T18:40:34.0817016Z Version: 20261004.326.1 +2026-10-08T18:40:34.0818330Z Included Software: https://github.com/actions/runner-images/blob/win22/20261004.326/images/windows/Windows2022-Readme.md +2026-10-08T18:40:34.0819796Z Image Release: https://github.com/actions/runner-images/releases/tag/win22%2F20261004.326 +2026-10-08T18:40:34.0820659Z ##[endgroup] +2026-10-08T18:40:34.0821767Z ##[group]GITHUB_TOKEN Permissions +2026-10-08T18:40:34.0823524Z Contents: read +2026-10-08T18:40:34.0824111Z Metadata: read +2026-10-08T18:40:34.0824594Z Packages: read +2026-10-08T18:40:34.0825102Z ##[endgroup] +2026-10-08T18:40:34.0827081Z Secret source: Actions +2026-10-08T18:40:34.0827900Z Cache mode: write +2026-10-08T18:40:34.0828589Z Prepare workflow directory +2026-10-08T18:40:34.1226162Z Prepare all required actions +2026-10-08T18:40:34.1295771Z Getting action download info +2026-10-08T18:40:34.3867407Z Download action repository 'actions/checkout@v4' (SHA:11d5960a326750d5838078e36cf38b85af677262) +2026-10-08T18:40:34.4958772Z Download action repository 'actions/setup-python@v5' (SHA:a26af69be951a213d495a4c3e4e4022e16d87065) +2026-10-08T18:40:34.6378849Z Download action repository 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' (SHA:043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) +2026-10-08T18:40:34.8604347Z Complete job name: python +2026-10-08T18:40:35.0171274Z ##[group]Run actions/checkout@v4 +2026-10-08T18:40:35.0172474Z with: +2026-10-08T18:40:35.0172922Z repository: Jacob-Met/CaptureSuite +2026-10-08T18:40:35.0176745Z token: *** +2026-10-08T18:40:35.0177146Z ssh-strict: true +2026-10-08T18:40:35.0177558Z ssh-user: git +2026-10-08T18:40:35.0177962Z persist-credentials: true +2026-10-08T18:40:35.0178408Z clean: true +2026-10-08T18:40:35.0178816Z sparse-checkout-cone-mode: true +2026-10-08T18:40:35.0179295Z fetch-depth: 1 +2026-10-08T18:40:35.0179687Z fetch-tags: false +2026-10-08T18:40:35.0180083Z show-progress: true +2026-10-08T18:40:35.0180504Z lfs: false +2026-10-08T18:40:35.0180890Z submodules: false +2026-10-08T18:40:35.0181309Z set-safe-directory: true +2026-10-08T18:40:35.0181781Z allow-unsafe-pr-checkout: false +2026-10-08T18:40:35.0182564Z ##[endgroup] +2026-10-08T18:40:35.1750822Z Syncing repository: Jacob-Met/CaptureSuite +2026-10-08T18:40:35.1752570Z ##[group]Getting Git version info +2026-10-08T18:40:35.1753309Z Working directory is 'D:\a\CaptureSuite\CaptureSuite' +2026-10-08T18:40:35.2761157Z [command]"C:\Program Files\Git\bin\git.exe" version +2026-10-08T18:40:35.5943706Z git version 2.56.0.windows.1 +2026-10-08T18:40:35.5988576Z ##[endgroup] +2026-10-08T18:40:35.6009357Z Temporarily overriding HOME='D:\a\_temp\5cbf3b83-fa66-4c93-a132-1f57853741d6' before making global git config changes +2026-10-08T18:40:35.6011786Z Adding repository directory to the temporary git global config as a safe directory +2026-10-08T18:40:35.6020962Z [command]"C:\Program Files\Git\bin\git.exe" config --global --add safe.directory D:\a\CaptureSuite\CaptureSuite +2026-10-08T18:40:35.6581623Z Deleting the contents of 'D:\a\CaptureSuite\CaptureSuite' +2026-10-08T18:40:35.6586879Z ##[group]Initializing the repository +2026-10-08T18:40:35.6596538Z [command]"C:\Program Files\Git\bin\git.exe" init D:\a\CaptureSuite\CaptureSuite +2026-10-08T18:40:35.7344780Z Initialized empty Git repository in D:/a/CaptureSuite/CaptureSuite/.git/ +2026-10-08T18:40:35.7384514Z [command]"C:\Program Files\Git\bin\git.exe" remote add origin https://github.com/Jacob-Met/CaptureSuite +2026-10-08T18:40:35.7924100Z ##[endgroup] +2026-10-08T18:40:35.7925021Z ##[group]Disabling automatic garbage collection +2026-10-08T18:40:35.7933039Z [command]"C:\Program Files\Git\bin\git.exe" config --local gc.auto 0 +2026-10-08T18:40:35.8237675Z ##[endgroup] +2026-10-08T18:40:35.8239068Z ##[group]Setting up auth +2026-10-08T18:40:35.8240921Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp core\.sshCommand +2026-10-08T18:40:35.8563331Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :\"" +2026-10-08T18:40:37.1235964Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +2026-10-08T18:40:37.1572282Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :\"" +2026-10-08T18:40:37.6178432Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp ^includeIf\.gitdir: +2026-10-08T18:40:37.6479486Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "git config --local --show-origin --name-only --get-regexp remote.origin.url" +2026-10-08T18:40:38.1370401Z [command]"C:\Program Files\Git\bin\git.exe" config --local http.https://github.com/.extraheader "AUTHORIZATION: basic ***" +2026-10-08T18:40:38.1678327Z ##[endgroup] +2026-10-08T18:40:38.1678855Z ##[group]Fetching the repository +2026-10-08T18:40:38.1702033Z [command]"C:\Program Files\Git\bin\git.exe" -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +f17f811366bc9915e0f001b42d9df86afc353213:refs/remotes/pull/71/merge +2026-10-08T18:40:39.5956910Z From https://github.com/Jacob-Met/CaptureSuite +2026-10-08T18:40:39.5957843Z * [new ref] f17f811366bc9915e0f001b42d9df86afc353213 -> pull/71/merge +2026-10-08T18:40:39.5990927Z ##[endgroup] +2026-10-08T18:40:39.5991619Z ##[group]Determining the checkout info +2026-10-08T18:40:39.5994112Z ##[endgroup] +2026-10-08T18:40:39.6003831Z [command]"C:\Program Files\Git\bin\git.exe" sparse-checkout disable +2026-10-08T18:40:39.6426741Z [command]"C:\Program Files\Git\bin\git.exe" config --local --unset-all extensions.worktreeConfig +2026-10-08T18:40:39.6727844Z ##[group]Checking out the ref +2026-10-08T18:40:39.6741753Z [command]"C:\Program Files\Git\bin\git.exe" checkout --progress --force refs/remotes/pull/71/merge +2026-10-08T18:40:39.9875541Z Note: switching to 'refs/remotes/pull/71/merge'. +2026-10-08T18:40:39.9876017Z +2026-10-08T18:40:39.9876546Z You are in 'detached HEAD' state. You can look around, make experimental +2026-10-08T18:40:39.9957812Z changes and commit them, and you can discard any commits you make in this +2026-10-08T18:40:39.9958677Z state without impacting any branches by switching back to a branch. +2026-10-08T18:40:39.9959128Z +2026-10-08T18:40:39.9959431Z If you want to create a new branch to retain commits you create, you may +2026-10-08T18:40:39.9960243Z do so (now or later) by using -c with the switch command. Example: +2026-10-08T18:40:39.9960705Z +2026-10-08T18:40:39.9960915Z git switch -c +2026-10-08T18:40:39.9961224Z +2026-10-08T18:40:39.9961406Z Or undo this operation with: +2026-10-08T18:40:39.9962204Z +2026-10-08T18:40:39.9962371Z git switch - +2026-10-08T18:40:39.9962624Z +2026-10-08T18:40:39.9963001Z Turn off this advice by setting config variable advice.detachedHead to false +2026-10-08T18:40:39.9964868Z +2026-10-08T18:40:39.9966405Z HEAD is now at f17f811 Merge 8747cb95bfb2ac91aa4f1ff604ad677f3597fa12 into 11cc78297d8d214407aea693548af4de855d61da +2026-10-08T18:40:39.9968991Z ##[endgroup] +2026-10-08T18:40:40.0316882Z [command]"C:\Program Files\Git\bin\git.exe" log -1 --format=%H +2026-10-08T18:40:40.0637044Z f17f811366bc9915e0f001b42d9df86afc353213 +2026-10-08T18:40:40.1172069Z ##[group]Run actions/setup-python@v5 +2026-10-08T18:40:40.1172430Z with: +2026-10-08T18:40:40.1172617Z python-version: 3.12 +2026-10-08T18:40:40.1172848Z check-latest: false +2026-10-08T18:40:40.1175267Z token: *** +2026-10-08T18:40:40.1175476Z update-environment: true +2026-10-08T18:40:40.1175706Z allow-prereleases: false +2026-10-08T18:40:40.1175915Z freethreaded: false +2026-10-08T18:40:40.1176104Z ##[endgroup] +2026-10-08T18:40:40.2713388Z ##[group]Installed versions +2026-10-08T18:40:40.2850497Z (node:4632) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead. +2026-10-08T18:40:40.2851900Z (Use `node --trace-deprecation ...` to show where the warning was created) +2026-10-08T18:40:40.2853585Z Successfully set up CPython (3.12.10) +2026-10-08T18:40:40.2854116Z ##[endgroup] +2026-10-08T18:40:40.3107788Z ##[group]Run python -m pip install -r requirements-ci.txt +2026-10-08T18:40:40.3108357Z python -m pip install -r requirements-ci.txt +2026-10-08T18:40:40.3230261Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:40:40.3230648Z env: +2026-10-08T18:40:40.3230924Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:40:40.3231433Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:40:40.3231918Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:40:40.3232348Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:40:40.3232774Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:40:40.3233135Z ##[endgroup] +2026-10-08T18:40:56.4165946Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_protocol (from -r requirements-ci.txt (line 3)) +2026-10-08T18:40:56.4194170Z Installing build dependencies: started +2026-10-08T18:41:00.0683694Z Installing build dependencies: finished with status 'done' +2026-10-08T18:41:00.0698247Z Checking if build backend supports build_editable: started +2026-10-08T18:41:00.7627972Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T18:41:00.7652922Z Getting requirements to build editable: started +2026-10-08T18:41:01.3064449Z Getting requirements to build editable: finished with status 'done' +2026-10-08T18:41:01.3093329Z Preparing editable metadata (pyproject.toml): started +2026-10-08T18:41:01.6428236Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T18:41:01.6477362Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_session (from -r requirements-ci.txt (line 4)) +2026-10-08T18:41:01.6506289Z Installing build dependencies: started +2026-10-08T18:41:03.2585899Z Installing build dependencies: finished with status 'done' +2026-10-08T18:41:03.2599995Z Checking if build backend supports build_editable: started +2026-10-08T18:41:03.7581017Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T18:41:03.7605912Z Getting requirements to build editable: started +2026-10-08T18:41:04.2805447Z Getting requirements to build editable: finished with status 'done' +2026-10-08T18:41:04.2831922Z Preparing editable metadata (pyproject.toml): started +2026-10-08T18:41:04.6101866Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T18:41:04.6147375Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_analysis +2026-10-08T18:41:04.6173106Z Installing build dependencies: started +2026-10-08T18:41:06.2345459Z Installing build dependencies: finished with status 'done' +2026-10-08T18:41:06.2360444Z Checking if build backend supports build_editable: started +2026-10-08T18:41:06.7065896Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T18:41:06.7089054Z Getting requirements to build editable: started +2026-10-08T18:41:07.2309309Z Getting requirements to build editable: finished with status 'done' +2026-10-08T18:41:07.2335587Z Preparing editable metadata (pyproject.toml): started +2026-10-08T18:41:07.5945575Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T18:41:07.5996969Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_worker (from -r requirements-ci.txt (line 6)) +2026-10-08T18:41:07.6023906Z Installing build dependencies: started +2026-10-08T18:41:09.2036418Z Installing build dependencies: finished with status 'done' +2026-10-08T18:41:09.2052440Z Checking if build backend supports build_editable: started +2026-10-08T18:41:09.6664125Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T18:41:09.6685749Z Getting requirements to build editable: started +2026-10-08T18:41:10.2011142Z Getting requirements to build editable: finished with status 'done' +2026-10-08T18:41:10.2035469Z Preparing editable metadata (pyproject.toml): started +2026-10-08T18:41:10.5620796Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T18:41:10.5665139Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/desktop +2026-10-08T18:41:10.5691401Z Installing build dependencies: started +2026-10-08T18:41:12.2742931Z Installing build dependencies: finished with status 'done' +2026-10-08T18:41:12.2758238Z Checking if build backend supports build_editable: started +2026-10-08T18:41:12.7398446Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T18:41:12.7424841Z Getting requirements to build editable: started +2026-10-08T18:41:13.5350306Z Getting requirements to build editable: finished with status 'done' +2026-10-08T18:41:13.5378536Z Preparing editable metadata (pyproject.toml): started +2026-10-08T18:41:13.8964497Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T18:41:14.7167674Z Collecting grpcio-tools<1.63,>=1.62 (from -r requirements-ci.txt (line 8)) +2026-10-08T18:41:14.8987090Z Downloading grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl.metadata (6.4 kB) +2026-10-08T18:41:14.9518413Z Collecting mcap<2,>=1.1 (from -r requirements-ci.txt (line 9)) +2026-10-08T18:41:14.9636160Z Downloading mcap-1.5.0-py3-none-any.whl.metadata (380 bytes) +2026-10-08T18:41:15.0256311Z Collecting pytest>=8 (from -r requirements-ci.txt (line 10)) +2026-10-08T18:41:15.0375671Z Downloading pytest-9.1.1-py3-none-any.whl.metadata (7.6 kB) +2026-10-08T18:41:15.1061704Z Collecting pytest-cov>=5 (from -r requirements-ci.txt (line 11)) +2026-10-08T18:41:15.1188119Z Downloading pytest_cov-7.1.0-py3-none-any.whl.metadata (32 kB) +2026-10-08T18:41:15.5400825Z Collecting ruff<1,>=0.6 (from -r requirements-ci.txt (line 12)) +2026-10-08T18:41:15.5527700Z Downloading ruff-0.16.10-py3-none-win_amd64.whl.metadata (21 kB) +2026-10-08T18:41:15.7503008Z Collecting protobuf<5,>=4.25 (from capture-protocol==0.1.0->-r requirements-ci.txt (line 3)) +2026-10-08T18:41:15.7635679Z Downloading protobuf-4.25.9-cp310-abi3-win_amd64.whl.metadata (541 bytes) +2026-10-08T18:41:15.8228061Z Collecting jsonschema>=4.21 (from capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T18:41:15.8409076Z Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB) +2026-10-08T18:41:15.9466788Z Collecting pyyaml>=6.0 (from capture-analysis==0.1.0) +2026-10-08T18:41:15.9592614Z Downloading pyyaml-6.0.3-cp312-cp312-win_amd64.whl.metadata (2.4 kB) +2026-10-08T18:41:16.0301482Z Collecting PySide6<7,>=6.6 (from capture-desktop==0.1.0) +2026-10-08T18:41:16.0465205Z Downloading pyside6-6.12.0-cp310-abi3-win_amd64.whl.metadata (5.7 kB) +2026-10-08T18:41:16.3177313Z Collecting numpy>=1.26 (from capture-analysis==0.1.0) +2026-10-08T18:41:16.3338271Z Downloading numpy-2.5.3-cp312-cp312-win_amd64.whl.metadata (6.6 kB) +2026-10-08T18:41:16.5271081Z Collecting scipy>=1.11 (from capture-analysis==0.1.0) +2026-10-08T18:41:16.5437609Z Downloading scipy-1.18.1-cp312-cp312-win_amd64.whl.metadata (61 kB) +2026-10-08T18:41:16.7633887Z Collecting pandas>=2.1 (from capture-analysis==0.1.0) +2026-10-08T18:41:16.7774458Z Downloading pandas-3.0.6-cp312-cp312-win_amd64.whl.metadata (19 kB) +2026-10-08T18:41:16.9172160Z Collecting pyarrow>=14.0 (from capture-analysis==0.1.0) +2026-10-08T18:41:16.9365664Z Downloading pyarrow-25.0.1-cp312-cp312-win_amd64.whl.metadata (3.0 kB) +2026-10-08T18:41:17.1367714Z Collecting matplotlib>=3.8 (from capture-analysis==0.1.0) +2026-10-08T18:41:17.1527037Z Downloading matplotlib-3.11.2-cp312-cp312-win_amd64.whl.metadata (80 kB) +2026-10-08T18:41:17.2405644Z Collecting pyqtgraph>=0.13 (from capture-desktop==0.1.0) +2026-10-08T18:41:17.2756058Z Downloading pyqtgraph-0.14.0-py3-none-any.whl.metadata (1.5 kB) +2026-10-08T18:41:17.8959580Z Collecting grpcio>=1.62.3 (from grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T18:41:17.9119999Z Downloading grpcio-1.84.0-cp312-cp312-win_amd64.whl.metadata (3.9 kB) +2026-10-08T18:41:18.0234920Z Collecting setuptools (from grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T18:41:18.0261493Z Using cached setuptools-84.0.0-py3-none-any.whl.metadata (6.6 kB) +2026-10-08T18:41:18.1263817Z Collecting lz4 (from mcap<2,>=1.1->-r requirements-ci.txt (line 9)) +2026-10-08T18:41:18.1399974Z Downloading lz4-4.4.5-cp312-cp312-win_amd64.whl.metadata (3.9 kB) +2026-10-08T18:41:18.2610479Z Collecting zstandard (from mcap<2,>=1.1->-r requirements-ci.txt (line 9)) +2026-10-08T18:41:18.2775420Z Downloading zstandard-0.25.0-cp312-cp312-win_amd64.whl.metadata (3.3 kB) +2026-10-08T18:41:18.3353196Z Collecting PySide6_Essentials==6.12.0 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T18:41:18.3477845Z Downloading pyside6_essentials-6.12.0-cp310-abi3-win_amd64.whl.metadata (3.9 kB) +2026-10-08T18:41:18.4066847Z Collecting PySide6_Addons==6.12.0 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T18:41:18.4199663Z Downloading pyside6_addons-6.12.0-cp310-abi3-win_amd64.whl.metadata (4.4 kB) +2026-10-08T18:41:18.4748861Z Collecting PySide6_WebEngine==6.12.0.140 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T18:41:18.4867270Z Downloading pyside6_webengine-6.12.0.140-cp310-abi3-win_amd64.whl.metadata (3.7 kB) +2026-10-08T18:41:18.5354195Z Collecting PySide6_Pdf==6.12.0.140 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T18:41:18.5477557Z Downloading pyside6_pdf-6.12.0.140-cp310-abi3-win_amd64.whl.metadata (3.6 kB) +2026-10-08T18:41:18.6070730Z Collecting shiboken6==6.12.0 (from PySide6_Essentials==6.12.0->PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T18:41:18.6195997Z Downloading shiboken6-6.12.0-cp310-abi3-win_amd64.whl.metadata (2.6 kB) +2026-10-08T18:41:18.6727616Z Requirement already satisfied: colorama>=0.4 in C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages (from pytest>=8->-r requirements-ci.txt (line 10)) (0.4.6) +2026-10-08T18:41:18.7035085Z Collecting iniconfig>=1.0.1 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T18:41:18.7156660Z Downloading iniconfig-2.3.1-py3-none-any.whl.metadata (2.8 kB) +2026-10-08T18:41:18.7332134Z Requirement already satisfied: packaging>=22 in C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages (from pytest>=8->-r requirements-ci.txt (line 10)) (26.3) +2026-10-08T18:41:18.7668902Z Collecting pluggy<2,>=1.5 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T18:41:18.7790363Z Downloading pluggy-1.6.0-py3-none-any.whl.metadata (4.8 kB) +2026-10-08T18:41:18.8406979Z Collecting pygments>=2.7.2 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T18:41:18.8527872Z Downloading pygments-2.21.0-py3-none-any.whl.metadata (2.5 kB) +2026-10-08T18:41:19.3808711Z Collecting coverage>=7.10.6 (from coverage[toml]>=7.10.6->pytest-cov>=5->-r requirements-ci.txt (line 11)) +2026-10-08T18:41:19.3931918Z Downloading coverage-7.16.2-cp312-cp312-win_amd64.whl.metadata (8.4 kB) +2026-10-08T18:41:19.4542641Z Collecting typing-extensions~=4.12 (from grpcio>=1.62.3->grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T18:41:19.4666239Z Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB) +2026-10-08T18:41:19.5216272Z Collecting attrs>=22.2.0 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T18:41:19.5349099Z Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB) +2026-10-08T18:41:19.5927906Z Collecting jsonschema-specifications>=2023.03.6 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T18:41:19.6052104Z Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB) +2026-10-08T18:41:19.6628479Z Collecting referencing>=0.28.4 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T18:41:19.6752975Z Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB) +2026-10-08T18:41:19.9948950Z Collecting rpds-py>=0.25.0 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T18:41:20.0067138Z Downloading rpds_py-2026.9.1-cp312-cp312-win_amd64.whl.metadata (4.2 kB) +2026-10-08T18:41:20.1831104Z Collecting contourpy>=1.0.1 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T18:41:20.1953498Z Downloading contourpy-1.4.0-cp312-cp312-win_amd64.whl.metadata (3.8 kB) +2026-10-08T18:41:20.2452934Z Collecting cycler>=0.10 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T18:41:20.2587726Z Downloading cycler-0.12.1-py3-none-any.whl.metadata (3.8 kB) +2026-10-08T18:41:20.4582738Z Collecting fonttools>=4.28.2 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T18:41:20.4719067Z Downloading fonttools-4.66.1-cp312-cp312-win_amd64.whl.metadata (132 kB) +2026-10-08T18:41:20.5966935Z Collecting kiwisolver>=1.3.1 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T18:41:20.6090476Z Downloading kiwisolver-1.5.1-cp312-cp312-win_amd64.whl.metadata (5.2 kB) +2026-10-08T18:41:20.8656530Z Collecting pillow>=9 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T18:41:20.8776822Z Downloading pillow-12.3.0-cp312-cp312-win_amd64.whl.metadata (9.3 kB) +2026-10-08T18:41:20.9400165Z Collecting pyparsing>=3 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T18:41:20.9531862Z Downloading pyparsing-3.3.3-py3-none-any.whl.metadata (5.9 kB) +2026-10-08T18:41:21.0102813Z Collecting python-dateutil>=2.7 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T18:41:21.0220681Z Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB) +2026-10-08T18:41:21.0802650Z Collecting tzdata (from pandas>=2.1->capture-analysis==0.1.0) +2026-10-08T18:41:21.0921538Z Downloading tzdata-2026.5-py2.py3-none-any.whl.metadata (1.4 kB) +2026-10-08T18:41:21.1457125Z Collecting six>=1.5 (from python-dateutil>=2.7->matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T18:41:21.1573016Z Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB) +2026-10-08T18:41:21.1981067Z Downloading grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl (1.1 MB) +2026-10-08T18:41:21.2389847Z ---------------------------------------- 1.1/1.1 MB 25.5 MB/s 0:00:00 +2026-10-08T18:41:21.2503688Z Downloading mcap-1.5.0-py3-none-any.whl (21 kB) +2026-10-08T18:41:21.2791947Z Downloading ruff-0.16.10-py3-none-win_amd64.whl (10.6 MB) +2026-10-08T18:41:21.3826807Z ---------------------------------------- 10.6/10.6 MB 109.8 MB/s 0:00:00 +2026-10-08T18:41:21.3953816Z Downloading protobuf-4.25.9-cp310-abi3-win_amd64.whl (413 kB) +2026-10-08T18:41:21.4468297Z Downloading pyside6-6.12.0-cp310-abi3-win_amd64.whl (578 kB) +2026-10-08T18:41:21.4648202Z ---------------------------------------- 579.0/579.0 kB 19.8 MB/s 0:00:00 +2026-10-08T18:41:21.4766575Z Downloading pyside6_addons-6.12.0-cp310-abi3-win_amd64.whl (40.5 MB) +2026-10-08T18:41:21.9336082Z ---------------------------------------- 40.5/40.5 MB 88.7 MB/s 0:00:00 +2026-10-08T18:41:21.9454527Z Downloading pyside6_essentials-6.12.0-cp310-abi3-win_amd64.whl (82.2 MB) +2026-10-08T18:41:23.0583014Z ---------------------------------------- 82.2/82.2 MB 73.8 MB/s 0:00:01 +2026-10-08T18:41:23.0694532Z Downloading pyside6_pdf-6.12.0.140-cp310-abi3-win_amd64.whl (3.0 MB) +2026-10-08T18:41:23.1092395Z ---------------------------------------- 3.0/3.0 MB 87.8 MB/s 0:00:00 +2026-10-08T18:41:23.1241673Z Downloading pyside6_webengine-6.12.0.140-cp310-abi3-win_amd64.whl (131.7 MB) +2026-10-08T18:41:25.0396200Z ---------------------------------------- 131.7/131.7 MB 69.0 MB/s 0:00:01 +2026-10-08T18:41:25.0513385Z Downloading shiboken6-6.12.0-cp310-abi3-win_amd64.whl (1.3 MB) +2026-10-08T18:41:25.0764285Z ---------------------------------------- 1.3/1.3 MB 66.9 MB/s 0:00:00 +2026-10-08T18:41:25.0879655Z Downloading pytest-9.1.1-py3-none-any.whl (386 kB) +2026-10-08T18:41:25.1168090Z Downloading pluggy-1.6.0-py3-none-any.whl (20 kB) +2026-10-08T18:41:25.1446275Z Downloading pytest_cov-7.1.0-py3-none-any.whl (22 kB) +2026-10-08T18:41:25.1717120Z Downloading coverage-7.16.2-cp312-cp312-win_amd64.whl (226 kB) +2026-10-08T18:41:25.1998346Z Downloading grpcio-1.84.0-cp312-cp312-win_amd64.whl (5.3 MB) +2026-10-08T18:41:25.2460102Z ---------------------------------------- 5.3/5.3 MB 106.2 MB/s 0:00:00 +2026-10-08T18:41:25.2572528Z Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB) +2026-10-08T18:41:25.2842156Z Downloading iniconfig-2.3.1-py3-none-any.whl (7.6 kB) +2026-10-08T18:41:25.3093727Z Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB) +2026-10-08T18:41:25.3407369Z Downloading attrs-26.1.0-py3-none-any.whl (67 kB) +2026-10-08T18:41:25.3660356Z Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB) +2026-10-08T18:41:25.3919731Z Downloading matplotlib-3.11.2-cp312-cp312-win_amd64.whl (9.3 MB) +2026-10-08T18:41:25.4640057Z ---------------------------------------- 9.3/9.3 MB 144.2 MB/s 0:00:00 +2026-10-08T18:41:25.4757196Z Downloading contourpy-1.4.0-cp312-cp312-win_amd64.whl (234 kB) +2026-10-08T18:41:25.5141811Z Downloading cycler-0.12.1-py3-none-any.whl (8.3 kB) +2026-10-08T18:41:25.6018318Z Downloading fonttools-4.66.1-cp312-cp312-win_amd64.whl (2.5 MB) +2026-10-08T18:41:25.6540408Z ---------------------------------------- 2.5/2.5 MB 35.3 MB/s 0:00:00 +2026-10-08T18:41:25.6657973Z Downloading kiwisolver-1.5.1-cp312-cp312-win_amd64.whl (70 kB) +2026-10-08T18:41:25.7074505Z Downloading numpy-2.5.3-cp312-cp312-win_amd64.whl (12.6 MB) +2026-10-08T18:41:25.7978235Z ---------------------------------------- 12.6/12.6 MB 130.9 MB/s 0:00:00 +2026-10-08T18:41:25.8102561Z Downloading pandas-3.0.6-cp312-cp312-win_amd64.whl (9.7 MB) +2026-10-08T18:41:25.8900241Z ---------------------------------------- 9.7/9.7 MB 120.5 MB/s 0:00:00 +2026-10-08T18:41:25.9014863Z Downloading pillow-12.3.0-cp312-cp312-win_amd64.whl (7.2 MB) +2026-10-08T18:41:25.9649733Z ---------------------------------------- 7.2/7.2 MB 148.2 MB/s 0:00:00 +2026-10-08T18:41:25.9850009Z Downloading pyarrow-25.0.1-cp312-cp312-win_amd64.whl (28.0 MB) +2026-10-08T18:41:26.2872460Z ---------------------------------------- 28.0/28.0 MB 93.2 MB/s 0:00:00 +2026-10-08T18:41:26.2996494Z Downloading pygments-2.21.0-py3-none-any.whl (1.3 MB) +2026-10-08T18:41:26.3361670Z ---------------------------------------- 1.3/1.3 MB 31.9 MB/s 0:00:00 +2026-10-08T18:41:26.3478751Z Downloading pyparsing-3.3.3-py3-none-any.whl (126 kB) +2026-10-08T18:41:26.3889803Z Downloading pyqtgraph-0.14.0-py3-none-any.whl (1.9 MB) +2026-10-08T18:41:26.4242121Z ---------------------------------------- 1.9/1.9 MB 52.0 MB/s 0:00:00 +2026-10-08T18:41:26.4392354Z Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB) +2026-10-08T18:41:26.4762736Z Downloading pyyaml-6.0.3-cp312-cp312-win_amd64.whl (154 kB) +2026-10-08T18:41:26.5056038Z Downloading referencing-0.37.0-py3-none-any.whl (26 kB) +2026-10-08T18:41:26.5379101Z Downloading rpds_py-2026.9.1-cp312-cp312-win_amd64.whl (222 kB) +2026-10-08T18:41:26.5802614Z Downloading scipy-1.18.1-cp312-cp312-win_amd64.whl (36.7 MB) +2026-10-08T18:41:27.3019438Z ---------------------------------------- 36.7/36.7 MB 50.6 MB/s 0:00:00 +2026-10-08T18:41:27.3137858Z Downloading six-1.17.0-py2.py3-none-any.whl (11 kB) +2026-10-08T18:41:27.3568281Z Downloading lz4-4.4.5-cp312-cp312-win_amd64.whl (99 kB) +2026-10-08T18:41:27.3847170Z Using cached setuptools-84.0.0-py3-none-any.whl (818 kB) +2026-10-08T18:41:27.3979288Z Downloading tzdata-2026.5-py2.py3-none-any.whl (347 kB) +2026-10-08T18:41:27.4254492Z Downloading zstandard-0.25.0-cp312-cp312-win_amd64.whl (506 kB) +2026-10-08T18:41:28.0446557Z Building wheels for collected packages: capture-protocol, capture-session, capture-analysis, capture-worker, capture-desktop +2026-10-08T18:41:28.8523354Z Building editable for capture-protocol (pyproject.toml): started +2026-10-08T18:41:29.2291562Z Building editable for capture-protocol (pyproject.toml): finished with status 'done' +2026-10-08T18:41:29.2325428Z Created wheel for capture-protocol: filename=capture_protocol-0.1.0-0.editable-py3-none-any.whl size=7398 sha256=74f5b123ef63870573d62852846385634c0781501bfa160498cc831e7e06118e +2026-10-08T18:41:29.2327704Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-iy411gcj\wheels\be\38\74\adf0f9a8f0ba8d26599b299cff33b892a58ed35959c9e09acd +2026-10-08T18:41:29.2373038Z Building editable for capture-session (pyproject.toml): started +2026-10-08T18:41:29.5764249Z Building editable for capture-session (pyproject.toml): finished with status 'done' +2026-10-08T18:41:29.5799512Z Created wheel for capture-session: filename=capture_session-0.1.0-0.editable-py3-none-any.whl size=2863 sha256=ede2369ea7e581a7a326e3c2b5819c81737343f8fc6b0b2b17c0ac75c3e4f023 +2026-10-08T18:41:29.5801662Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-iy411gcj\wheels\49\8f\6e\163bd066522d89fdd0906cf22a1687ebc628821c7980903be9 +2026-10-08T18:41:29.5845189Z Building editable for capture-analysis (pyproject.toml): started +2026-10-08T18:41:29.9604535Z Building editable for capture-analysis (pyproject.toml): finished with status 'done' +2026-10-08T18:41:29.9635479Z Created wheel for capture-analysis: filename=capture_analysis-0.1.0-0.editable-py3-none-any.whl size=3050 sha256=02382b2a15b5123617c2e39a3087a08c1a28ad8e86e893857425a83d46bb6259 +2026-10-08T18:41:29.9637618Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-iy411gcj\wheels\f4\d1\58\14e4976a0c15c2c470fc12f9a2873cc8c4bc7bd989766b97b4 +2026-10-08T18:41:29.9681668Z Building editable for capture-worker (pyproject.toml): started +2026-10-08T18:41:30.3359203Z Building editable for capture-worker (pyproject.toml): finished with status 'done' +2026-10-08T18:41:30.3394224Z Created wheel for capture-worker: filename=capture_worker-0.1.0-0.editable-py3-none-any.whl size=7659 sha256=e32d1edd9be4ed3f4ea6b49fa5ea82c2eb27175ba76bcf2d5f853aa465060882 +2026-10-08T18:41:30.3396093Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-iy411gcj\wheels\91\10\bd\b56fd1c22822b4cd753ca217f259119db33a4fa54b26c297ee +2026-10-08T18:41:30.3441100Z Building editable for capture-desktop (pyproject.toml): started +2026-10-08T18:41:30.7048024Z Building editable for capture-desktop (pyproject.toml): finished with status 'done' +2026-10-08T18:41:30.7083864Z Created wheel for capture-desktop: filename=capture_desktop-0.1.0-0.editable-py3-none-any.whl size=3184 sha256=684a9220c5dfcbc09d69964340ab998956b37443c65d9d9e117389ccbfe6757a +2026-10-08T18:41:30.7085737Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-iy411gcj\wheels\04\f4\80\083223dba330947d948f2d768e3de9f1e54ae638d0a391d614 +2026-10-08T18:41:30.7111020Z Successfully built capture-protocol capture-session capture-analysis capture-worker capture-desktop +2026-10-08T18:41:30.8854495Z Installing collected packages: zstandard, tzdata, typing-extensions, six, shiboken6, setuptools, ruff, rpds-py, pyyaml, pyparsing, pygments, pyarrow, protobuf, pluggy, pillow, numpy, lz4, kiwisolver, iniconfig, fonttools, cycler, coverage, attrs, scipy, referencing, python-dateutil, pytest, PySide6_Essentials, pyqtgraph, mcap, grpcio, contourpy, capture-protocol, pytest-cov, PySide6_Pdf, PySide6_Addons, pandas, matplotlib, jsonschema-specifications, grpcio-tools, capture-worker, PySide6_WebEngine, jsonschema, PySide6, capture-session, capture-desktop, capture-analysis +2026-10-08T18:42:22.6046310Z +2026-10-08T18:42:22.6100190Z Successfully installed PySide6-6.12.0 PySide6_Addons-6.12.0 PySide6_Essentials-6.12.0 PySide6_Pdf-6.12.0.140 PySide6_WebEngine-6.12.0.140 attrs-26.1.0 capture-analysis-0.1.0 capture-desktop-0.1.0 capture-protocol-0.1.0 capture-session-0.1.0 capture-worker-0.1.0 contourpy-1.4.0 coverage-7.16.2 cycler-0.12.1 fonttools-4.66.1 grpcio-1.84.0 grpcio-tools-1.62.3 iniconfig-2.3.1 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 kiwisolver-1.5.1 lz4-4.4.5 matplotlib-3.11.2 mcap-1.5.0 numpy-2.5.3 pandas-3.0.6 pillow-12.3.0 pluggy-1.6.0 protobuf-4.25.9 pyarrow-25.0.1 pygments-2.21.0 pyparsing-3.3.3 pyqtgraph-0.14.0 pytest-9.1.1 pytest-cov-7.1.0 python-dateutil-2.9.0.post0 pyyaml-6.0.3 referencing-0.37.0 rpds-py-2026.9.1 ruff-0.16.10 scipy-1.18.1 setuptools-84.0.0 shiboken6-6.12.0 six-1.17.0 typing-extensions-4.16.0 tzdata-2026.5 zstandard-0.25.0 +2026-10-08T18:42:23.4091185Z ##[group]Run python -m pip check +2026-10-08T18:42:23.4091545Z python -m pip check +2026-10-08T18:42:23.4135227Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:23.4135577Z env: +2026-10-08T18:42:23.4135862Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:23.4136339Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:23.4136804Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:23.4137208Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:23.4137601Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:23.4137915Z ##[endgroup] +2026-10-08T18:42:24.1892770Z No broken requirements found. +2026-10-08T18:42:24.3593416Z ##[group]Run python tools/check_ci_contract.py --check-environment +2026-10-08T18:42:24.3593958Z python tools/check_ci_contract.py --check-environment +2026-10-08T18:42:24.3634266Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:24.3634607Z env: +2026-10-08T18:42:24.3634872Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:24.3635361Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:24.3635816Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:24.3636229Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:24.3636614Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:24.3636933Z ##[endgroup] +2026-10-08T18:42:30.7534155Z Matplotlib is building the font cache; this may take a moment. +2026-10-08T18:42:46.3844915Z { +2026-10-08T18:42:46.3846145Z "accepted": true, +2026-10-08T18:42:46.3846491Z "errors": [] +2026-10-08T18:42:46.3846783Z } +2026-10-08T18:42:46.7136620Z ##[group]Run python tools/gen_protos.py +2026-10-08T18:42:46.7137001Z python tools/gen_protos.py +2026-10-08T18:42:46.7177615Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:46.7177967Z env: +2026-10-08T18:42:46.7178241Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:46.7178704Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:46.7179150Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:46.7180337Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:46.7180731Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:46.7181051Z ##[endgroup] +2026-10-08T18:42:47.1923842Z Running: C:\hostedtoolcache\windows\Python\3.12.10\x64\python.exe -m grpc_tools.protoc --proto_path=D:\a\CaptureSuite\CaptureSuite\schemas\proto --python_out=D:\a\CaptureSuite\CaptureSuite\libs\python\capture_protocol\capture_protocol\generated --descriptor_set_out=D:\a\CaptureSuite\CaptureSuite\build\generated\capture_v1.desc --include_imports --proto_path=C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages\grpc_tools\_proto capture/v1/arrays.proto capture/v1/common.proto capture/v1/control.proto capture/v1/data/emg_batch.proto capture/v1/data/imu_frame.proto capture/v1/data/numeric_batch.proto capture/v1/data/radar_doppler.proto capture/v1/data/radar_frame.proto capture/v1/data/video_timing.proto capture/v1/events.proto capture/v1/health.proto capture/v1/presets.proto capture/v1/preview.proto capture/v1/project.proto capture/v1/source.proto capture/v1/storage.proto capture/v1/worker.proto +2026-10-08T18:42:47.1929086Z Wrote Python bindings under D:\a\CaptureSuite\CaptureSuite\libs\python\capture_protocol\capture_protocol\generated +2026-10-08T18:42:47.1929900Z Wrote descriptor set D:\a\CaptureSuite\CaptureSuite\build\generated\capture_v1.desc +2026-10-08T18:42:47.3288881Z ##[group]Run git diff --exit-code -- libs/python/capture_protocol/capture_protocol/generated +2026-10-08T18:42:47.3289592Z git diff --exit-code -- libs/python/capture_protocol/capture_protocol/generated +2026-10-08T18:42:47.3332148Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:47.3332753Z env: +2026-10-08T18:42:47.3333194Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:47.3334019Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:47.3334851Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:47.3335577Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:47.3336280Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:47.3336851Z ##[endgroup] +2026-10-08T18:42:47.8426426Z ##[group]Run python tools/gen_session_schemas.py +2026-10-08T18:42:47.8426870Z python tools/gen_session_schemas.py +2026-10-08T18:42:47.8474326Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:47.8474678Z env: +2026-10-08T18:42:47.8474939Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:47.8475394Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:47.8476016Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:47.8476691Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:47.8477394Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:47.8477829Z ##[endgroup] +2026-10-08T18:42:48.1900550Z Wrote 19 schemas to D:\a\CaptureSuite\CaptureSuite\schemas\session\jsonschema +2026-10-08T18:42:48.3039387Z ##[group]Run git diff --exit-code -- schemas/session/jsonschema +2026-10-08T18:42:48.3039918Z git diff --exit-code -- schemas/session/jsonschema +2026-10-08T18:42:48.3083537Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:48.3083893Z env: +2026-10-08T18:42:48.3084156Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:48.3084615Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:48.3085050Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:48.3085443Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:48.3085843Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:48.3086454Z ##[endgroup] +2026-10-08T18:42:48.6966101Z ##[group]Run ruff check libs/python/capture_protocol libs/python/capture_session libs/python/capture_analysis libs/python/capture_worker workers/python_host desktop/capture_desktop tools tests plugins/example_sine_py plugins/lsl_bridge +2026-10-08T18:42:48.6967838Z ruff check libs/python/capture_protocol libs/python/capture_session libs/python/capture_analysis libs/python/capture_worker workers/python_host desktop/capture_desktop tools tests plugins/example_sine_py plugins/lsl_bridge +2026-10-08T18:42:48.7008981Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:48.7009321Z env: +2026-10-08T18:42:48.7009592Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:48.7010052Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:48.7010495Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:48.7010947Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:48.7011333Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:48.7011635Z ##[endgroup] +2026-10-08T18:42:49.1148936Z All checks passed! +2026-10-08T18:42:49.2212946Z ##[group]Run python tools/check_licenses.py --enforce-spdx +2026-10-08T18:42:49.2213450Z python tools/check_licenses.py --enforce-spdx +2026-10-08T18:42:49.2253992Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:49.2254342Z env: +2026-10-08T18:42:49.2254605Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:49.2255063Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:49.2255499Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:49.2255901Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:49.2256640Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:49.2257246Z ##[endgroup] +2026-10-08T18:42:50.0001912Z license check OK +2026-10-08T18:42:50.1121846Z ##[group]Run python tools/run_ci_tests.py +2026-10-08T18:42:50.1122244Z python tools/run_ci_tests.py +2026-10-08T18:42:50.1163277Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T18:42:50.1163626Z env: +2026-10-08T18:42:50.1163884Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:50.1164356Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:42:50.1164814Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:50.1165205Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:50.1165867Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:42:50.1166776Z QT_QPA_PLATFORM: offscreen +2026-10-08T18:42:50.1166992Z ##[endgroup] +2026-10-08T18:47:48.4473444Z ........................................................................ [ 12%] +2026-10-08T18:47:48.4474596Z ........................................................................ [ 25%] +2026-10-08T18:47:48.4475251Z ........................................................................ [ 38%] +2026-10-08T18:47:48.4475872Z ........................................................................ [ 51%] +2026-10-08T18:47:48.4476490Z ..................................................................ssssss [ 64%] +2026-10-08T18:47:48.4477103Z ........................................................................ [ 77%] +2026-10-08T18:47:48.4477707Z ........................................................................ [ 89%] +2026-10-08T18:47:48.4478885Z ................[analysis-history:start] tests/ui/test_analysis_history.py::test_real_completed_and_failed_jobs_are_read_only +2026-10-08T18:47:48.4480212Z .[analysis-history:finish] tests/ui/test_analysis_history.py::test_real_completed_and_failed_jobs_are_read_only 0.093s +2026-10-08T18:47:48.4481912Z [analysis-history:start] tests/ui/test_analysis_history.py::test_copied_package_keeps_its_saved_result +2026-10-08T18:47:48.4483189Z .[analysis-history:finish] tests/ui/test_analysis_history.py::test_copied_package_keeps_its_saved_result 0.094s +2026-10-08T18:47:48.4484548Z [analysis-history:start] tests/ui/test_analysis_history.py::test_catalog_explains_unreadable_rows_without_hiding_good_jobs +2026-10-08T18:47:48.4485992Z .[analysis-history:finish] tests/ui/test_analysis_history.py::test_catalog_explains_unreadable_rows_without_hiding_good_jobs 0.085s +2026-10-08T18:47:48.4487349Z [analysis-history:start] tests/ui/test_analysis_history.py::test_missing_details_and_long_log_are_explicit +2026-10-08T18:47:48.4488629Z .[analysis-history:finish] tests/ui/test_analysis_history.py::test_missing_details_and_long_log_are_explicit 0.073s +2026-10-08T18:47:48.4489951Z [analysis-history:start] tests/ui/test_analysis_history.py::test_native_open_and_details_leave_the_package_unchanged +2026-10-08T18:47:48.4491354Z .[analysis-history:finish] tests/ui/test_analysis_history.py::test_native_open_and_details_leave_the_package_unchanged 0.116s +2026-10-08T18:47:48.4492748Z [analysis-history:start] tests/ui/test_analysis_history.py::test_refresh_preserves_the_view_and_offers_a_new_retained_job +2026-10-08T18:47:48.4494284Z .[analysis-history:finish] tests/ui/test_analysis_history.py::test_refresh_preserves_the_view_and_offers_a_new_retained_job 0.158s +2026-10-08T18:47:48.4495717Z [analysis-history:start] tests/ui/test_analysis_history.py::test_real_threaded_completion_populates_history +2026-10-08T18:47:48.4497047Z .[analysis-history:finish] tests/ui/test_analysis_history.py::test_real_threaded_completion_populates_history 0.114s +2026-10-08T18:47:48.4498434Z [analysis-history:start] tests/ui/test_analysis_history.py::test_real_threaded_failure_offers_its_retained_diagnostics +2026-10-08T18:47:48.4499947Z .[analysis-history:finish] tests/ui/test_analysis_history.py::test_real_threaded_failure_offers_its_retained_diagnostics 0.101s +2026-10-08T18:47:48.4503604Z ................................. [100%] +2026-10-08T18:47:48.4504312Z ============================== warnings summary =============================== +2026-10-08T18:47:48.4504937Z :488 +2026-10-08T18:47:48.4506953Z :488: DeprecationWarning: Type google._upb._message.MessageMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14. +2026-10-08T18:47:48.4508425Z +2026-10-08T18:47:48.4508583Z :488 +2026-10-08T18:47:48.4510134Z :488: DeprecationWarning: Type google._upb._message.ScalarMapContainer uses PyType_Spec with a metaclass that has custom tp_new. This is deprecated and will no longer be allowed in Python 3.14. +2026-10-08T18:47:48.4511574Z +2026-10-08T18:47:48.4512025Z -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html +2026-10-08T18:47:48.4512835Z =========================== short test summary info =========================== +2026-10-08T18:47:48.4513828Z SKIPPED [1] tests\protocol\test_daemon_e2e.py:74: capture_daemon.exe not built (run cmake --build) +2026-10-08T18:47:48.4514967Z SKIPPED [1] tests\protocol\test_daemon_e2e.py:148: capture_daemon.exe not built (run cmake --build) +2026-10-08T18:47:48.4516315Z SKIPPED [1] tests\protocol\test_daemon_e2e.py:161: capture_daemon.exe not built (run cmake --build) +2026-10-08T18:47:48.4517545Z SKIPPED [1] tests\protocol\test_daemon_e2e.py:196: capture_daemon.exe not built (run cmake --build) +2026-10-08T18:47:48.4518679Z SKIPPED [1] tests\protocol\test_daemon_e2e.py:238: capture_daemon.exe not built (run cmake --build) +2026-10-08T18:47:48.4519805Z SKIPPED [1] tests\protocol\test_daemon_e2e.py:262: capture_daemon.exe not built (run cmake --build) +2026-10-08T18:47:48.4520684Z 555 passed, 6 skipped, 2 warnings in 295.60s (0:04:55) +2026-10-08T18:47:48.4521327Z +2026-10-08T18:47:48.4521496Z { +2026-10-08T18:47:48.4521875Z "schema": "capturesuite.test-receipt.v1", +2026-10-08T18:47:48.4522498Z "accepted": true, +2026-10-08T18:47:48.4522917Z "process_exit": 0, +2026-10-08T18:47:48.4523299Z "counts": { +2026-10-08T18:47:48.4523626Z "tests": 561, +2026-10-08T18:47:48.4523985Z "passed": 555, +2026-10-08T18:47:48.4524330Z "failures": 0, +2026-10-08T18:47:48.4524652Z "errors": 0, +2026-10-08T18:47:48.4524974Z "skipped": 6 +2026-10-08T18:47:48.4525298Z }, +2026-10-08T18:47:48.4525865Z "junit_sha256": "024d03bebc15c2640a86fc8309a8a1cc2ad411f87a000f404b0ef846f0f10764", +2026-10-08T18:47:48.4526608Z "problems": [], +2026-10-08T18:47:48.4527197Z "scope": "Process and test-evidence consistency, not clinical validation", +2026-10-08T18:47:48.4527961Z "seconds": 296.77340969999995, +2026-10-08T18:47:48.4528479Z "created_at": "2026-10-08T18:47:47.824177+00:00", +2026-10-08T18:47:48.4529202Z "run_directory": "build/evidence/python-20261008T184250Z-e1bb4f7d", +2026-10-08T18:47:48.4530113Z "log_sha256": "2a6e81ac2871463414d40e41de21c2e62b93497289601fe13ae3529aa9b6a935", +2026-10-08T18:47:48.4530968Z "source_commit": "f17f811366bc9915e0f001b42d9df86afc353213", +2026-10-08T18:47:48.4531612Z "source_worktree_dirty": false, +2026-10-08T18:47:48.4532363Z "source_tree_sha256": "e265754e62a900bd080b409d4fa720d570003c24e6d06fb5136cf9275856a446", +2026-10-08T18:47:48.4533141Z "source_file_count": 1142, +2026-10-08T18:47:48.4533565Z "github": { +2026-10-08T18:47:48.4533947Z "GITHUB_ACTIONS": "true", +2026-10-08T18:47:48.4534383Z "GITHUB_EVENT_NAME": "pull_request", +2026-10-08T18:47:48.4534943Z "GITHUB_SHA": "f17f811366bc9915e0f001b42d9df86afc353213", +2026-10-08T18:47:48.4535513Z "GITHUB_REF": "refs/pull/71/merge", +2026-10-08T18:47:48.4536072Z "GITHUB_HEAD_REF": "work/analysis-history-401c5d17da79", +2026-10-08T18:47:48.4536634Z "GITHUB_BASE_REF": "main", +2026-10-08T18:47:48.4537044Z "GITHUB_RUN_ID": "37826104818", +2026-10-08T18:47:48.4538690Z "GITHUB_WORKFLOW_REF": "Jacob-Met/CaptureSuite/.github/workflows/ci.yml@refs/pull/71/merge" +2026-10-08T18:47:48.4539493Z }, +2026-10-08T18:47:48.4539845Z "source_unchanged_during_test": true +2026-10-08T18:47:48.4540341Z } +2026-10-08T18:47:48.5684282Z ##[group]Run actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a +2026-10-08T18:47:48.5684836Z with: +2026-10-08T18:47:48.5685084Z name: python-test-evidence +2026-10-08T18:47:48.5685366Z path: build/evidence/ +2026-10-08T18:47:48.5685622Z if-no-files-found: warn +2026-10-08T18:47:48.5685876Z retention-days: 7 +2026-10-08T18:47:48.5712691Z compression-level: 6 +2026-10-08T18:47:48.5712956Z overwrite: false +2026-10-08T18:47:48.5713177Z include-hidden-files: false +2026-10-08T18:47:48.5713458Z archive: true +2026-10-08T18:47:48.5713691Z env: +2026-10-08T18:47:48.5714029Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:47:48.5714541Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:47:48.5715072Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:47:48.5715510Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:47:48.5716018Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:47:48.5716387Z ##[endgroup] +2026-10-08T18:47:48.8901358Z With the provided path, there will be 281 files uploaded +2026-10-08T18:47:48.8907472Z Artifact name is valid! +2026-10-08T18:47:48.8908969Z Root directory input is valid! +2026-10-08T18:47:49.2140420Z Uploading artifact: python-test-evidence.zip +2026-10-08T18:47:49.2189165Z Beginning upload of artifact content to blob storage +2026-10-08T18:47:49.9861524Z Uploaded bytes 1613155 +2026-10-08T18:47:50.0252565Z Finished uploading artifact content to blob storage! +2026-10-08T18:47:50.0253439Z SHA256 digest of uploaded artifact is 3f26c00b6f7ba7ba472ac417109df28ceb52ca1df2cbc377b78c09cd8d0bacb6 +2026-10-08T18:47:50.0255368Z Finalizing artifact upload +2026-10-08T18:47:50.3497324Z Artifact python-test-evidence successfully finalized. Artifact ID 11572321018 +2026-10-08T18:47:50.3498792Z Artifact python-test-evidence has been successfully uploaded! Final size is 1613155 bytes. Artifact ID is 11572321018 +2026-10-08T18:47:50.3504653Z Artifact download URL: https://github.com/Jacob-Met/CaptureSuite/actions/runs/37826104818/artifacts/11572321018 +2026-10-08T18:47:50.3811264Z Post job cleanup. +2026-10-08T18:47:50.5223319Z (node:7576) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead. +2026-10-08T18:47:50.5224199Z (Use `node --trace-deprecation ...` to show where the warning was created) +2026-10-08T18:47:50.5488855Z Post job cleanup. +2026-10-08T18:47:50.7984728Z [command]"C:\Program Files\Git\bin\git.exe" version +2026-10-08T18:47:50.8277716Z git version 2.56.0.windows.1 +2026-10-08T18:47:50.8350233Z Temporarily overriding HOME='D:\a\_temp\427e99bd-b099-4900-ba5b-18d86a931f30' before making global git config changes +2026-10-08T18:47:50.8352033Z Adding repository directory to the temporary git global config as a safe directory +2026-10-08T18:47:50.8363756Z [command]"C:\Program Files\Git\bin\git.exe" config --global --add safe.directory D:\a\CaptureSuite\CaptureSuite +2026-10-08T18:47:50.8733777Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp core\.sshCommand +2026-10-08T18:47:50.9068324Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :\"" +2026-10-08T18:47:51.4758667Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +2026-10-08T18:47:51.5059058Z http.https://github.com/.extraheader +2026-10-08T18:47:51.5102290Z [command]"C:\Program Files\Git\bin\git.exe" config --local --unset-all http.https://github.com/.extraheader +2026-10-08T18:47:51.5498392Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :\"" +2026-10-08T18:47:52.0794220Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp ^includeIf\.gitdir: +2026-10-08T18:47:52.1123607Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "git config --local --show-origin --name-only --get-regexp remote.origin.url" +2026-10-08T18:47:52.6111731Z Cleaning up orphan processes +2026-10-08T18:47:52.6307945Z Terminate orphan process: pid (3788) (vctip) +2026-10-08T18:47:52.6362444Z Terminate orphan process: pid (5868) (MSBuild) +2026-10-08T18:47:52.6542418Z Terminate orphan process: pid (2880) (conhost) +2026-10-08T18:47:52.6820274Z ##[warning]Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@v4, actions/setup-python@v5. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/ diff --git a/docs/receiving/analysis-history-ci-budget-401c5d17da79/original-windows-timeout.log b/docs/receiving/analysis-history-ci-budget-401c5d17da79/original-windows-timeout.log new file mode 100644 index 00000000..78a18999 --- /dev/null +++ b/docs/receiving/analysis-history-ci-budget-401c5d17da79/original-windows-timeout.log @@ -0,0 +1,542 @@ +2026-10-08T16:50:40.1732602Z Current runner version: '2.337.0' +2026-10-08T16:50:40.1758241Z ##[group]Runner Image Provisioner +2026-10-08T16:50:40.1759051Z Hosted Compute Agent +2026-10-08T16:50:40.1759599Z Version: 20261002.596 +2026-10-08T16:50:40.1760250Z Commit: c3d12f3313a95f25162a1503be624f3b0617f8c0 +2026-10-08T16:50:40.1760933Z Build Date: 2026-10-02T22:28:27Z +2026-10-08T16:50:40.1761528Z Worker ID: {0e557afc-6416-42ff-a1a4-86af5f4cd416} +2026-10-08T16:50:40.1762207Z Region: eastus +2026-10-08T16:50:40.1762684Z Cloud: Azure +2026-10-08T16:50:40.1763142Z ##[endgroup] +2026-10-08T16:50:40.1764737Z ##[group]Operating System +2026-10-08T16:50:40.1765577Z Microsoft Windows Server 2022 +2026-10-08T16:50:40.1766464Z 10.0.20348 +2026-10-08T16:50:40.1766962Z Datacenter +2026-10-08T16:50:40.1767463Z ##[endgroup] +2026-10-08T16:50:40.1767982Z ##[group]Runner Image +2026-10-08T16:50:40.1768513Z Image: windows-2022 +2026-10-08T16:50:40.1769020Z Version: 20261004.326.1 +2026-10-08T16:50:40.1770684Z Included Software: https://github.com/actions/runner-images/blob/win22/20261004.326/images/windows/Windows2022-Readme.md +2026-10-08T16:50:40.1772353Z Image Release: https://github.com/actions/runner-images/releases/tag/win22%2F20261004.326 +2026-10-08T16:50:40.1773255Z ##[endgroup] +2026-10-08T16:50:40.1774373Z ##[group]GITHUB_TOKEN Permissions +2026-10-08T16:50:40.1776177Z Contents: read +2026-10-08T16:50:40.1776738Z Metadata: read +2026-10-08T16:50:40.1777231Z Packages: read +2026-10-08T16:50:40.1777835Z ##[endgroup] +2026-10-08T16:50:40.1779907Z Secret source: Actions +2026-10-08T16:50:40.1780720Z Cache mode: write +2026-10-08T16:50:40.1781383Z Prepare workflow directory +2026-10-08T16:50:40.2122719Z Prepare all required actions +2026-10-08T16:50:40.2168998Z Getting action download info +2026-10-08T16:50:40.3727201Z Download action repository 'actions/checkout@v4' (SHA:11d5960a326750d5838078e36cf38b85af677262) +2026-10-08T16:50:40.5367456Z Download action repository 'actions/setup-python@v5' (SHA:a26af69be951a213d495a4c3e4e4022e16d87065) +2026-10-08T16:50:40.8006955Z Download action repository 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' (SHA:043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) +2026-10-08T16:50:41.1484909Z Complete job name: python +2026-10-08T16:50:41.3092154Z ##[group]Run actions/checkout@v4 +2026-10-08T16:50:41.3093251Z with: +2026-10-08T16:50:41.3093724Z repository: Jacob-Met/CaptureSuite +2026-10-08T16:50:41.3098233Z token: *** +2026-10-08T16:50:41.3098682Z ssh-strict: true +2026-10-08T16:50:41.3099125Z ssh-user: git +2026-10-08T16:50:41.3099572Z persist-credentials: true +2026-10-08T16:50:41.3100063Z clean: true +2026-10-08T16:50:41.3100501Z sparse-checkout-cone-mode: true +2026-10-08T16:50:41.3101022Z fetch-depth: 1 +2026-10-08T16:50:41.3101459Z fetch-tags: false +2026-10-08T16:50:41.3101902Z show-progress: true +2026-10-08T16:50:41.3102348Z lfs: false +2026-10-08T16:50:41.3102761Z submodules: false +2026-10-08T16:50:41.3103230Z set-safe-directory: true +2026-10-08T16:50:41.3103757Z allow-unsafe-pr-checkout: false +2026-10-08T16:50:41.3104555Z ##[endgroup] +2026-10-08T16:50:41.4471667Z Syncing repository: Jacob-Met/CaptureSuite +2026-10-08T16:50:41.4473592Z ##[group]Getting Git version info +2026-10-08T16:50:41.4474432Z Working directory is 'D:\a\CaptureSuite\CaptureSuite' +2026-10-08T16:50:41.5889109Z [command]"C:\Program Files\Git\bin\git.exe" version +2026-10-08T16:50:43.3854406Z git version 2.56.0.windows.1 +2026-10-08T16:50:43.3899541Z ##[endgroup] +2026-10-08T16:50:43.3917906Z Temporarily overriding HOME='D:\a\_temp\bfe3167c-7825-46d1-8d5d-7a72fbb78fb6' before making global git config changes +2026-10-08T16:50:43.3919021Z Adding repository directory to the temporary git global config as a safe directory +2026-10-08T16:50:43.3929370Z [command]"C:\Program Files\Git\bin\git.exe" config --global --add safe.directory D:\a\CaptureSuite\CaptureSuite +2026-10-08T16:50:43.5775530Z Deleting the contents of 'D:\a\CaptureSuite\CaptureSuite' +2026-10-08T16:50:43.5780572Z ##[group]Initializing the repository +2026-10-08T16:50:43.5789821Z [command]"C:\Program Files\Git\bin\git.exe" init D:\a\CaptureSuite\CaptureSuite +2026-10-08T16:50:43.8783912Z Initialized empty Git repository in D:/a/CaptureSuite/CaptureSuite/.git/ +2026-10-08T16:50:43.8825991Z [command]"C:\Program Files\Git\bin\git.exe" remote add origin https://github.com/Jacob-Met/CaptureSuite +2026-10-08T16:50:44.0614832Z ##[endgroup] +2026-10-08T16:50:44.0615371Z ##[group]Disabling automatic garbage collection +2026-10-08T16:50:44.0624256Z [command]"C:\Program Files\Git\bin\git.exe" config --local gc.auto 0 +2026-10-08T16:50:44.0916303Z ##[endgroup] +2026-10-08T16:50:44.0917248Z ##[group]Setting up auth +2026-10-08T16:50:44.0929436Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp core\.sshCommand +2026-10-08T16:50:44.1227324Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :\"" +2026-10-08T16:50:49.7036543Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +2026-10-08T16:50:49.7350551Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :\"" +2026-10-08T16:50:50.2267341Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp ^includeIf\.gitdir: +2026-10-08T16:50:50.2561916Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "git config --local --show-origin --name-only --get-regexp remote.origin.url" +2026-10-08T16:50:50.7278395Z [command]"C:\Program Files\Git\bin\git.exe" config --local http.https://github.com/.extraheader "AUTHORIZATION: basic ***" +2026-10-08T16:50:50.7584907Z ##[endgroup] +2026-10-08T16:50:50.7585607Z ##[group]Fetching the repository +2026-10-08T16:50:50.7601533Z [command]"C:\Program Files\Git\bin\git.exe" -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +0de94b767061ec1fe5c05d11c6baa36ec9ddf16b:refs/remotes/pull/71/merge +2026-10-08T16:50:54.3618633Z From https://github.com/Jacob-Met/CaptureSuite +2026-10-08T16:50:54.3619855Z * [new ref] 0de94b767061ec1fe5c05d11c6baa36ec9ddf16b -> pull/71/merge +2026-10-08T16:50:54.3652768Z ##[endgroup] +2026-10-08T16:50:54.3653501Z ##[group]Determining the checkout info +2026-10-08T16:50:54.3656535Z ##[endgroup] +2026-10-08T16:50:54.3665543Z [command]"C:\Program Files\Git\bin\git.exe" sparse-checkout disable +2026-10-08T16:50:54.4483696Z [command]"C:\Program Files\Git\bin\git.exe" config --local --unset-all extensions.worktreeConfig +2026-10-08T16:50:54.4841742Z ##[group]Checking out the ref +2026-10-08T16:50:54.4842688Z [command]"C:\Program Files\Git\bin\git.exe" checkout --progress --force refs/remotes/pull/71/merge +2026-10-08T16:50:54.8789346Z Note: switching to 'refs/remotes/pull/71/merge'. +2026-10-08T16:50:54.8789772Z +2026-10-08T16:50:54.8790126Z You are in 'detached HEAD' state. You can look around, make experimental +2026-10-08T16:50:54.8791540Z changes and commit them, and you can discard any commits you make in this +2026-10-08T16:50:54.8792214Z state without impacting any branches by switching back to a branch. +2026-10-08T16:50:54.8792606Z +2026-10-08T16:50:54.8792856Z If you want to create a new branch to retain commits you create, you may +2026-10-08T16:50:54.8793406Z do so (now or later) by using -c with the switch command. Example: +2026-10-08T16:50:54.8793659Z +2026-10-08T16:50:54.8793765Z git switch -c +2026-10-08T16:50:54.8793943Z +2026-10-08T16:50:54.8794036Z Or undo this operation with: +2026-10-08T16:50:54.8794191Z +2026-10-08T16:50:54.8794272Z git switch - +2026-10-08T16:50:54.8794385Z +2026-10-08T16:50:54.8794602Z Turn off this advice by setting config variable advice.detachedHead to false +2026-10-08T16:50:54.8795838Z +2026-10-08T16:50:54.8808549Z HEAD is now at 0de94b7 Merge aefaffe03331f5c8e0cc41dfd75ce9c81f9d09fe into 3cbb5300bdc79c157370d1b3e599a6c82752d54a +2026-10-08T16:50:54.8879557Z ##[endgroup] +2026-10-08T16:50:54.9476126Z [command]"C:\Program Files\Git\bin\git.exe" log -1 --format=%H +2026-10-08T16:50:54.9740996Z 0de94b767061ec1fe5c05d11c6baa36ec9ddf16b +2026-10-08T16:50:55.0162922Z ##[group]Run actions/setup-python@v5 +2026-10-08T16:50:55.0163300Z with: +2026-10-08T16:50:55.0163498Z python-version: 3.12 +2026-10-08T16:50:55.0163721Z check-latest: false +2026-10-08T16:50:55.0166505Z token: *** +2026-10-08T16:50:55.0166700Z update-environment: true +2026-10-08T16:50:55.0166924Z allow-prereleases: false +2026-10-08T16:50:55.0167130Z freethreaded: false +2026-10-08T16:50:55.0167325Z ##[endgroup] +2026-10-08T16:50:55.1676667Z ##[group]Installed versions +2026-10-08T16:50:55.2030994Z (node:4948) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead. +2026-10-08T16:50:55.2032300Z (Use `node --trace-deprecation ...` to show where the warning was created) +2026-10-08T16:50:55.2033015Z Successfully set up CPython (3.12.10) +2026-10-08T16:50:55.2033755Z ##[endgroup] +2026-10-08T16:50:55.2274227Z ##[group]Run python -m pip install -r requirements-ci.txt +2026-10-08T16:50:55.2274748Z python -m pip install -r requirements-ci.txt +2026-10-08T16:50:55.2388503Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:50:55.2388983Z env: +2026-10-08T16:50:55.2389379Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:50:55.2390042Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:50:55.2390640Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:50:55.2391164Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:50:55.2391687Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:50:55.2392125Z ##[endgroup] +2026-10-08T16:51:13.5562825Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_protocol (from -r requirements-ci.txt (line 3)) +2026-10-08T16:51:13.5590941Z Installing build dependencies: started +2026-10-08T16:51:16.9073033Z Installing build dependencies: finished with status 'done' +2026-10-08T16:51:16.9088450Z Checking if build backend supports build_editable: started +2026-10-08T16:51:17.4898741Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T16:51:17.4922111Z Getting requirements to build editable: started +2026-10-08T16:51:18.0287688Z Getting requirements to build editable: finished with status 'done' +2026-10-08T16:51:18.0316377Z Preparing editable metadata (pyproject.toml): started +2026-10-08T16:51:18.3490975Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T16:51:18.3536906Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_session (from -r requirements-ci.txt (line 4)) +2026-10-08T16:51:18.3563001Z Installing build dependencies: started +2026-10-08T16:51:19.9030065Z Installing build dependencies: finished with status 'done' +2026-10-08T16:51:19.9045112Z Checking if build backend supports build_editable: started +2026-10-08T16:51:20.5394434Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T16:51:20.5418588Z Getting requirements to build editable: started +2026-10-08T16:51:21.0356063Z Getting requirements to build editable: finished with status 'done' +2026-10-08T16:51:21.0382743Z Preparing editable metadata (pyproject.toml): started +2026-10-08T16:51:21.3597787Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T16:51:21.3643789Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_analysis +2026-10-08T16:51:21.3670454Z Installing build dependencies: started +2026-10-08T16:51:22.9890787Z Installing build dependencies: finished with status 'done' +2026-10-08T16:51:22.9905940Z Checking if build backend supports build_editable: started +2026-10-08T16:51:23.4751136Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T16:51:23.4783113Z Getting requirements to build editable: started +2026-10-08T16:51:24.0174905Z Getting requirements to build editable: finished with status 'done' +2026-10-08T16:51:24.0202966Z Preparing editable metadata (pyproject.toml): started +2026-10-08T16:51:24.3431631Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T16:51:24.3487068Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_worker (from -r requirements-ci.txt (line 6)) +2026-10-08T16:51:24.3514943Z Installing build dependencies: started +2026-10-08T16:51:26.1672664Z Installing build dependencies: finished with status 'done' +2026-10-08T16:51:26.1687153Z Checking if build backend supports build_editable: started +2026-10-08T16:51:26.6197779Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T16:51:26.6220120Z Getting requirements to build editable: started +2026-10-08T16:51:27.1743260Z Getting requirements to build editable: finished with status 'done' +2026-10-08T16:51:27.1777729Z Preparing editable metadata (pyproject.toml): started +2026-10-08T16:51:27.5016936Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T16:51:27.5062590Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/desktop +2026-10-08T16:51:27.5090179Z Installing build dependencies: started +2026-10-08T16:51:30.3968898Z Installing build dependencies: finished with status 'done' +2026-10-08T16:51:30.3983330Z Checking if build backend supports build_editable: started +2026-10-08T16:51:30.8880960Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T16:51:30.8903623Z Getting requirements to build editable: started +2026-10-08T16:51:31.4620925Z Getting requirements to build editable: finished with status 'done' +2026-10-08T16:51:31.4647262Z Preparing editable metadata (pyproject.toml): started +2026-10-08T16:51:31.8104116Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T16:51:32.6665181Z Collecting grpcio-tools<1.63,>=1.62 (from -r requirements-ci.txt (line 8)) +2026-10-08T16:51:32.8479723Z Downloading grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl.metadata (6.4 kB) +2026-10-08T16:51:32.8875854Z Collecting mcap<2,>=1.1 (from -r requirements-ci.txt (line 9)) +2026-10-08T16:51:32.9236282Z Downloading mcap-1.5.0-py3-none-any.whl.metadata (380 bytes) +2026-10-08T16:51:32.9835664Z Collecting pytest>=8 (from -r requirements-ci.txt (line 10)) +2026-10-08T16:51:33.0018085Z Downloading pytest-9.1.1-py3-none-any.whl.metadata (7.6 kB) +2026-10-08T16:51:33.0725675Z Collecting pytest-cov>=5 (from -r requirements-ci.txt (line 11)) +2026-10-08T16:51:33.0844784Z Downloading pytest_cov-7.1.0-py3-none-any.whl.metadata (32 kB) +2026-10-08T16:51:33.4915789Z Collecting ruff<1,>=0.6 (from -r requirements-ci.txt (line 12)) +2026-10-08T16:51:33.5046928Z Downloading ruff-0.16.10-py3-none-win_amd64.whl.metadata (21 kB) +2026-10-08T16:51:33.6889359Z Collecting protobuf<5,>=4.25 (from capture-protocol==0.1.0->-r requirements-ci.txt (line 3)) +2026-10-08T16:51:33.7014397Z Downloading protobuf-4.25.9-cp310-abi3-win_amd64.whl.metadata (541 bytes) +2026-10-08T16:51:33.7463248Z Collecting jsonschema>=4.21 (from capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T16:51:33.7570141Z Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB) +2026-10-08T16:51:33.8471756Z Collecting pyyaml>=6.0 (from capture-analysis==0.1.0) +2026-10-08T16:51:33.8649268Z Downloading pyyaml-6.0.3-cp312-cp312-win_amd64.whl.metadata (2.4 kB) +2026-10-08T16:51:34.0216512Z Collecting PySide6<7,>=6.6 (from capture-desktop==0.1.0) +2026-10-08T16:51:34.0370745Z Downloading pyside6-6.12.0-cp310-abi3-win_amd64.whl.metadata (5.7 kB) +2026-10-08T16:51:34.3969610Z Collecting numpy>=1.26 (from capture-analysis==0.1.0) +2026-10-08T16:51:34.4336309Z Downloading numpy-2.5.3-cp312-cp312-win_amd64.whl.metadata (6.6 kB) +2026-10-08T16:51:34.5910488Z Collecting scipy>=1.11 (from capture-analysis==0.1.0) +2026-10-08T16:51:34.6033611Z Downloading scipy-1.18.1-cp312-cp312-win_amd64.whl.metadata (61 kB) +2026-10-08T16:51:34.7878801Z Collecting pandas>=2.1 (from capture-analysis==0.1.0) +2026-10-08T16:51:34.8051138Z Downloading pandas-3.0.6-cp312-cp312-win_amd64.whl.metadata (19 kB) +2026-10-08T16:51:34.9584489Z Collecting pyarrow>=14.0 (from capture-analysis==0.1.0) +2026-10-08T16:51:34.9717279Z Downloading pyarrow-25.0.1-cp312-cp312-win_amd64.whl.metadata (3.0 kB) +2026-10-08T16:51:35.1460811Z Collecting matplotlib>=3.8 (from capture-analysis==0.1.0) +2026-10-08T16:51:35.1567985Z Downloading matplotlib-3.11.2-cp312-cp312-win_amd64.whl.metadata (80 kB) +2026-10-08T16:51:35.2172709Z Collecting pyqtgraph>=0.13 (from capture-desktop==0.1.0) +2026-10-08T16:51:35.2286880Z Downloading pyqtgraph-0.14.0-py3-none-any.whl.metadata (1.5 kB) +2026-10-08T16:51:35.8214587Z Collecting grpcio>=1.62.3 (from grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T16:51:35.8364492Z Downloading grpcio-1.84.0-cp312-cp312-win_amd64.whl.metadata (3.9 kB) +2026-10-08T16:51:35.9428826Z Collecting setuptools (from grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T16:51:35.9716851Z Using cached setuptools-84.0.0-py3-none-any.whl.metadata (6.6 kB) +2026-10-08T16:51:36.0496957Z Collecting lz4 (from mcap<2,>=1.1->-r requirements-ci.txt (line 9)) +2026-10-08T16:51:36.0614904Z Downloading lz4-4.4.5-cp312-cp312-win_amd64.whl.metadata (3.9 kB) +2026-10-08T16:51:36.1520867Z Collecting zstandard (from mcap<2,>=1.1->-r requirements-ci.txt (line 9)) +2026-10-08T16:51:36.1633446Z Downloading zstandard-0.25.0-cp312-cp312-win_amd64.whl.metadata (3.3 kB) +2026-10-08T16:51:36.3551252Z Collecting PySide6_Essentials==6.12.0 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T16:51:36.3897367Z Downloading pyside6_essentials-6.12.0-cp310-abi3-win_amd64.whl.metadata (3.9 kB) +2026-10-08T16:51:36.5877382Z Collecting PySide6_Addons==6.12.0 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T16:51:36.6260147Z Downloading pyside6_addons-6.12.0-cp310-abi3-win_amd64.whl.metadata (4.4 kB) +2026-10-08T16:51:36.7838062Z Collecting PySide6_WebEngine==6.12.0.140 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T16:51:36.7956957Z Downloading pyside6_webengine-6.12.0.140-cp310-abi3-win_amd64.whl.metadata (3.7 kB) +2026-10-08T16:51:36.8793260Z Collecting PySide6_Pdf==6.12.0.140 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T16:51:36.9148705Z Downloading pyside6_pdf-6.12.0.140-cp310-abi3-win_amd64.whl.metadata (3.6 kB) +2026-10-08T16:51:37.0672128Z Collecting shiboken6==6.12.0 (from PySide6_Essentials==6.12.0->PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T16:51:37.0932130Z Downloading shiboken6-6.12.0-cp310-abi3-win_amd64.whl.metadata (2.6 kB) +2026-10-08T16:51:37.1601355Z Requirement already satisfied: colorama>=0.4 in C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages (from pytest>=8->-r requirements-ci.txt (line 10)) (0.4.6) +2026-10-08T16:51:37.2758472Z Collecting iniconfig>=1.0.1 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T16:51:37.3133143Z Downloading iniconfig-2.3.1-py3-none-any.whl.metadata (2.8 kB) +2026-10-08T16:51:37.3724899Z Requirement already satisfied: packaging>=22 in C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages (from pytest>=8->-r requirements-ci.txt (line 10)) (26.3) +2026-10-08T16:51:37.4228392Z Collecting pluggy<2,>=1.5 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T16:51:37.4331131Z Downloading pluggy-1.6.0-py3-none-any.whl.metadata (4.8 kB) +2026-10-08T16:51:37.6292817Z Collecting pygments>=2.7.2 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T16:51:37.6400206Z Downloading pygments-2.21.0-py3-none-any.whl.metadata (2.5 kB) +2026-10-08T16:51:38.1853638Z Collecting coverage>=7.10.6 (from coverage[toml]>=7.10.6->pytest-cov>=5->-r requirements-ci.txt (line 11)) +2026-10-08T16:51:38.1967161Z Downloading coverage-7.16.2-cp312-cp312-win_amd64.whl.metadata (8.4 kB) +2026-10-08T16:51:38.3299896Z Collecting typing-extensions~=4.12 (from grpcio>=1.62.3->grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T16:51:38.3404511Z Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB) +2026-10-08T16:51:38.3785942Z Collecting attrs>=22.2.0 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T16:51:38.3902889Z Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB) +2026-10-08T16:51:38.4536870Z Collecting jsonschema-specifications>=2023.03.6 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T16:51:38.4640671Z Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB) +2026-10-08T16:51:38.5140596Z Collecting referencing>=0.28.4 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T16:51:38.5468151Z Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB) +2026-10-08T16:51:38.8536997Z Collecting rpds-py>=0.25.0 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T16:51:38.8641850Z Downloading rpds_py-2026.9.1-cp312-cp312-win_amd64.whl.metadata (4.2 kB) +2026-10-08T16:51:38.9861672Z Collecting contourpy>=1.0.1 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T16:51:38.9989727Z Downloading contourpy-1.4.0-cp312-cp312-win_amd64.whl.metadata (3.8 kB) +2026-10-08T16:51:39.0362010Z Collecting cycler>=0.10 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T16:51:39.0607948Z Downloading cycler-0.12.1-py3-none-any.whl.metadata (3.8 kB) +2026-10-08T16:51:39.2518309Z Collecting fonttools>=4.28.2 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T16:51:39.2811582Z Downloading fonttools-4.66.1-cp312-cp312-win_amd64.whl.metadata (132 kB) +2026-10-08T16:51:39.3938175Z Collecting kiwisolver>=1.3.1 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T16:51:39.4293485Z Downloading kiwisolver-1.5.1-cp312-cp312-win_amd64.whl.metadata (5.2 kB) +2026-10-08T16:51:39.6636259Z Collecting pillow>=9 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T16:51:39.6747267Z Downloading pillow-12.3.0-cp312-cp312-win_amd64.whl.metadata (9.3 kB) +2026-10-08T16:51:39.7563396Z Collecting pyparsing>=3 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T16:51:39.7679568Z Downloading pyparsing-3.3.3-py3-none-any.whl.metadata (5.9 kB) +2026-10-08T16:51:39.8079353Z Collecting python-dateutil>=2.7 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T16:51:39.8448456Z Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB) +2026-10-08T16:51:39.8903732Z Collecting tzdata (from pandas>=2.1->capture-analysis==0.1.0) +2026-10-08T16:51:39.9016037Z Downloading tzdata-2026.5-py2.py3-none-any.whl.metadata (1.4 kB) +2026-10-08T16:51:39.9411270Z Collecting six>=1.5 (from python-dateutil>=2.7->matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T16:51:39.9523806Z Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB) +2026-10-08T16:51:40.0433696Z Downloading grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl (1.1 MB) +2026-10-08T16:51:40.0895726Z ---------------------------------------- 1.1/1.1 MB 25.5 MB/s 0:00:00 +2026-10-08T16:51:40.1102531Z Downloading mcap-1.5.0-py3-none-any.whl (21 kB) +2026-10-08T16:51:40.1368500Z Downloading ruff-0.16.10-py3-none-win_amd64.whl (10.6 MB) +2026-10-08T16:51:40.3075799Z ---------------------------------------- 10.6/10.6 MB 60.0 MB/s 0:00:00 +2026-10-08T16:51:40.3240580Z Downloading protobuf-4.25.9-cp310-abi3-win_amd64.whl (413 kB) +2026-10-08T16:51:40.3543332Z Downloading pyside6-6.12.0-cp310-abi3-win_amd64.whl (578 kB) +2026-10-08T16:51:40.3750754Z ---------------------------------------- 579.0/579.0 kB 10.2 MB/s 0:00:00 +2026-10-08T16:51:40.3868574Z Downloading pyside6_addons-6.12.0-cp310-abi3-win_amd64.whl (40.5 MB) +2026-10-08T16:51:41.2050753Z ---------------------------------------- 40.5/40.5 MB 48.6 MB/s 0:00:00 +2026-10-08T16:51:41.2170127Z Downloading pyside6_essentials-6.12.0-cp310-abi3-win_amd64.whl (82.2 MB) +2026-10-08T16:51:42.9091584Z ---------------------------------------- 82.2/82.2 MB 49.0 MB/s 0:00:01 +2026-10-08T16:51:42.9212582Z Downloading pyside6_pdf-6.12.0.140-cp310-abi3-win_amd64.whl (3.0 MB) +2026-10-08T16:51:43.0358416Z ---------------------------------------- 3.0/3.0 MB 29.3 MB/s 0:00:00 +2026-10-08T16:51:43.0614204Z Downloading pyside6_webengine-6.12.0.140-cp310-abi3-win_amd64.whl (131.7 MB) +2026-10-08T16:51:46.2080232Z ---------------------------------------- 131.7/131.7 MB 41.9 MB/s 0:00:03 +2026-10-08T16:51:46.2224123Z Downloading shiboken6-6.12.0-cp310-abi3-win_amd64.whl (1.3 MB) +2026-10-08T16:51:46.2598974Z ---------------------------------------- 1.3/1.3 MB 32.4 MB/s 0:00:00 +2026-10-08T16:51:46.2702954Z Downloading pytest-9.1.1-py3-none-any.whl (386 kB) +2026-10-08T16:51:46.2968396Z Downloading pluggy-1.6.0-py3-none-any.whl (20 kB) +2026-10-08T16:51:46.3193605Z Downloading pytest_cov-7.1.0-py3-none-any.whl (22 kB) +2026-10-08T16:51:46.3450263Z Downloading coverage-7.16.2-cp312-cp312-win_amd64.whl (226 kB) +2026-10-08T16:51:46.3773061Z Downloading grpcio-1.84.0-cp312-cp312-win_amd64.whl (5.3 MB) +2026-10-08T16:51:46.4518703Z ---------------------------------------- 5.3/5.3 MB 79.2 MB/s 0:00:00 +2026-10-08T16:51:46.4621264Z Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB) +2026-10-08T16:51:46.4968460Z Downloading iniconfig-2.3.1-py3-none-any.whl (7.6 kB) +2026-10-08T16:51:46.5207024Z Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB) +2026-10-08T16:51:46.5438660Z Downloading attrs-26.1.0-py3-none-any.whl (67 kB) +2026-10-08T16:51:46.5684012Z Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB) +2026-10-08T16:51:46.6167020Z Downloading matplotlib-3.11.2-cp312-cp312-win_amd64.whl (9.3 MB) +2026-10-08T16:51:46.9089907Z ---------------------------------------- 9.3/9.3 MB 30.7 MB/s 0:00:00 +2026-10-08T16:51:46.9243307Z Downloading contourpy-1.4.0-cp312-cp312-win_amd64.whl (234 kB) +2026-10-08T16:51:46.9512255Z Downloading cycler-0.12.1-py3-none-any.whl (8.3 kB) +2026-10-08T16:51:46.9795440Z Downloading fonttools-4.66.1-cp312-cp312-win_amd64.whl (2.5 MB) +2026-10-08T16:51:47.0168912Z ---------------------------------------- 2.5/2.5 MB 71.8 MB/s 0:00:00 +2026-10-08T16:51:47.0321105Z Downloading kiwisolver-1.5.1-cp312-cp312-win_amd64.whl (70 kB) +2026-10-08T16:51:47.0693402Z Downloading numpy-2.5.3-cp312-cp312-win_amd64.whl (12.6 MB) +2026-10-08T16:51:47.2093110Z ---------------------------------------- 12.6/12.6 MB 87.3 MB/s 0:00:00 +2026-10-08T16:51:47.2225921Z Downloading pandas-3.0.6-cp312-cp312-win_amd64.whl (9.7 MB) +2026-10-08T16:51:47.3407580Z ---------------------------------------- 9.7/9.7 MB 86.2 MB/s 0:00:00 +2026-10-08T16:51:47.3571737Z Downloading pillow-12.3.0-cp312-cp312-win_amd64.whl (7.2 MB) +2026-10-08T16:51:47.4228512Z ---------------------------------------- 7.2/7.2 MB 112.3 MB/s 0:00:00 +2026-10-08T16:51:47.4363287Z Downloading pyarrow-25.0.1-cp312-cp312-win_amd64.whl (28.0 MB) +2026-10-08T16:51:47.9542078Z ---------------------------------------- 28.0/28.0 MB 53.8 MB/s 0:00:00 +2026-10-08T16:51:47.9655214Z Downloading pygments-2.21.0-py3-none-any.whl (1.3 MB) +2026-10-08T16:51:47.9955546Z ---------------------------------------- 1.3/1.3 MB 31.9 MB/s 0:00:00 +2026-10-08T16:51:48.0055069Z Downloading pyparsing-3.3.3-py3-none-any.whl (126 kB) +2026-10-08T16:51:48.0400895Z Downloading pyqtgraph-0.14.0-py3-none-any.whl (1.9 MB) +2026-10-08T16:51:48.0956516Z ---------------------------------------- 1.9/1.9 MB 35.4 MB/s 0:00:00 +2026-10-08T16:51:48.2590989Z Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB) +2026-10-08T16:51:48.2878370Z Downloading pyyaml-6.0.3-cp312-cp312-win_amd64.whl (154 kB) +2026-10-08T16:51:48.3126164Z Downloading referencing-0.37.0-py3-none-any.whl (26 kB) +2026-10-08T16:51:48.3413706Z Downloading rpds_py-2026.9.1-cp312-cp312-win_amd64.whl (222 kB) +2026-10-08T16:51:48.3724232Z Downloading scipy-1.18.1-cp312-cp312-win_amd64.whl (36.7 MB) +2026-10-08T16:51:48.9477921Z ---------------------------------------- 36.7/36.7 MB 63.0 MB/s 0:00:00 +2026-10-08T16:51:48.9592956Z Downloading six-1.17.0-py2.py3-none-any.whl (11 kB) +2026-10-08T16:51:48.9994280Z Downloading lz4-4.4.5-cp312-cp312-win_amd64.whl (99 kB) +2026-10-08T16:51:49.0165711Z Using cached setuptools-84.0.0-py3-none-any.whl (818 kB) +2026-10-08T16:51:49.0289558Z Downloading tzdata-2026.5-py2.py3-none-any.whl (347 kB) +2026-10-08T16:51:49.0572328Z Downloading zstandard-0.25.0-cp312-cp312-win_amd64.whl (506 kB) +2026-10-08T16:51:49.6707981Z Building wheels for collected packages: capture-protocol, capture-session, capture-analysis, capture-worker, capture-desktop +2026-10-08T16:51:50.2220816Z Building editable for capture-protocol (pyproject.toml): started +2026-10-08T16:51:50.6194992Z Building editable for capture-protocol (pyproject.toml): finished with status 'done' +2026-10-08T16:51:50.6225793Z Created wheel for capture-protocol: filename=capture_protocol-0.1.0-0.editable-py3-none-any.whl size=7398 sha256=e0b159196577c37bb5b58304d4293099c61bc1729aec54e852c28ac0ba0286c3 +2026-10-08T16:51:50.6227573Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-z_40czgb\wheels\be\38\74\adf0f9a8f0ba8d26599b299cff33b892a58ed35959c9e09acd +2026-10-08T16:51:50.6271832Z Building editable for capture-session (pyproject.toml): started +2026-10-08T16:51:50.9660583Z Building editable for capture-session (pyproject.toml): finished with status 'done' +2026-10-08T16:51:50.9692518Z Created wheel for capture-session: filename=capture_session-0.1.0-0.editable-py3-none-any.whl size=2863 sha256=410383a4f1e4e5ae6d0bef5e66a215409b7ef0fa0df33a81d9b06e652aa17398 +2026-10-08T16:51:50.9695181Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-z_40czgb\wheels\49\8f\6e\163bd066522d89fdd0906cf22a1687ebc628821c7980903be9 +2026-10-08T16:51:50.9739496Z Building editable for capture-analysis (pyproject.toml): started +2026-10-08T16:51:51.3481274Z Building editable for capture-analysis (pyproject.toml): finished with status 'done' +2026-10-08T16:51:51.3512631Z Created wheel for capture-analysis: filename=capture_analysis-0.1.0-0.editable-py3-none-any.whl size=3050 sha256=6b42d188c746b1bb1592932b2c42a4ea19c82ff13151c094a51c3347c7cc9669 +2026-10-08T16:51:51.3515358Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-z_40czgb\wheels\f4\d1\58\14e4976a0c15c2c470fc12f9a2873cc8c4bc7bd989766b97b4 +2026-10-08T16:51:51.3561749Z Building editable for capture-worker (pyproject.toml): started +2026-10-08T16:51:51.7272322Z Building editable for capture-worker (pyproject.toml): finished with status 'done' +2026-10-08T16:51:51.7306396Z Created wheel for capture-worker: filename=capture_worker-0.1.0-0.editable-py3-none-any.whl size=7659 sha256=f4262489391c85149b5426e67c319327b5c213437784f35ade3bc9880d5874f7 +2026-10-08T16:51:51.7308698Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-z_40czgb\wheels\91\10\bd\b56fd1c22822b4cd753ca217f259119db33a4fa54b26c297ee +2026-10-08T16:51:51.7353359Z Building editable for capture-desktop (pyproject.toml): started +2026-10-08T16:51:52.0805299Z Building editable for capture-desktop (pyproject.toml): finished with status 'done' +2026-10-08T16:51:52.0838895Z Created wheel for capture-desktop: filename=capture_desktop-0.1.0-0.editable-py3-none-any.whl size=3184 sha256=be0abcbb2767c25cc20e7c870237a5063cf2c9cd798191e9dddf531d1cdda113 +2026-10-08T16:51:52.0841606Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-z_40czgb\wheels\04\f4\80\083223dba330947d948f2d768e3de9f1e54ae638d0a391d614 +2026-10-08T16:51:52.0865240Z Successfully built capture-protocol capture-session capture-analysis capture-worker capture-desktop +2026-10-08T16:51:52.2517353Z Installing collected packages: zstandard, tzdata, typing-extensions, six, shiboken6, setuptools, ruff, rpds-py, pyyaml, pyparsing, pygments, pyarrow, protobuf, pluggy, pillow, numpy, lz4, kiwisolver, iniconfig, fonttools, cycler, coverage, attrs, scipy, referencing, python-dateutil, pytest, PySide6_Essentials, pyqtgraph, mcap, grpcio, contourpy, capture-protocol, pytest-cov, PySide6_Pdf, PySide6_Addons, pandas, matplotlib, jsonschema-specifications, grpcio-tools, capture-worker, PySide6_WebEngine, jsonschema, PySide6, capture-session, capture-desktop, capture-analysis +2026-10-08T16:52:38.8098372Z +2026-10-08T16:52:38.8152100Z Successfully installed PySide6-6.12.0 PySide6_Addons-6.12.0 PySide6_Essentials-6.12.0 PySide6_Pdf-6.12.0.140 PySide6_WebEngine-6.12.0.140 attrs-26.1.0 capture-analysis-0.1.0 capture-desktop-0.1.0 capture-protocol-0.1.0 capture-session-0.1.0 capture-worker-0.1.0 contourpy-1.4.0 coverage-7.16.2 cycler-0.12.1 fonttools-4.66.1 grpcio-1.84.0 grpcio-tools-1.62.3 iniconfig-2.3.1 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 kiwisolver-1.5.1 lz4-4.4.5 matplotlib-3.11.2 mcap-1.5.0 numpy-2.5.3 pandas-3.0.6 pillow-12.3.0 pluggy-1.6.0 protobuf-4.25.9 pyarrow-25.0.1 pygments-2.21.0 pyparsing-3.3.3 pyqtgraph-0.14.0 pytest-9.1.1 pytest-cov-7.1.0 python-dateutil-2.9.0.post0 pyyaml-6.0.3 referencing-0.37.0 rpds-py-2026.9.1 ruff-0.16.10 scipy-1.18.1 setuptools-84.0.0 shiboken6-6.12.0 six-1.17.0 typing-extensions-4.16.0 tzdata-2026.5 zstandard-0.25.0 +2026-10-08T16:52:39.6732066Z ##[group]Run python -m pip check +2026-10-08T16:52:39.6732427Z python -m pip check +2026-10-08T16:52:39.6775789Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:52:39.6776135Z env: +2026-10-08T16:52:39.6776409Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:52:39.6776865Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:52:39.6777320Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:52:39.6777710Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:52:39.6778108Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:52:39.6778417Z ##[endgroup] +2026-10-08T16:52:40.4364840Z No broken requirements found. +2026-10-08T16:52:40.5905951Z ##[group]Run python tools/check_ci_contract.py --check-environment +2026-10-08T16:52:40.5906507Z python tools/check_ci_contract.py --check-environment +2026-10-08T16:52:40.5950239Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:52:40.5950586Z env: +2026-10-08T16:52:40.5950859Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:52:40.5951331Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:52:40.5951789Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:52:40.5952208Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:52:40.5952618Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:52:40.5952933Z ##[endgroup] +2026-10-08T16:52:47.3810056Z Matplotlib is building the font cache; this may take a moment. +2026-10-08T16:53:01.4329598Z { +2026-10-08T16:53:01.4330050Z "accepted": true, +2026-10-08T16:53:01.4330321Z "errors": [] +2026-10-08T16:53:01.4330548Z } +2026-10-08T16:53:01.7223635Z ##[group]Run python tools/gen_protos.py +2026-10-08T16:53:01.7224048Z python tools/gen_protos.py +2026-10-08T16:53:01.7263656Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:53:01.7263991Z env: +2026-10-08T16:53:01.7264249Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:01.7264703Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:53:01.7265152Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:01.7266359Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:01.7266758Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:01.7267085Z ##[endgroup] +2026-10-08T16:53:02.1747213Z Running: C:\hostedtoolcache\windows\Python\3.12.10\x64\python.exe -m grpc_tools.protoc --proto_path=D:\a\CaptureSuite\CaptureSuite\schemas\proto --python_out=D:\a\CaptureSuite\CaptureSuite\libs\python\capture_protocol\capture_protocol\generated --descriptor_set_out=D:\a\CaptureSuite\CaptureSuite\build\generated\capture_v1.desc --include_imports --proto_path=C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages\grpc_tools\_proto capture/v1/arrays.proto capture/v1/common.proto capture/v1/control.proto capture/v1/data/emg_batch.proto capture/v1/data/imu_frame.proto capture/v1/data/numeric_batch.proto capture/v1/data/radar_doppler.proto capture/v1/data/radar_frame.proto capture/v1/data/video_timing.proto capture/v1/events.proto capture/v1/health.proto capture/v1/presets.proto capture/v1/preview.proto capture/v1/project.proto capture/v1/source.proto capture/v1/storage.proto capture/v1/worker.proto +2026-10-08T16:53:02.1752124Z Wrote Python bindings under D:\a\CaptureSuite\CaptureSuite\libs\python\capture_protocol\capture_protocol\generated +2026-10-08T16:53:02.1753025Z Wrote descriptor set D:\a\CaptureSuite\CaptureSuite\build\generated\capture_v1.desc +2026-10-08T16:53:02.3018159Z ##[group]Run git diff --exit-code -- libs/python/capture_protocol/capture_protocol/generated +2026-10-08T16:53:02.3018869Z git diff --exit-code -- libs/python/capture_protocol/capture_protocol/generated +2026-10-08T16:53:02.3058436Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:53:02.3058768Z env: +2026-10-08T16:53:02.3059035Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:02.3059503Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:53:02.3059985Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:02.3060376Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:02.3060779Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:02.3061098Z ##[endgroup] +2026-10-08T16:53:02.8470572Z ##[group]Run python tools/gen_session_schemas.py +2026-10-08T16:53:02.8471012Z python tools/gen_session_schemas.py +2026-10-08T16:53:02.8510532Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:53:02.8510874Z env: +2026-10-08T16:53:02.8511141Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:02.8511620Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:53:02.8512091Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:02.8512497Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:02.8512935Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:02.8513251Z ##[endgroup] +2026-10-08T16:53:03.1790445Z Wrote 19 schemas to D:\a\CaptureSuite\CaptureSuite\schemas\session\jsonschema +2026-10-08T16:53:03.2871205Z ##[group]Run git diff --exit-code -- schemas/session/jsonschema +2026-10-08T16:53:03.2871842Z git diff --exit-code -- schemas/session/jsonschema +2026-10-08T16:53:03.2912272Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:53:03.2912678Z env: +2026-10-08T16:53:03.2969389Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:03.2969931Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:53:03.2970406Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:03.2970816Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:03.2971213Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:03.2971763Z ##[endgroup] +2026-10-08T16:53:03.6547038Z ##[group]Run ruff check libs/python/capture_protocol libs/python/capture_session libs/python/capture_analysis libs/python/capture_worker workers/python_host desktop/capture_desktop tools tests plugins/example_sine_py plugins/lsl_bridge +2026-10-08T16:53:03.6548729Z ruff check libs/python/capture_protocol libs/python/capture_session libs/python/capture_analysis libs/python/capture_worker workers/python_host desktop/capture_desktop tools tests plugins/example_sine_py plugins/lsl_bridge +2026-10-08T16:53:03.6589774Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:53:03.6590117Z env: +2026-10-08T16:53:03.6590382Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:03.6590842Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:53:03.6591316Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:03.6591765Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:03.6592167Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:03.6592479Z ##[endgroup] +2026-10-08T16:53:04.0439418Z All checks passed! +2026-10-08T16:53:04.1471828Z ##[group]Run python tools/check_licenses.py --enforce-spdx +2026-10-08T16:53:04.1472315Z python tools/check_licenses.py --enforce-spdx +2026-10-08T16:53:04.1518903Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:53:04.1519255Z env: +2026-10-08T16:53:04.1519541Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:04.1520018Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:53:04.1520477Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:04.1520876Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:04.1521275Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:04.1521602Z ##[endgroup] +2026-10-08T16:53:04.9046500Z license check OK +2026-10-08T16:53:05.0105423Z ##[group]Run python tools/run_ci_tests.py +2026-10-08T16:53:05.0105801Z python tools/run_ci_tests.py +2026-10-08T16:53:05.0144836Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T16:53:05.0145175Z env: +2026-10-08T16:53:05.0145433Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:05.0145911Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:53:05.0146357Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:05.0146763Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:05.0147163Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:53:05.0147486Z QT_QPA_PLATFORM: offscreen +2026-10-08T16:53:05.0147703Z ##[endgroup] +2026-10-08T16:58:06.6384166Z ........................................................................ [ 13%] +2026-10-08T16:58:06.6385761Z ........................................................................ [ 26%] +2026-10-08T16:58:06.6386475Z ........................................................................ [ 39%] +2026-10-08T16:58:06.6387110Z ........................................................................ [ 52%] +2026-10-08T16:58:06.6387788Z ..........................................................ssssss........ [ 65%] +2026-10-08T16:58:06.6388427Z ........................................................................ [ 78%] +2026-10-08T16:58:06.6389064Z ........................................................................ [ 91%] +2026-10-08T16:58:06.6389621Z .................. +2026-10-08T16:58:06.6389973Z { +2026-10-08T16:58:06.6390332Z "schema": "capturesuite.test-receipt.v1", +2026-10-08T16:58:06.6390827Z "accepted": false, +2026-10-08T16:58:06.6391190Z "process_exit": null, +2026-10-08T16:58:06.6391865Z "counts": null, +2026-10-08T16:58:06.6392211Z "junit_sha256": null, +2026-10-08T16:58:06.6392573Z "problems": [ +2026-10-08T16:58:06.6392995Z "Test process did not exit successfully", +2026-10-08T16:58:06.6393608Z "JUnit unavailable or invalid: FileNotFoundError" +2026-10-08T16:58:06.6394155Z ], +2026-10-08T16:58:06.6394737Z "scope": "Process and test-evidence consistency, not clinical validation", +2026-10-08T16:58:06.6395486Z "seconds": 300.02024009999997, +2026-10-08T16:58:06.6395981Z "created_at": "2026-10-08T16:58:05.977591+00:00", +2026-10-08T16:58:06.6396905Z "run_directory": "build/evidence/python-20261008T165305Z-8ba576a8", +2026-10-08T16:58:06.6397806Z "log_sha256": "c2bf3d9313504aa13db59b07ce25b84c5cd3fcfc99331a60e3d0da7351784408", +2026-10-08T16:58:06.6398669Z "source_commit": "0de94b767061ec1fe5c05d11c6baa36ec9ddf16b", +2026-10-08T16:58:06.6399214Z "source_worktree_dirty": false, +2026-10-08T16:58:06.6399991Z "source_tree_sha256": "54236876c74e30d97fb8ef1a930918dec17b2ca7d719fcdb47ca1af3bc6f1bed", +2026-10-08T16:58:06.6400869Z "source_file_count": 1129, +2026-10-08T16:58:06.6401346Z "github": { +2026-10-08T16:58:06.6401732Z "GITHUB_ACTIONS": "true", +2026-10-08T16:58:06.6402215Z "GITHUB_EVENT_NAME": "pull_request", +2026-10-08T16:58:06.6402861Z "GITHUB_SHA": "0de94b767061ec1fe5c05d11c6baa36ec9ddf16b", +2026-10-08T16:58:06.6403516Z "GITHUB_REF": "refs/pull/71/merge", +2026-10-08T16:58:06.6404167Z "GITHUB_HEAD_REF": "work/analysis-history-401c5d17da79", +2026-10-08T16:58:06.6405106Z "GITHUB_BASE_REF": "main", +2026-10-08T16:58:06.6405673Z "GITHUB_RUN_ID": "37811934426", +2026-10-08T16:58:06.6406492Z "GITHUB_WORKFLOW_REF": "Jacob-Met/CaptureSuite/.github/workflows/ci.yml@refs/pull/71/merge" +2026-10-08T16:58:06.6407237Z }, +2026-10-08T16:58:06.6407603Z "source_unchanged_during_test": true +2026-10-08T16:58:06.6408101Z } +2026-10-08T16:58:06.7385198Z ##[error]Process completed with exit code 1. +2026-10-08T16:58:06.7589535Z ##[group]Run actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a +2026-10-08T16:58:06.7590073Z with: +2026-10-08T16:58:06.7590317Z name: python-test-evidence +2026-10-08T16:58:06.7590610Z path: build/evidence/ +2026-10-08T16:58:06.7590879Z if-no-files-found: warn +2026-10-08T16:58:06.7591515Z retention-days: 7 +2026-10-08T16:58:06.7591837Z compression-level: 6 +2026-10-08T16:58:06.7592109Z overwrite: false +2026-10-08T16:58:06.7592390Z include-hidden-files: false +2026-10-08T16:58:06.7592661Z archive: true +2026-10-08T16:58:06.7592908Z env: +2026-10-08T16:58:06.7593211Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:58:06.7593726Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T16:58:06.7594241Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:58:06.7594690Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:58:06.7595203Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T16:58:06.7595573Z ##[endgroup] +2026-10-08T16:58:07.1168016Z With the provided path, there will be 280 files uploaded +2026-10-08T16:58:07.1174341Z Artifact name is valid! +2026-10-08T16:58:07.1175964Z Root directory input is valid! +2026-10-08T16:58:07.3285502Z Uploading artifact: python-test-evidence.zip +2026-10-08T16:58:07.3332109Z Beginning upload of artifact content to blob storage +2026-10-08T16:58:07.8565612Z Uploaded bytes 1600563 +2026-10-08T16:58:07.8696378Z Finished uploading artifact content to blob storage! +2026-10-08T16:58:07.8698090Z SHA256 digest of uploaded artifact is 5d0a77f1b24a3807d407e11e847e0354a3876c6ffbbe1d937a188dc0896c18f3 +2026-10-08T16:58:07.8699101Z Finalizing artifact upload +2026-10-08T16:58:08.1441604Z Artifact python-test-evidence successfully finalized. Artifact ID 11566210891 +2026-10-08T16:58:08.1443437Z Artifact python-test-evidence has been successfully uploaded! Final size is 1600563 bytes. Artifact ID is 11566210891 +2026-10-08T16:58:08.1449751Z Artifact download URL: https://github.com/Jacob-Met/CaptureSuite/actions/runs/37811934426/artifacts/11566210891 +2026-10-08T16:58:08.1794732Z Post job cleanup. +2026-10-08T16:58:08.4211801Z [command]"C:\Program Files\Git\bin\git.exe" version +2026-10-08T16:58:08.4510656Z git version 2.56.0.windows.1 +2026-10-08T16:58:08.4585935Z Temporarily overriding HOME='D:\a\_temp\c5c09ce2-1082-4774-8541-c786d7428b36' before making global git config changes +2026-10-08T16:58:08.4587608Z Adding repository directory to the temporary git global config as a safe directory +2026-10-08T16:58:08.4600414Z [command]"C:\Program Files\Git\bin\git.exe" config --global --add safe.directory D:\a\CaptureSuite\CaptureSuite +2026-10-08T16:58:08.4932217Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp core\.sshCommand +2026-10-08T16:58:08.5262548Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :\"" +2026-10-08T16:58:09.0448059Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +2026-10-08T16:58:09.0731062Z http.https://github.com/.extraheader +2026-10-08T16:58:09.0768682Z [command]"C:\Program Files\Git\bin\git.exe" config --local --unset-all http.https://github.com/.extraheader +2026-10-08T16:58:09.1078354Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :\"" +2026-10-08T16:58:09.6026739Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp ^includeIf\.gitdir: +2026-10-08T16:58:09.6356072Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "git config --local --show-origin --name-only --get-regexp remote.origin.url" +2026-10-08T16:58:10.1268790Z Cleaning up orphan processes +2026-10-08T16:58:10.1510083Z Terminate orphan process: pid (6732) (vctip) +2026-10-08T16:58:10.1569860Z Terminate orphan process: pid (5600) (MSBuild) +2026-10-08T16:58:10.1717959Z Terminate orphan process: pid (2176) (conhost) +2026-10-08T16:58:10.1726130Z ##[warning]Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@v4, actions/setup-python@v5. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/ diff --git a/docs/receiving/analysis-history-ci-budget-401c5d17da79/retry-windows-timeout.log b/docs/receiving/analysis-history-ci-budget-401c5d17da79/retry-windows-timeout.log new file mode 100644 index 00000000..bb77d92c --- /dev/null +++ b/docs/receiving/analysis-history-ci-budget-401c5d17da79/retry-windows-timeout.log @@ -0,0 +1,542 @@ +2026-10-08T17:56:47.7326226Z Current runner version: '2.337.0' +2026-10-08T17:56:47.7346244Z ##[group]Runner Image Provisioner +2026-10-08T17:56:47.7346904Z Hosted Compute Agent +2026-10-08T17:56:47.7347356Z Version: 20261002.596 +2026-10-08T17:56:47.7347798Z Commit: c3d12f3313a95f25162a1503be624f3b0617f8c0 +2026-10-08T17:56:47.7348319Z Build Date: 2026-10-02T22:28:27Z +2026-10-08T17:56:47.7348824Z Worker ID: {6648adac-1715-40e8-a42f-f6295f46e7d0} +2026-10-08T17:56:47.7349311Z Region: westus3 +2026-10-08T17:56:47.7349696Z Cloud: Azure +2026-10-08T17:56:47.7350068Z ##[endgroup] +2026-10-08T17:56:47.7351049Z ##[group]Operating System +2026-10-08T17:56:47.7351517Z Microsoft Windows Server 2022 +2026-10-08T17:56:47.7351967Z 10.0.20348 +2026-10-08T17:56:47.7352342Z Datacenter +2026-10-08T17:56:47.7352706Z ##[endgroup] +2026-10-08T17:56:47.7353083Z ##[group]Runner Image +2026-10-08T17:56:47.7353498Z Image: windows-2022 +2026-10-08T17:56:47.7353891Z Version: 20261004.326.1 +2026-10-08T17:56:47.7354963Z Included Software: https://github.com/actions/runner-images/blob/win22/20261004.326/images/windows/Windows2022-Readme.md +2026-10-08T17:56:47.7356097Z Image Release: https://github.com/actions/runner-images/releases/tag/win22%2F20261004.326 +2026-10-08T17:56:47.7356811Z ##[endgroup] +2026-10-08T17:56:47.7357715Z ##[group]GITHUB_TOKEN Permissions +2026-10-08T17:56:47.7359089Z Contents: read +2026-10-08T17:56:47.7359513Z Metadata: read +2026-10-08T17:56:47.7359973Z Packages: read +2026-10-08T17:56:47.7360405Z ##[endgroup] +2026-10-08T17:56:47.7361993Z Secret source: Actions +2026-10-08T17:56:47.7362658Z Cache mode: write +2026-10-08T17:56:47.7363119Z Prepare workflow directory +2026-10-08T17:56:47.7632414Z Prepare all required actions +2026-10-08T17:56:47.7685714Z Getting action download info +2026-10-08T17:56:48.0967089Z Download action repository 'actions/checkout@v4' (SHA:11d5960a326750d5838078e36cf38b85af677262) +2026-10-08T17:56:48.2383804Z Download action repository 'actions/setup-python@v5' (SHA:a26af69be951a213d495a4c3e4e4022e16d87065) +2026-10-08T17:56:48.5032702Z Download action repository 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' (SHA:043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) +2026-10-08T17:56:48.8673977Z Complete job name: python +2026-10-08T17:56:49.1352281Z ##[group]Run actions/checkout@v4 +2026-10-08T17:56:49.1353324Z with: +2026-10-08T17:56:49.1353651Z repository: Jacob-Met/CaptureSuite +2026-10-08T17:56:49.1357143Z token: *** +2026-10-08T17:56:49.1357461Z ssh-strict: true +2026-10-08T17:56:49.1357787Z ssh-user: git +2026-10-08T17:56:49.1358111Z persist-credentials: true +2026-10-08T17:56:49.1358463Z clean: true +2026-10-08T17:56:49.1358787Z sparse-checkout-cone-mode: true +2026-10-08T17:56:49.1359164Z fetch-depth: 1 +2026-10-08T17:56:49.1359474Z fetch-tags: false +2026-10-08T17:56:49.1359786Z show-progress: true +2026-10-08T17:56:49.1360109Z lfs: false +2026-10-08T17:56:49.1360416Z submodules: false +2026-10-08T17:56:49.1360738Z set-safe-directory: true +2026-10-08T17:56:49.1361099Z allow-unsafe-pr-checkout: false +2026-10-08T17:56:49.1361734Z ##[endgroup] +2026-10-08T17:56:49.2523169Z Syncing repository: Jacob-Met/CaptureSuite +2026-10-08T17:56:49.2524574Z ##[group]Getting Git version info +2026-10-08T17:56:49.2525171Z Working directory is 'D:\a\CaptureSuite\CaptureSuite' +2026-10-08T17:56:49.3362137Z [command]"C:\Program Files\Git\bin\git.exe" version +2026-10-08T17:56:50.7414136Z git version 2.56.0.windows.1 +2026-10-08T17:56:50.7445182Z ##[endgroup] +2026-10-08T17:56:50.7459491Z Temporarily overriding HOME='D:\a\_temp\f1d6413d-486e-499a-89e9-ed09f2312c5c' before making global git config changes +2026-10-08T17:56:50.7460400Z Adding repository directory to the temporary git global config as a safe directory +2026-10-08T17:56:50.7468373Z [command]"C:\Program Files\Git\bin\git.exe" config --global --add safe.directory D:\a\CaptureSuite\CaptureSuite +2026-10-08T17:56:50.8460419Z Deleting the contents of 'D:\a\CaptureSuite\CaptureSuite' +2026-10-08T17:56:50.8464528Z ##[group]Initializing the repository +2026-10-08T17:56:50.8472143Z [command]"C:\Program Files\Git\bin\git.exe" init D:\a\CaptureSuite\CaptureSuite +2026-10-08T17:56:50.9891136Z Initialized empty Git repository in D:/a/CaptureSuite/CaptureSuite/.git/ +2026-10-08T17:56:50.9927986Z [command]"C:\Program Files\Git\bin\git.exe" remote add origin https://github.com/Jacob-Met/CaptureSuite +2026-10-08T17:56:51.0933044Z ##[endgroup] +2026-10-08T17:56:51.0933519Z ##[group]Disabling automatic garbage collection +2026-10-08T17:56:51.0940936Z [command]"C:\Program Files\Git\bin\git.exe" config --local gc.auto 0 +2026-10-08T17:56:51.1164314Z ##[endgroup] +2026-10-08T17:56:51.1164673Z ##[group]Setting up auth +2026-10-08T17:56:51.1173553Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp core\.sshCommand +2026-10-08T17:56:51.1410006Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :\"" +2026-10-08T17:56:54.5328680Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +2026-10-08T17:56:54.5565190Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :\"" +2026-10-08T17:56:55.4711341Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp ^includeIf\.gitdir: +2026-10-08T17:56:55.4979962Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "git config --local --show-origin --name-only --get-regexp remote.origin.url" +2026-10-08T17:56:55.8909181Z [command]"C:\Program Files\Git\bin\git.exe" config --local http.https://github.com/.extraheader "AUTHORIZATION: basic ***" +2026-10-08T17:56:55.9144963Z ##[endgroup] +2026-10-08T17:56:55.9154900Z ##[group]Fetching the repository +2026-10-08T17:56:55.9157750Z [command]"C:\Program Files\Git\bin\git.exe" -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +0de94b767061ec1fe5c05d11c6baa36ec9ddf16b:refs/remotes/pull/71/merge +2026-10-08T17:56:59.6644767Z From https://github.com/Jacob-Met/CaptureSuite +2026-10-08T17:56:59.6645515Z * [new ref] 0de94b767061ec1fe5c05d11c6baa36ec9ddf16b -> pull/71/merge +2026-10-08T17:56:59.6672909Z ##[endgroup] +2026-10-08T17:56:59.6673552Z ##[group]Determining the checkout info +2026-10-08T17:56:59.6675313Z ##[endgroup] +2026-10-08T17:56:59.6684343Z [command]"C:\Program Files\Git\bin\git.exe" sparse-checkout disable +2026-10-08T17:56:59.7190073Z [command]"C:\Program Files\Git\bin\git.exe" config --local --unset-all extensions.worktreeConfig +2026-10-08T17:56:59.7446670Z ##[group]Checking out the ref +2026-10-08T17:56:59.7447158Z [command]"C:\Program Files\Git\bin\git.exe" checkout --progress --force refs/remotes/pull/71/merge +2026-10-08T17:57:00.0432897Z Note: switching to 'refs/remotes/pull/71/merge'. +2026-10-08T17:57:00.0433269Z +2026-10-08T17:57:00.0433517Z You are in 'detached HEAD' state. You can look around, make experimental +2026-10-08T17:57:00.0434209Z changes and commit them, and you can discard any commits you make in this +2026-10-08T17:57:00.0434683Z state without impacting any branches by switching back to a branch. +2026-10-08T17:57:00.0434922Z +2026-10-08T17:57:00.0435068Z If you want to create a new branch to retain commits you create, you may +2026-10-08T17:57:00.0435470Z do so (now or later) by using -c with the switch command. Example: +2026-10-08T17:57:00.0435668Z +2026-10-08T17:57:00.0435777Z git switch -c +2026-10-08T17:57:00.0435922Z +2026-10-08T17:57:00.0436007Z Or undo this operation with: +2026-10-08T17:57:00.0436126Z +2026-10-08T17:57:00.0436195Z git switch - +2026-10-08T17:57:00.0436284Z +2026-10-08T17:57:00.0436451Z Turn off this advice by setting config variable advice.detachedHead to false +2026-10-08T17:57:00.0437560Z +2026-10-08T17:57:00.0564135Z HEAD is now at 0de94b7 Merge aefaffe03331f5c8e0cc41dfd75ce9c81f9d09fe into 3cbb5300bdc79c157370d1b3e599a6c82752d54a +2026-10-08T17:57:00.0618418Z ##[endgroup] +2026-10-08T17:57:00.0989617Z [command]"C:\Program Files\Git\bin\git.exe" log -1 --format=%H +2026-10-08T17:57:00.2602209Z 0de94b767061ec1fe5c05d11c6baa36ec9ddf16b +2026-10-08T17:57:00.2940222Z ##[group]Run actions/setup-python@v5 +2026-10-08T17:57:00.2940499Z with: +2026-10-08T17:57:00.2940656Z python-version: 3.12 +2026-10-08T17:57:00.2940844Z check-latest: false +2026-10-08T17:57:00.2942749Z token: *** +2026-10-08T17:57:00.2942921Z update-environment: true +2026-10-08T17:57:00.2943102Z allow-prereleases: false +2026-10-08T17:57:00.2943271Z freethreaded: false +2026-10-08T17:57:00.2943428Z ##[endgroup] +2026-10-08T17:57:00.4119855Z ##[group]Installed versions +2026-10-08T17:57:00.5101298Z (node:1592) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead. +2026-10-08T17:57:00.5102205Z (Use `node --trace-deprecation ...` to show where the warning was created) +2026-10-08T17:57:00.5102685Z Successfully set up CPython (3.12.10) +2026-10-08T17:57:00.5116627Z ##[endgroup] +2026-10-08T17:57:00.5310264Z ##[group]Run python -m pip install -r requirements-ci.txt +2026-10-08T17:57:00.5310724Z python -m pip install -r requirements-ci.txt +2026-10-08T17:57:00.5422103Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:57:00.5422370Z env: +2026-10-08T17:57:00.5422579Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:57:00.5422956Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:57:00.5423302Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:57:00.5423603Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:57:00.5423898Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:57:00.5424155Z ##[endgroup] +2026-10-08T17:57:13.8364101Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_protocol (from -r requirements-ci.txt (line 3)) +2026-10-08T17:57:13.8387001Z Installing build dependencies: started +2026-10-08T17:57:16.9915103Z Installing build dependencies: finished with status 'done' +2026-10-08T17:57:16.9927473Z Checking if build backend supports build_editable: started +2026-10-08T17:57:17.6027485Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T17:57:17.6045800Z Getting requirements to build editable: started +2026-10-08T17:57:18.1678876Z Getting requirements to build editable: finished with status 'done' +2026-10-08T17:57:18.1700620Z Preparing editable metadata (pyproject.toml): started +2026-10-08T17:57:18.4172009Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T17:57:18.4209664Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_session (from -r requirements-ci.txt (line 4)) +2026-10-08T17:57:18.4232429Z Installing build dependencies: started +2026-10-08T17:57:19.8623999Z Installing build dependencies: finished with status 'done' +2026-10-08T17:57:19.8636404Z Checking if build backend supports build_editable: started +2026-10-08T17:57:20.2740652Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T17:57:20.2757960Z Getting requirements to build editable: started +2026-10-08T17:57:20.7574938Z Getting requirements to build editable: finished with status 'done' +2026-10-08T17:57:20.7596486Z Preparing editable metadata (pyproject.toml): started +2026-10-08T17:57:21.0189141Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T17:57:21.0224232Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_analysis +2026-10-08T17:57:21.0244717Z Installing build dependencies: started +2026-10-08T17:57:23.8436096Z Installing build dependencies: finished with status 'done' +2026-10-08T17:57:23.8447741Z Checking if build backend supports build_editable: started +2026-10-08T17:57:24.4631077Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T17:57:24.4647255Z Getting requirements to build editable: started +2026-10-08T17:57:25.2352957Z Getting requirements to build editable: finished with status 'done' +2026-10-08T17:57:25.2376307Z Preparing editable metadata (pyproject.toml): started +2026-10-08T17:57:25.5709018Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T17:57:25.5746651Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/libs/python/capture_worker (from -r requirements-ci.txt (line 6)) +2026-10-08T17:57:25.5766510Z Installing build dependencies: started +2026-10-08T17:57:27.7691170Z Installing build dependencies: finished with status 'done' +2026-10-08T17:57:27.7704662Z Checking if build backend supports build_editable: started +2026-10-08T17:57:28.4184415Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T17:57:28.4201298Z Getting requirements to build editable: started +2026-10-08T17:57:30.0800787Z Getting requirements to build editable: finished with status 'done' +2026-10-08T17:57:30.0820319Z Preparing editable metadata (pyproject.toml): started +2026-10-08T17:57:30.3877760Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T17:57:30.3911213Z Obtaining file:///D:/a/CaptureSuite/CaptureSuite/desktop +2026-10-08T17:57:30.3932556Z Installing build dependencies: started +2026-10-08T17:57:32.7957072Z Installing build dependencies: finished with status 'done' +2026-10-08T17:57:32.7968781Z Checking if build backend supports build_editable: started +2026-10-08T17:57:33.2265032Z Checking if build backend supports build_editable: finished with status 'done' +2026-10-08T17:57:33.2281837Z Getting requirements to build editable: started +2026-10-08T17:57:33.6587068Z Getting requirements to build editable: finished with status 'done' +2026-10-08T17:57:33.6607347Z Preparing editable metadata (pyproject.toml): started +2026-10-08T17:57:33.9067811Z Preparing editable metadata (pyproject.toml): finished with status 'done' +2026-10-08T17:57:34.5565953Z Collecting grpcio-tools<1.63,>=1.62 (from -r requirements-ci.txt (line 8)) +2026-10-08T17:57:34.6811557Z Downloading grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl.metadata (6.4 kB) +2026-10-08T17:57:34.9110048Z Collecting mcap<2,>=1.1 (from -r requirements-ci.txt (line 9)) +2026-10-08T17:57:34.9169092Z Downloading mcap-1.5.0-py3-none-any.whl.metadata (380 bytes) +2026-10-08T17:57:35.0593349Z Collecting pytest>=8 (from -r requirements-ci.txt (line 10)) +2026-10-08T17:57:35.0673129Z Downloading pytest-9.1.1-py3-none-any.whl.metadata (7.6 kB) +2026-10-08T17:57:35.1618220Z Collecting pytest-cov>=5 (from -r requirements-ci.txt (line 11)) +2026-10-08T17:57:35.1657087Z Downloading pytest_cov-7.1.0-py3-none-any.whl.metadata (32 kB) +2026-10-08T17:57:35.5579775Z Collecting ruff<1,>=0.6 (from -r requirements-ci.txt (line 12)) +2026-10-08T17:57:35.5727113Z Downloading ruff-0.16.10-py3-none-win_amd64.whl.metadata (21 kB) +2026-10-08T17:57:35.9518688Z Collecting protobuf<5,>=4.25 (from capture-protocol==0.1.0->-r requirements-ci.txt (line 3)) +2026-10-08T17:57:35.9591566Z Downloading protobuf-4.25.9-cp310-abi3-win_amd64.whl.metadata (541 bytes) +2026-10-08T17:57:36.1657639Z Collecting jsonschema>=4.21 (from capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T17:57:36.1701651Z Downloading jsonschema-4.26.0-py3-none-any.whl.metadata (7.6 kB) +2026-10-08T17:57:36.3344934Z Collecting pyyaml>=6.0 (from capture-analysis==0.1.0) +2026-10-08T17:57:36.3387571Z Downloading pyyaml-6.0.3-cp312-cp312-win_amd64.whl.metadata (2.4 kB) +2026-10-08T17:57:36.4501523Z Collecting PySide6<7,>=6.6 (from capture-desktop==0.1.0) +2026-10-08T17:57:36.4543193Z Downloading pyside6-6.12.0-cp310-abi3-win_amd64.whl.metadata (5.7 kB) +2026-10-08T17:57:36.6845401Z Collecting numpy>=1.26 (from capture-analysis==0.1.0) +2026-10-08T17:57:36.6892856Z Downloading numpy-2.5.3-cp312-cp312-win_amd64.whl.metadata (6.6 kB) +2026-10-08T17:57:36.8787036Z Collecting scipy>=1.11 (from capture-analysis==0.1.0) +2026-10-08T17:57:36.8845686Z Downloading scipy-1.18.1-cp312-cp312-win_amd64.whl.metadata (61 kB) +2026-10-08T17:57:37.0844933Z Collecting pandas>=2.1 (from capture-analysis==0.1.0) +2026-10-08T17:57:37.0942953Z Downloading pandas-3.0.6-cp312-cp312-win_amd64.whl.metadata (19 kB) +2026-10-08T17:57:37.7307361Z Collecting pyarrow>=14.0 (from capture-analysis==0.1.0) +2026-10-08T17:57:37.7386891Z Downloading pyarrow-25.0.1-cp312-cp312-win_amd64.whl.metadata (3.0 kB) +2026-10-08T17:57:37.9172942Z Collecting matplotlib>=3.8 (from capture-analysis==0.1.0) +2026-10-08T17:57:37.9225658Z Downloading matplotlib-3.11.2-cp312-cp312-win_amd64.whl.metadata (80 kB) +2026-10-08T17:57:38.0875701Z Collecting pyqtgraph>=0.13 (from capture-desktop==0.1.0) +2026-10-08T17:57:38.0930842Z Downloading pyqtgraph-0.14.0-py3-none-any.whl.metadata (1.5 kB) +2026-10-08T17:57:38.6176555Z Collecting grpcio>=1.62.3 (from grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T17:57:38.6350630Z Downloading grpcio-1.84.0-cp312-cp312-win_amd64.whl.metadata (3.9 kB) +2026-10-08T17:57:38.8024247Z Collecting setuptools (from grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T17:57:38.8176033Z Using cached setuptools-84.0.0-py3-none-any.whl.metadata (6.6 kB) +2026-10-08T17:57:39.1502545Z Collecting lz4 (from mcap<2,>=1.1->-r requirements-ci.txt (line 9)) +2026-10-08T17:57:39.1711702Z Downloading lz4-4.4.5-cp312-cp312-win_amd64.whl.metadata (3.9 kB) +2026-10-08T17:57:39.4763531Z Collecting zstandard (from mcap<2,>=1.1->-r requirements-ci.txt (line 9)) +2026-10-08T17:57:39.4929874Z Downloading zstandard-0.25.0-cp312-cp312-win_amd64.whl.metadata (3.3 kB) +2026-10-08T17:57:39.6890568Z Collecting PySide6_Essentials==6.12.0 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T17:57:39.6965552Z Downloading pyside6_essentials-6.12.0-cp310-abi3-win_amd64.whl.metadata (3.9 kB) +2026-10-08T17:57:39.8621920Z Collecting PySide6_Addons==6.12.0 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T17:57:39.9265169Z Downloading pyside6_addons-6.12.0-cp310-abi3-win_amd64.whl.metadata (4.4 kB) +2026-10-08T17:57:40.1534040Z Collecting PySide6_WebEngine==6.12.0.140 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T17:57:40.1598143Z Downloading pyside6_webengine-6.12.0.140-cp310-abi3-win_amd64.whl.metadata (3.7 kB) +2026-10-08T17:57:40.4024023Z Collecting PySide6_Pdf==6.12.0.140 (from PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T17:57:40.4209875Z Downloading pyside6_pdf-6.12.0.140-cp310-abi3-win_amd64.whl.metadata (3.6 kB) +2026-10-08T17:57:40.5825837Z Collecting shiboken6==6.12.0 (from PySide6_Essentials==6.12.0->PySide6<7,>=6.6->capture-desktop==0.1.0) +2026-10-08T17:57:40.6176037Z Downloading shiboken6-6.12.0-cp310-abi3-win_amd64.whl.metadata (2.6 kB) +2026-10-08T17:57:40.6891062Z Requirement already satisfied: colorama>=0.4 in C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages (from pytest>=8->-r requirements-ci.txt (line 10)) (0.4.6) +2026-10-08T17:57:40.7921965Z Collecting iniconfig>=1.0.1 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T17:57:40.7962808Z Downloading iniconfig-2.3.1-py3-none-any.whl.metadata (2.8 kB) +2026-10-08T17:57:40.9377792Z Requirement already satisfied: packaging>=22 in C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages (from pytest>=8->-r requirements-ci.txt (line 10)) (26.3) +2026-10-08T17:57:40.9990693Z Collecting pluggy<2,>=1.5 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T17:57:41.0094846Z Downloading pluggy-1.6.0-py3-none-any.whl.metadata (4.8 kB) +2026-10-08T17:57:41.1571054Z Collecting pygments>=2.7.2 (from pytest>=8->-r requirements-ci.txt (line 10)) +2026-10-08T17:57:41.1650762Z Downloading pygments-2.21.0-py3-none-any.whl.metadata (2.5 kB) +2026-10-08T17:57:41.5966550Z Collecting coverage>=7.10.6 (from coverage[toml]>=7.10.6->pytest-cov>=5->-r requirements-ci.txt (line 11)) +2026-10-08T17:57:41.6009924Z Downloading coverage-7.16.2-cp312-cp312-win_amd64.whl.metadata (8.4 kB) +2026-10-08T17:57:41.7848303Z Collecting typing-extensions~=4.12 (from grpcio>=1.62.3->grpcio-tools<1.63,>=1.62->-r requirements-ci.txt (line 8)) +2026-10-08T17:57:41.7887694Z Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB) +2026-10-08T17:57:41.8752378Z Collecting attrs>=22.2.0 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T17:57:42.0100452Z Downloading attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB) +2026-10-08T17:57:42.0938467Z Collecting jsonschema-specifications>=2023.03.6 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T17:57:42.0976801Z Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB) +2026-10-08T17:57:42.5209828Z Collecting referencing>=0.28.4 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T17:57:42.5249719Z Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB) +2026-10-08T17:57:42.9112500Z Collecting rpds-py>=0.25.0 (from jsonschema>=4.21->capture-session==0.1.0->-r requirements-ci.txt (line 4)) +2026-10-08T17:57:42.9802780Z Downloading rpds_py-2026.9.1-cp312-cp312-win_amd64.whl.metadata (4.2 kB) +2026-10-08T17:57:43.1143975Z Collecting contourpy>=1.0.1 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T17:57:43.1201884Z Downloading contourpy-1.4.0-cp312-cp312-win_amd64.whl.metadata (3.8 kB) +2026-10-08T17:57:43.3583815Z Collecting cycler>=0.10 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T17:57:43.3625932Z Downloading cycler-0.12.1-py3-none-any.whl.metadata (3.8 kB) +2026-10-08T17:57:43.5677686Z Collecting fonttools>=4.28.2 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T17:57:43.5843514Z Downloading fonttools-4.66.1-cp312-cp312-win_amd64.whl.metadata (132 kB) +2026-10-08T17:57:43.7475543Z Collecting kiwisolver>=1.3.1 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T17:57:43.8181272Z Downloading kiwisolver-1.5.1-cp312-cp312-win_amd64.whl.metadata (5.2 kB) +2026-10-08T17:57:44.0452060Z Collecting pillow>=9 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T17:57:44.1538680Z Downloading pillow-12.3.0-cp312-cp312-win_amd64.whl.metadata (9.3 kB) +2026-10-08T17:57:44.2928714Z Collecting pyparsing>=3 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T17:57:44.2989679Z Downloading pyparsing-3.3.3-py3-none-any.whl.metadata (5.9 kB) +2026-10-08T17:57:44.3946238Z Collecting python-dateutil>=2.7 (from matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T17:57:44.3994854Z Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB) +2026-10-08T17:57:44.5048514Z Collecting tzdata (from pandas>=2.1->capture-analysis==0.1.0) +2026-10-08T17:57:44.5089100Z Downloading tzdata-2026.5-py2.py3-none-any.whl.metadata (1.4 kB) +2026-10-08T17:57:44.6285074Z Collecting six>=1.5 (from python-dateutil>=2.7->matplotlib>=3.8->capture-analysis==0.1.0) +2026-10-08T17:57:44.6321879Z Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB) +2026-10-08T17:57:44.7305405Z Downloading grpcio_tools-1.62.3-cp312-cp312-win_amd64.whl (1.1 MB) +2026-10-08T17:57:44.7963909Z ---------------------------------------- 1.1/1.1 MB 12.6 MB/s 0:00:00 +2026-10-08T17:57:44.8086067Z Downloading mcap-1.5.0-py3-none-any.whl (21 kB) +2026-10-08T17:57:44.9467807Z Downloading ruff-0.16.10-py3-none-win_amd64.whl (10.6 MB) +2026-10-08T17:57:45.0999689Z ---------------------------------------- 10.6/10.6 MB 73.2 MB/s 0:00:00 +2026-10-08T17:57:45.1040040Z Downloading protobuf-4.25.9-cp310-abi3-win_amd64.whl (413 kB) +2026-10-08T17:57:45.1582575Z Downloading pyside6-6.12.0-cp310-abi3-win_amd64.whl (578 kB) +2026-10-08T17:57:45.2071187Z ---------------------------------------- 579.0/579.0 kB 6.7 MB/s 0:00:00 +2026-10-08T17:57:45.2198348Z Downloading pyside6_addons-6.12.0-cp310-abi3-win_amd64.whl (40.5 MB) +2026-10-08T17:57:47.2939682Z ---------------------------------------- 40.5/40.5 MB 19.4 MB/s 0:00:02 +2026-10-08T17:57:47.3020006Z Downloading pyside6_essentials-6.12.0-cp310-abi3-win_amd64.whl (82.2 MB) +2026-10-08T17:57:49.4867142Z ---------------------------------------- 82.2/82.2 MB 37.4 MB/s 0:00:02 +2026-10-08T17:57:49.4924167Z Downloading pyside6_pdf-6.12.0.140-cp310-abi3-win_amd64.whl (3.0 MB) +2026-10-08T17:57:49.5356746Z ---------------------------------------- 3.0/3.0 MB 57.9 MB/s 0:00:00 +2026-10-08T17:57:49.5419306Z Downloading pyside6_webengine-6.12.0.140-cp310-abi3-win_amd64.whl (131.7 MB) +2026-10-08T17:57:53.2829632Z ---------------------------------------- 131.7/131.7 MB 35.2 MB/s 0:00:03 +2026-10-08T17:57:53.2882494Z Downloading shiboken6-6.12.0-cp310-abi3-win_amd64.whl (1.3 MB) +2026-10-08T17:57:53.3184971Z ---------------------------------------- 1.3/1.3 MB 32.4 MB/s 0:00:00 +2026-10-08T17:57:53.3221768Z Downloading pytest-9.1.1-py3-none-any.whl (386 kB) +2026-10-08T17:57:53.3598283Z Downloading pluggy-1.6.0-py3-none-any.whl (20 kB) +2026-10-08T17:57:53.3866792Z Downloading pytest_cov-7.1.0-py3-none-any.whl (22 kB) +2026-10-08T17:57:53.4081921Z Downloading coverage-7.16.2-cp312-cp312-win_amd64.whl (226 kB) +2026-10-08T17:57:53.4358884Z Downloading grpcio-1.84.0-cp312-cp312-win_amd64.whl (5.3 MB) +2026-10-08T17:57:53.5071378Z ---------------------------------------- 5.3/5.3 MB 64.0 MB/s 0:00:00 +2026-10-08T17:57:53.5110474Z Downloading typing_extensions-4.16.0-py3-none-any.whl (45 kB) +2026-10-08T17:57:53.5318028Z Downloading iniconfig-2.3.1-py3-none-any.whl (7.6 kB) +2026-10-08T17:57:53.5574286Z Downloading jsonschema-4.26.0-py3-none-any.whl (90 kB) +2026-10-08T17:57:53.5817631Z Downloading attrs-26.1.0-py3-none-any.whl (67 kB) +2026-10-08T17:57:53.6154151Z Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB) +2026-10-08T17:57:53.6449941Z Downloading matplotlib-3.11.2-cp312-cp312-win_amd64.whl (9.3 MB) +2026-10-08T17:57:53.7813182Z ---------------------------------------- 9.3/9.3 MB 72.7 MB/s 0:00:00 +2026-10-08T17:57:53.7868230Z Downloading contourpy-1.4.0-cp312-cp312-win_amd64.whl (234 kB) +2026-10-08T17:57:53.8214482Z Downloading cycler-0.12.1-py3-none-any.whl (8.3 kB) +2026-10-08T17:57:53.8454690Z Downloading fonttools-4.66.1-cp312-cp312-win_amd64.whl (2.5 MB) +2026-10-08T17:57:53.8822107Z ---------------------------------------- 2.5/2.5 MB 71.8 MB/s 0:00:00 +2026-10-08T17:57:53.8862482Z Downloading kiwisolver-1.5.1-cp312-cp312-win_amd64.whl (70 kB) +2026-10-08T17:57:53.9106105Z Downloading numpy-2.5.3-cp312-cp312-win_amd64.whl (12.6 MB) +2026-10-08T17:57:54.2465174Z ---------------------------------------- 12.6/12.6 MB 37.5 MB/s 0:00:00 +2026-10-08T17:57:54.2523571Z Downloading pandas-3.0.6-cp312-cp312-win_amd64.whl (9.7 MB) +2026-10-08T17:57:54.3714314Z ---------------------------------------- 9.7/9.7 MB 86.2 MB/s 0:00:00 +2026-10-08T17:57:54.3756524Z Downloading pillow-12.3.0-cp312-cp312-win_amd64.whl (7.2 MB) +2026-10-08T17:57:54.4471987Z ---------------------------------------- 7.2/7.2 MB 112.3 MB/s 0:00:00 +2026-10-08T17:57:54.4520863Z Downloading pyarrow-25.0.1-cp312-cp312-win_amd64.whl (28.0 MB) +2026-10-08T17:57:55.2799863Z ---------------------------------------- 28.0/28.0 MB 33.4 MB/s 0:00:00 +2026-10-08T17:57:55.2837898Z Downloading pygments-2.21.0-py3-none-any.whl (1.3 MB) +2026-10-08T17:57:55.4341371Z ---------------------------------------- 1.3/1.3 MB 7.0 MB/s 0:00:00 +2026-10-08T17:57:55.4382688Z Downloading pyparsing-3.3.3-py3-none-any.whl (126 kB) +2026-10-08T17:57:55.5311098Z Downloading pyqtgraph-0.14.0-py3-none-any.whl (1.9 MB) +2026-10-08T17:57:55.5906121Z ---------------------------------------- 1.9/1.9 MB 26.8 MB/s 0:00:00 +2026-10-08T17:57:55.5944826Z Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB) +2026-10-08T17:57:55.6220928Z Downloading pyyaml-6.0.3-cp312-cp312-win_amd64.whl (154 kB) +2026-10-08T17:57:57.7504386Z Downloading referencing-0.37.0-py3-none-any.whl (26 kB) +2026-10-08T17:57:57.7775378Z Downloading rpds_py-2026.9.1-cp312-cp312-win_amd64.whl (222 kB) +2026-10-08T17:57:57.8089219Z Downloading scipy-1.18.1-cp312-cp312-win_amd64.whl (36.7 MB) +2026-10-08T17:57:58.6055140Z ---------------------------------------- 36.7/36.7 MB 45.7 MB/s 0:00:00 +2026-10-08T17:57:58.6096320Z Downloading six-1.17.0-py2.py3-none-any.whl (11 kB) +2026-10-08T17:57:58.6427259Z Downloading lz4-4.4.5-cp312-cp312-win_amd64.whl (99 kB) +2026-10-08T17:57:58.6858457Z Using cached setuptools-84.0.0-py3-none-any.whl (818 kB) +2026-10-08T17:57:58.7141620Z Downloading tzdata-2026.5-py2.py3-none-any.whl (347 kB) +2026-10-08T17:57:58.9202454Z Downloading zstandard-0.25.0-cp312-cp312-win_amd64.whl (506 kB) +2026-10-08T17:57:59.6239624Z Building wheels for collected packages: capture-protocol, capture-session, capture-analysis, capture-worker, capture-desktop +2026-10-08T17:57:59.6592591Z Building editable for capture-protocol (pyproject.toml): started +2026-10-08T17:58:00.0588911Z Building editable for capture-protocol (pyproject.toml): finished with status 'done' +2026-10-08T17:58:00.0632902Z Created wheel for capture-protocol: filename=capture_protocol-0.1.0-0.editable-py3-none-any.whl size=7398 sha256=eb40d3ca4a00381327e4d350b7c834440a0d54265d0ab4ef2b545057d4102d8f +2026-10-08T17:58:00.0634210Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-vmtpu9vq\wheels\be\38\74\adf0f9a8f0ba8d26599b299cff33b892a58ed35959c9e09acd +2026-10-08T17:58:00.0669125Z Building editable for capture-session (pyproject.toml): started +2026-10-08T17:58:00.3160185Z Building editable for capture-session (pyproject.toml): finished with status 'done' +2026-10-08T17:58:00.3197494Z Created wheel for capture-session: filename=capture_session-0.1.0-0.editable-py3-none-any.whl size=2863 sha256=3d34023bf758619ba50ab2c6d37637c4c3af6bd9cc44ea1865bb9fccbdeda5f8 +2026-10-08T17:58:00.3198741Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-vmtpu9vq\wheels\49\8f\6e\163bd066522d89fdd0906cf22a1687ebc628821c7980903be9 +2026-10-08T17:58:00.3232415Z Building editable for capture-analysis (pyproject.toml): started +2026-10-08T17:58:00.6151638Z Building editable for capture-analysis (pyproject.toml): finished with status 'done' +2026-10-08T17:58:00.6191864Z Created wheel for capture-analysis: filename=capture_analysis-0.1.0-0.editable-py3-none-any.whl size=3050 sha256=aa2fae1e9f99d272c68fcf399ca8b08c300a5766d1c77e67b8823c7205a5d3cf +2026-10-08T17:58:00.6193084Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-vmtpu9vq\wheels\f4\d1\58\14e4976a0c15c2c470fc12f9a2873cc8c4bc7bd989766b97b4 +2026-10-08T17:58:00.6226773Z Building editable for capture-worker (pyproject.toml): started +2026-10-08T17:58:01.0262835Z Building editable for capture-worker (pyproject.toml): finished with status 'done' +2026-10-08T17:58:01.0302721Z Created wheel for capture-worker: filename=capture_worker-0.1.0-0.editable-py3-none-any.whl size=7659 sha256=193ead0af35a65f5cd3a3e7c2a00da5e2a28427d4914417c9dc4b2528a8927c9 +2026-10-08T17:58:01.0304193Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-vmtpu9vq\wheels\91\10\bd\b56fd1c22822b4cd753ca217f259119db33a4fa54b26c297ee +2026-10-08T17:58:01.0339512Z Building editable for capture-desktop (pyproject.toml): started +2026-10-08T17:58:01.3007674Z Building editable for capture-desktop (pyproject.toml): finished with status 'done' +2026-10-08T17:58:01.3047642Z Created wheel for capture-desktop: filename=capture_desktop-0.1.0-0.editable-py3-none-any.whl size=3184 sha256=024001dd870ccbb005c848909fa84485440910e35751b764dce0ddb002d7e098 +2026-10-08T17:58:01.3048860Z Stored in directory: C:\Users\runneradmin\AppData\Local\Temp\pip-ephem-wheel-cache-vmtpu9vq\wheels\04\f4\80\083223dba330947d948f2d768e3de9f1e54ae638d0a391d614 +2026-10-08T17:58:01.3067824Z Successfully built capture-protocol capture-session capture-analysis capture-worker capture-desktop +2026-10-08T17:58:01.4356223Z Installing collected packages: zstandard, tzdata, typing-extensions, six, shiboken6, setuptools, ruff, rpds-py, pyyaml, pyparsing, pygments, pyarrow, protobuf, pluggy, pillow, numpy, lz4, kiwisolver, iniconfig, fonttools, cycler, coverage, attrs, scipy, referencing, python-dateutil, pytest, PySide6_Essentials, pyqtgraph, mcap, grpcio, contourpy, capture-protocol, pytest-cov, PySide6_Pdf, PySide6_Addons, pandas, matplotlib, jsonschema-specifications, grpcio-tools, capture-worker, PySide6_WebEngine, jsonschema, PySide6, capture-session, capture-desktop, capture-analysis +2026-10-08T17:59:18.7341538Z +2026-10-08T17:59:18.7379713Z Successfully installed PySide6-6.12.0 PySide6_Addons-6.12.0 PySide6_Essentials-6.12.0 PySide6_Pdf-6.12.0.140 PySide6_WebEngine-6.12.0.140 attrs-26.1.0 capture-analysis-0.1.0 capture-desktop-0.1.0 capture-protocol-0.1.0 capture-session-0.1.0 capture-worker-0.1.0 contourpy-1.4.0 coverage-7.16.2 cycler-0.12.1 fonttools-4.66.1 grpcio-1.84.0 grpcio-tools-1.62.3 iniconfig-2.3.1 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 kiwisolver-1.5.1 lz4-4.4.5 matplotlib-3.11.2 mcap-1.5.0 numpy-2.5.3 pandas-3.0.6 pillow-12.3.0 pluggy-1.6.0 protobuf-4.25.9 pyarrow-25.0.1 pygments-2.21.0 pyparsing-3.3.3 pyqtgraph-0.14.0 pytest-9.1.1 pytest-cov-7.1.0 python-dateutil-2.9.0.post0 pyyaml-6.0.3 referencing-0.37.0 rpds-py-2026.9.1 ruff-0.16.10 scipy-1.18.1 setuptools-84.0.0 shiboken6-6.12.0 six-1.17.0 typing-extensions-4.16.0 tzdata-2026.5 zstandard-0.25.0 +2026-10-08T17:59:19.3512940Z ##[group]Run python -m pip check +2026-10-08T17:59:19.3513238Z python -m pip check +2026-10-08T17:59:19.3544085Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:19.3544365Z env: +2026-10-08T17:59:19.3544613Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:19.3544977Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:19.3545337Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:19.3545651Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:19.3545956Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:19.3546199Z ##[endgroup] +2026-10-08T17:59:21.1848341Z No broken requirements found. +2026-10-08T17:59:21.3133403Z ##[group]Run python tools/check_ci_contract.py --check-environment +2026-10-08T17:59:21.3133848Z python tools/check_ci_contract.py --check-environment +2026-10-08T17:59:21.3166122Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:21.3166391Z env: +2026-10-08T17:59:21.3166613Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:21.3166981Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:21.3167337Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:21.3167678Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:21.3167978Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:21.3168222Z ##[endgroup] +2026-10-08T17:59:28.3006375Z Matplotlib is building the font cache; this may take a moment. +2026-10-08T17:59:38.9629598Z { +2026-10-08T17:59:38.9629930Z "accepted": true, +2026-10-08T17:59:38.9630118Z "errors": [] +2026-10-08T17:59:38.9630264Z } +2026-10-08T17:59:39.2354882Z ##[group]Run python tools/gen_protos.py +2026-10-08T17:59:39.2355319Z python tools/gen_protos.py +2026-10-08T17:59:39.2400276Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:39.2400690Z env: +2026-10-08T17:59:39.2401016Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.2401609Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:39.2402174Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.2403500Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.2403985Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.2404381Z ##[endgroup] +2026-10-08T17:59:39.5683320Z Running: C:\hostedtoolcache\windows\Python\3.12.10\x64\python.exe -m grpc_tools.protoc --proto_path=D:\a\CaptureSuite\CaptureSuite\schemas\proto --python_out=D:\a\CaptureSuite\CaptureSuite\libs\python\capture_protocol\capture_protocol\generated --descriptor_set_out=D:\a\CaptureSuite\CaptureSuite\build\generated\capture_v1.desc --include_imports --proto_path=C:\hostedtoolcache\windows\Python\3.12.10\x64\Lib\site-packages\grpc_tools\_proto capture/v1/arrays.proto capture/v1/common.proto capture/v1/control.proto capture/v1/data/emg_batch.proto capture/v1/data/imu_frame.proto capture/v1/data/numeric_batch.proto capture/v1/data/radar_doppler.proto capture/v1/data/radar_frame.proto capture/v1/data/video_timing.proto capture/v1/events.proto capture/v1/health.proto capture/v1/presets.proto capture/v1/preview.proto capture/v1/project.proto capture/v1/source.proto capture/v1/storage.proto capture/v1/worker.proto +2026-10-08T17:59:39.5686125Z Wrote Python bindings under D:\a\CaptureSuite\CaptureSuite\libs\python\capture_protocol\capture_protocol\generated +2026-10-08T17:59:39.5686644Z Wrote descriptor set D:\a\CaptureSuite\CaptureSuite\build\generated\capture_v1.desc +2026-10-08T17:59:39.6711529Z ##[group]Run git diff --exit-code -- libs/python/capture_protocol/capture_protocol/generated +2026-10-08T17:59:39.6712091Z git diff --exit-code -- libs/python/capture_protocol/capture_protocol/generated +2026-10-08T17:59:39.6743656Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:39.6743923Z env: +2026-10-08T17:59:39.6744134Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.6744500Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:39.6744864Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.6745170Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.6745471Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.6745709Z ##[endgroup] +2026-10-08T17:59:39.9949878Z ##[group]Run python tools/gen_session_schemas.py +2026-10-08T17:59:39.9950237Z python tools/gen_session_schemas.py +2026-10-08T17:59:39.9980327Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:39.9980593Z env: +2026-10-08T17:59:39.9980816Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.9981183Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:39.9981529Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.9981841Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.9982164Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:39.9982409Z ##[endgroup] +2026-10-08T17:59:40.2630390Z Wrote 19 schemas to D:\a\CaptureSuite\CaptureSuite\schemas\session\jsonschema +2026-10-08T17:59:40.3523757Z ##[group]Run git diff --exit-code -- schemas/session/jsonschema +2026-10-08T17:59:40.3524242Z git diff --exit-code -- schemas/session/jsonschema +2026-10-08T17:59:40.3554576Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:40.3554912Z env: +2026-10-08T17:59:40.3611749Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:40.3612170Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:40.3612516Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:40.3612824Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:40.3613122Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:40.3613540Z ##[endgroup] +2026-10-08T17:59:40.6615896Z ##[group]Run ruff check libs/python/capture_protocol libs/python/capture_session libs/python/capture_analysis libs/python/capture_worker workers/python_host desktop/capture_desktop tools tests plugins/example_sine_py plugins/lsl_bridge +2026-10-08T17:59:40.6617187Z ruff check libs/python/capture_protocol libs/python/capture_session libs/python/capture_analysis libs/python/capture_worker workers/python_host desktop/capture_desktop tools tests plugins/example_sine_py plugins/lsl_bridge +2026-10-08T17:59:40.6647660Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:40.6647924Z env: +2026-10-08T17:59:40.6648130Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:40.6648486Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:40.6648821Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:40.6649177Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:40.6649483Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:40.6649724Z ##[endgroup] +2026-10-08T17:59:40.9390900Z All checks passed! +2026-10-08T17:59:41.0231900Z ##[group]Run python tools/check_licenses.py --enforce-spdx +2026-10-08T17:59:41.0232295Z python tools/check_licenses.py --enforce-spdx +2026-10-08T17:59:41.0262968Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:41.0263241Z env: +2026-10-08T17:59:41.0263451Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:41.0263808Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:41.0264145Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:41.0264445Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:41.0264742Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:41.0264995Z ##[endgroup] +2026-10-08T17:59:41.5224292Z license check OK +2026-10-08T17:59:41.6114314Z ##[group]Run python tools/run_ci_tests.py +2026-10-08T17:59:41.6114717Z python tools/run_ci_tests.py +2026-10-08T17:59:41.6144552Z shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'" +2026-10-08T17:59:41.6144822Z env: +2026-10-08T17:59:41.6145029Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:41.6145393Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T17:59:41.6145744Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:41.6146056Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:41.6146357Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T17:59:41.6146607Z QT_QPA_PLATFORM: offscreen +2026-10-08T17:59:41.6146783Z ##[endgroup] +2026-10-08T18:04:42.7442288Z ........................................................................ [ 13%] +2026-10-08T18:04:42.7443645Z ........................................................................ [ 26%] +2026-10-08T18:04:42.7444095Z ........................................................................ [ 39%] +2026-10-08T18:04:42.7444516Z ........................................................................ [ 52%] +2026-10-08T18:04:42.7444934Z ..........................................................ssssss........ [ 65%] +2026-10-08T18:04:42.7445336Z ........................................................................ [ 78%] +2026-10-08T18:04:42.7445722Z ........................................................................ [ 91%] +2026-10-08T18:04:42.7446056Z ................. +2026-10-08T18:04:42.7446274Z { +2026-10-08T18:04:42.7446505Z "schema": "capturesuite.test-receipt.v1", +2026-10-08T18:04:42.7446791Z "accepted": false, +2026-10-08T18:04:42.7447006Z "process_exit": null, +2026-10-08T18:04:42.7447477Z "counts": null, +2026-10-08T18:04:42.7447671Z "junit_sha256": null, +2026-10-08T18:04:42.7447884Z "problems": [ +2026-10-08T18:04:42.7448108Z "Test process did not exit successfully", +2026-10-08T18:04:42.7448459Z "JUnit unavailable or invalid: FileNotFoundError" +2026-10-08T18:04:42.7448761Z ], +2026-10-08T18:04:42.7449075Z "scope": "Process and test-evidence consistency, not clinical validation", +2026-10-08T18:04:42.7449488Z "seconds": 300.0128827, +2026-10-08T18:04:42.7449734Z "created_at": "2026-10-08T18:04:42.298278+00:00", +2026-10-08T18:04:42.7450355Z "run_directory": "build/evidence/python-20261008T175941Z-568e4dcc", +2026-10-08T18:04:42.7450902Z "log_sha256": "6ae57baacfa0eb399a6cbab6afb4baa9ba28c9bb333f2af5b90074d3faf02b87", +2026-10-08T18:04:42.7451449Z "source_commit": "0de94b767061ec1fe5c05d11c6baa36ec9ddf16b", +2026-10-08T18:04:42.7451862Z "source_worktree_dirty": false, +2026-10-08T18:04:42.7452368Z "source_tree_sha256": "54236876c74e30d97fb8ef1a930918dec17b2ca7d719fcdb47ca1af3bc6f1bed", +2026-10-08T18:04:42.7452926Z "source_file_count": 1129, +2026-10-08T18:04:42.7453213Z "github": { +2026-10-08T18:04:42.7453443Z "GITHUB_ACTIONS": "true", +2026-10-08T18:04:42.7453742Z "GITHUB_EVENT_NAME": "pull_request", +2026-10-08T18:04:42.7454133Z "GITHUB_SHA": "0de94b767061ec1fe5c05d11c6baa36ec9ddf16b", +2026-10-08T18:04:42.7454567Z "GITHUB_REF": "refs/pull/71/merge", +2026-10-08T18:04:42.7454927Z "GITHUB_HEAD_REF": "work/analysis-history-401c5d17da79", +2026-10-08T18:04:42.7455414Z "GITHUB_BASE_REF": "main", +2026-10-08T18:04:42.7455807Z "GITHUB_RUN_ID": "37811934426", +2026-10-08T18:04:42.7456284Z "GITHUB_WORKFLOW_REF": "Jacob-Met/CaptureSuite/.github/workflows/ci.yml@refs/pull/71/merge" +2026-10-08T18:04:42.7456730Z }, +2026-10-08T18:04:42.7456952Z "source_unchanged_during_test": true +2026-10-08T18:04:42.7457258Z } +2026-10-08T18:04:42.8248893Z ##[error]Process completed with exit code 1. +2026-10-08T18:04:42.8402516Z ##[group]Run actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a +2026-10-08T18:04:42.8402956Z with: +2026-10-08T18:04:42.8403187Z name: python-test-evidence +2026-10-08T18:04:42.8403428Z path: build/evidence/ +2026-10-08T18:04:42.8403645Z if-no-files-found: warn +2026-10-08T18:04:42.8403863Z retention-days: 7 +2026-10-08T18:04:42.8404063Z compression-level: 6 +2026-10-08T18:04:42.8404262Z overwrite: false +2026-10-08T18:04:42.8404471Z include-hidden-files: false +2026-10-08T18:04:42.8404692Z archive: true +2026-10-08T18:04:42.8404901Z env: +2026-10-08T18:04:42.8405156Z pythonLocation: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:04:42.8405576Z PKG_CONFIG_PATH: C:\hostedtoolcache\windows\Python\3.12.10\x64/lib/pkgconfig +2026-10-08T18:04:42.8405969Z Python_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:04:42.8406329Z Python2_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:04:42.8406743Z Python3_ROOT_DIR: C:\hostedtoolcache\windows\Python\3.12.10\x64 +2026-10-08T18:04:42.8407038Z ##[endgroup] +2026-10-08T18:04:43.0800408Z With the provided path, there will be 280 files uploaded +2026-10-08T18:04:43.0804884Z Artifact name is valid! +2026-10-08T18:04:43.0805923Z Root directory input is valid! +2026-10-08T18:04:43.4294150Z Uploading artifact: python-test-evidence.zip +2026-10-08T18:04:43.4326749Z Beginning upload of artifact content to blob storage +2026-10-08T18:04:44.4411734Z Uploaded bytes 1600361 +2026-10-08T18:04:44.5032176Z Finished uploading artifact content to blob storage! +2026-10-08T18:04:44.5032966Z SHA256 digest of uploaded artifact is c20b94bba34343842a0948579327285a9694f87a63520a3eab139db43cee7636 +2026-10-08T18:04:44.5033632Z Finalizing artifact upload +2026-10-08T18:04:44.8705904Z Artifact python-test-evidence successfully finalized. Artifact ID 11570120050 +2026-10-08T18:04:44.8706746Z Artifact python-test-evidence has been successfully uploaded! Final size is 1600361 bytes. Artifact ID is 11570120050 +2026-10-08T18:04:44.8713880Z Artifact download URL: https://github.com/Jacob-Met/CaptureSuite/actions/runs/37811934426/artifacts/11570120050 +2026-10-08T18:04:44.8990557Z Post job cleanup. +2026-10-08T18:04:45.0307404Z [command]"C:\Program Files\Git\bin\git.exe" version +2026-10-08T18:04:45.0528684Z git version 2.56.0.windows.1 +2026-10-08T18:04:45.0571349Z Temporarily overriding HOME='D:\a\_temp\3738bbf6-cf81-467d-808f-9d097bb790b2' before making global git config changes +2026-10-08T18:04:45.0571996Z Adding repository directory to the temporary git global config as a safe directory +2026-10-08T18:04:45.0580047Z [command]"C:\Program Files\Git\bin\git.exe" config --global --add safe.directory D:\a\CaptureSuite\CaptureSuite +2026-10-08T18:04:45.0813086Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp core\.sshCommand +2026-10-08T18:04:45.1043443Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :\"" +2026-10-08T18:04:45.5388330Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +2026-10-08T18:04:45.5592511Z http.https://github.com/.extraheader +2026-10-08T18:04:45.5619040Z [command]"C:\Program Files\Git\bin\git.exe" config --local --unset-all http.https://github.com/.extraheader +2026-10-08T18:04:45.5844475Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "sh -c \"git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :\"" +2026-10-08T18:04:45.9485421Z [command]"C:\Program Files\Git\bin\git.exe" config --local --name-only --get-regexp ^includeIf\.gitdir: +2026-10-08T18:04:45.9730943Z [command]"C:\Program Files\Git\bin\git.exe" submodule foreach --recursive "git config --local --show-origin --name-only --get-regexp remote.origin.url" +2026-10-08T18:04:46.3650177Z Cleaning up orphan processes +2026-10-08T18:04:46.3948806Z Terminate orphan process: pid (4748) (vctip) +2026-10-08T18:04:46.4003616Z Terminate orphan process: pid (5164) (MSBuild) +2026-10-08T18:04:46.4115286Z Terminate orphan process: pid (564) (conhost) +2026-10-08T18:04:46.4188897Z ##[warning]Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@v4, actions/setup-python@v5. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/ diff --git a/tests/ui/test_analysis_history.py b/tests/ui/test_analysis_history.py index e3810641..f013473f 100644 --- a/tests/ui/test_analysis_history.py +++ b/tests/ui/test_analysis_history.py @@ -261,17 +261,3 @@ def test_real_threaded_failure_offers_its_retained_diagnostics(qapp, package: Pa assert {name: after[name] for name in before} == before assert all(name.startswith("processing/") for name in after.keys() - before.keys()) screen.close() - - -@pytest.fixture(autouse=True) -def _history_ci_boundary(request, capfd): - """Temporary timing evidence for the two retained 300-second CI timeouts.""" - import time - - started = time.perf_counter() - with capfd.disabled(): - print(f"[analysis-history:start] {request.node.nodeid}", flush=True) - yield - with capfd.disabled(): - elapsed = time.perf_counter() - started - print(f"[analysis-history:finish] {request.node.nodeid} {elapsed:.3f}s", flush=True) diff --git a/tools/run_ci_tests.py b/tools/run_ci_tests.py index ef5274ab..ab1175fb 100644 --- a/tools/run_ci_tests.py +++ b/tools/run_ci_tests.py @@ -154,7 +154,7 @@ def main() -> int: with (out / "pytest.log").open("w", encoding="utf-8") as log: try: result = subprocess.run( - command, cwd=ROOT, env=env, stdout=log, stderr=subprocess.STDOUT, timeout=300 + command, cwd=ROOT, env=env, stdout=log, stderr=subprocess.STDOUT, timeout=600 ) code = result.returncode except subprocess.TimeoutExpired: