diff --git a/- b/-
deleted file mode 100644
index 150d57a..0000000
--- a/-
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index b0ff918..a11316a 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -4,14 +4,14 @@
## How it was tested
-- [ ] `cargo check` passes
-- [ ] `cargo test` passes
-- [ ] `cargo build --release` passes
-- [ ] `tests/smoke_test.ps1` passes (with expected admin-only skips)
+- [ ] `scripts/check.ps1 -Mode Full` passes for Rust changes (or `-Mode Docs` for docs only)
+- [ ] `tests/developer_checks.ps1` passes if developer tooling changed
+- [ ] `tests/smoke_safety.ps1` passes if smoke setup or cleanup changed
+- [ ] Relevant smoke/manual checks run in an isolated environment, or skips explained
- [ ] Docs updated if behavior changed
## Checklist
-- [ ] Branch created from `dev`
-- [ ] No changes to `docs/ARCHITECTURE.md` without explicit approval
-- [ ] No changes to `docs/BUSINESS_MODEL.md` without explicit approval
+- [ ] Base branch stated; intended integration target follows CONTRIBUTING.md
+- [ ] Intentional architecture changes include rationale; unrelated drift is reported
+- [ ] Business-model changes reflect an explicit maintainer decision
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 3129fea..931ea7f 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -1,151 +1,10 @@
-# Copilot instructions
+# Copilot entrypoint
-This repository is an active Windows-only Rust application. `PLAN.md` remains the source of truth for product scope and MVP boundaries, but the repo now also contains a checked-in Cargo project, source tree, and a PowerShell smoke test script.
+Read and follow [AGENTS.md](../AGENTS.md), the shared repository instruction
+entrypoint, before editing. It links to canonical scope, architecture,
+development workflow and validation documents.
-## Read this first
-
-When you start work in this repo, read in this order:
-
-1. `README.md` for the current MVP snapshot
-2. `PLAN.md` for current boundaries and prioritized next steps
-3. `docs/ARCHITECTURE.md` for the code map
-4. `docs/WINDOWS_SHUTDOWN_LAYERS.md` for detailed shutdown-layer behavior, especially Layer 2 ETW/local-shutdown nuance and limits
-5. `CONTRIBUTING.md` for workflow and documentation expectations
-6. this file for agent-specific guardrails
-
-Also read `docs/BUSINESS_MODEL.md` before changing any README, changelog, contributor guidance, support copy, or other repo messaging that touches monetization, signed binaries, sponsorship, consulting/support, or commercialization decisions.
-
-## Architecture authority guardrail
-
-- Treat `docs/ARCHITECTURE.md` as the canonical architecture source of truth.
-- Do not "align `docs/ARCHITECTURE.md` to the code" just because implementation drift exists.
-- Only update that file to record intentional architectural changes, implementation deviations plus rationale, impossibilities discovered during implementation, or current status.
-
-## Business-model authority guardrail
-
-- Treat `docs/BUSINESS_MODEL.md` as the canonical business-model source of truth.
-- Do not invent or "normalize" sponsorship, funding, signed-binary, paid-support, consulting, or commercialization messaging from scattered repo hints.
-- Read `docs/BUSINESS_MODEL.md` before changing README, changelog, contributor guidance, release messaging, funding/support copy, or any other documentation that could imply a business decision.
-
-## How to answer "what's next?"
-
-If a user asks only **"what's next?"**, answer from repo docs instead of inventing a roadmap:
-
-1. summarize the shipped MVP from `README.md`
-2. state that the immediate priority is MVP hardening, validation, and documentation clarity from `PLAN.md`
-3. mention later-phase backlog items only as backlog, not as shipped or currently committed work
-4. stay conservative about local `shutdown.exe` handling and never promise that Wardoff stops `shutdown /t 0 /f`
-
-## Repository status and commands
-
-- The repo contains `Cargo.toml`, `src\`, and `tests\smoke_test.ps1`.
-- Preferred build / validation commands:
- - `cargo check`
- - `cargo test`
- - `cargo build --release`
-- `cargo build --release` produces `target\release\wardoff.exe`, typically around ~1.5 MiB on this branch.
-- `cargo check` and `cargo test` should pass on this branch.
-- The dedicated smoke test entry point is `powershell -ExecutionPolicy Bypass -File .\tests\smoke_test.ps1`.
-- Do not add CI workflows, release automation, or packaging work unless explicitly requested.
-
-## High-level architecture
-
-- `Wardoff` is a Windows-only Rust utility for protecting supported shutdown/reboot paths and preventing idle sleep and automatic display timeout. The intended target is `x86_64-pc-windows-msvc`.
-- The product has two control surfaces that should stay aligned:
- - a tray/background app with Block/Allow state and optional hidden mode
- - a CLI exposing `--block`, `--allow`, `--status`, `--hide`, `--log`, `--tail`, `--autostart on|off`, and `--version`, with `--status` expected to produce JSON for scripting
-- Keep the read-only CLI contract explicit: `--help`, `--version`, `--status`, and `--log --tail N` must remain non-elevating/local-or-read-only paths, while the default no-argument startup may still use the existing self-elevation path when needed.
-- Keep the IPC split explicit when documenting CLI behavior: the session-scoped `WardoffControl` pipe is the state-changing path and the session-scoped `WardoffStatus` pipe is the dedicated read-only status path.
-- Logging and observability are first-class:
- - rotating JSON lines file logs
- - shared counters and metadata such as total blocked attempts, last blocked attempt, and likely source
-- Shutdown handling is intentionally layered:
- 1. standard interactive shutdown blocking through a message-only window that handles `WM_QUERYENDSESSION`, calls `ShutdownBlockReasonCreate()`, and raises shutdown priority with `SetProcessShutdownParameters()`
- 2. local `shutdown.exe` protection is not part of the current documented MVP surface
- 3. Windows Update reboot protection by disabling the scheduled task `Microsoft\Windows\UpdateOrchestrator\Reboot` and re-checking it periodically when that task exists
- 4. remote shutdown protection via repeated `AbortSystemShutdown(NULL)` polling
-- Be explicit that Layer 3 can skip cleanly on editions such as LTSC where `\Microsoft\Windows\UpdateOrchestrator\Reboot` is absent; that is normal behavior, not a failure.
-- For detailed layer-by-layer behavior and the cautious wording around ETW/local shutdown handling, read `docs/WINDOWS_SHUTDOWN_LAYERS.md`.
-- Idle-sleep/display-timeout prevention follows Block/Allow through process-owned Power Requests. Follow `docs/ARCHITECTURE.md` and `docs/MVP_VALIDATION_MATRIX.md` for lifecycle, resume behavior and Windows limits; do not promise an explicit Sleep/Hibernate veto.
-- Autostart is handled via Task Scheduler rather than the `Run` registry key so elevated scenarios can be handled correctly.
-
-## Implemented module structure
-
-- `src/main.rs`: CLI dispatch, bootstrap, message loop, tray coordination, shutdown cleanup
-- `src/cli.rs`: clap definitions, requested-action mapping, JSON status payloads
-- `src/blocker/mod.rs`: blocker coordinator and shared power-action helpers
-- `src/blocker/shutdown.rs`: Layer 1 shutdown/sign-out handling and shutdown block reason ownership
-- `src/blocker/local.rs`: current local shutdown worker implementation; keep its user-facing documentation conservative and aligned with MVP scope decisions
-- `src/blocker/update.rs`: UpdateOrchestrator task monitoring and restore logic
-- `src/blocker/remote.rs`: Layer 4 `AbortSystemShutdownW(None)` polling loop
-- `src/blocker/sleep.rs`: owned system/display Power Requests
-- `src/blocker/abort.rs`: shared shutdown-abort privilege and result helpers
-- `src/autostart.rs`: scheduled-task autostart management
-- `src/instance.rs` and `src/ipc.rs`: single-instance ownership plus the named-pipe control and read-only status paths
-- `src/logger\`: human logging plus rotating structured JSONL logging
-- `src/tray\`: tray icon/menu surface and tray action plumbing
-- `src/windows_util.rs`: elevation checks and relaunch helpers
-- `src/config.rs`: app data and path helpers
-
-## Project-specific conventions from `PLAN.md`
-
-- Re-read `PLAN.md` before making major structural decisions. Use it as the roadmap and scope boundary document, while `README.md` stays the quickest current-state summary.
-- Preserve the distinction between MVP and later phases:
- - MVP is the safe, official-API release: standard shutdown blocking, UpdateOrchestrator handling, remote abort loop, tray basics, CLI basics, Task Scheduler autostart, idle-sleep/display-timeout prevention, and simple file logging
- - aggressive IFEO mode, Windows Event Log, profiles, timer, and toast notifications belong to later phases unless the plan is updated
-- Be explicit about elevation boundaries. Update protection and aggressive `shutdown.exe` interception are planned as admin-only features; tray, UI, and CLI flows should surface that requirement clearly rather than failing silently.
-- Prefer official Windows APIs first. Aggressive behavior is opt-in and should carry strong warnings because it may trigger EDR tooling.
-- The plan explicitly targets `Microsoft\Windows\UpdateOrchestrator\Reboot`, not the older `MusNotification` approach.
-- Do not hide platform limits. The plan is explicit that `shutdown /t 0 /f` cannot be blocked from user space; future code and docs should log that case honestly instead of claiming success.
-- Keep the project scriptable and sysadmin-friendly:
- - machine-readable CLI output for status
- - structured JSONL log data that can be queried from PowerShell or other tooling
- - Task Scheduler usage over ad-hoc startup hooks
-- Keep README/architecture/copilot guidance aligned with the documented exit-code contract in README rather than inventing new CLI result semantics.
-- UI semantics that matter in the current MVP: Block state is visually red and Allow is green.
-
-## Scope guardrails
-
-These rules apply to EVERY change in this repo. Re-read them before starting any task.
-
-### What is IN scope (MVP)
-Only these features belong in the current phase:
-- Layer 1: ShutdownBlockReasonCreate + WM_QUERYENDSESSION + SetProcessShutdownParameters
-- Layer 3: Task Scheduler UpdateOrchestrator\Reboot disable/re-check
-- Layer 4: AbortSystemShutdown polling loop
-- Idle-sleep/display-timeout prevention via Power Requests; no screensaver, lock or explicit Sleep/Hibernate veto
-- Tray icon: Block/Allow toggle, right-click menu (Block, Allow, Shutdown, Reboot, Sleep, Hibernate, Quit)
-- CLI: --block, --allow, --status (JSON output), --hide, --log, --tail, --autostart on|off, --version
-- Auto-start via Task Scheduler
-- File logging: rotating JSON lines (timestamp, event type, source, action, success/failure)
-- README.md with technical documentation
-
-### What is OUT of scope (v1.0 or later — do NOT implement)
-- IFEO aggressive mode
-- Windows Event Log integration (EventLog provider)
-- Toast notifications
-- Timer functionality
-- Profiles (Gaming, Work, Update Shield, Custom)
-- Settings window / GUI beyond tray menu
-- Winget/Scoop/Chocolatey packaging
-- CI/CD pipelines, GitHub Actions workflows
-- Release workflows, signing, packaging scripts
-- Benchmarks, performance testing infrastructure
-
-### Behavior rules for every commit
-1. **No unrequested work.** Do not add features, files, configs, or infrastructure not explicitly asked for. No CI configs. No release workflows. No architectural refactoring beyond the current task.
-2. **PLAN.md is the source of truth.** If a task contradicts PLAN.md, stop and ask. Do not silently deviate.
-3. **One branch per fix/feature when a task actually requires repo changes.** If the task is explicitly read-only or branchless, follow that instruction instead of creating a branch. Otherwise create a focused branch such as `feat/description` or `fix/description`, implement the change, then provide instructions to merge into the dev branch.
-4. **No scope creep into v1.0 features.** If a task seems to require a v1.0 feature, flag it explicitly: "This requires [feature X] which is marked as v1.0 in PLAN.md. Should I proceed?"
-5. **Document limitations honestly.** If something cannot be done (e.g., blocking `shutdown /t 0 /f`), document it in comments and README instead of implementing a hacky workaround.
-6. **Admin boundaries are explicit.** Features requiring elevation must check for admin rights and fail with a clear message, not silently degrade.
-7. **Document user-facing status conservatively.** Do not describe IFEO, ETW local shutdown interception, Windows Event Log, toasts, timers, profiles, or settings as shipped user-facing features unless the plan is updated and the task explicitly asks for that.
-8. **Test what you build.** After implementing a feature, compile it (`cargo build --release`) and verify it runs. If it requires Windows APIs that can only be tested at runtime, document what to test manually.
-
-### Code conventions
-- All public items must have `///` doc comments
-- Use `log` crate macros (info!, warn!, error!) for all operational messages
-- No `unwrap()` or `expect()` in production code paths — use proper error handling
-- Module structure must match the layout defined in this file (see Implemented module structure above)
-- Minimum Rust edition: 2021
-- Target: x86_64-pc-windows-msvc only
+Use the [task-to-code map](../docs/DEVELOPMENT.md#task-to-code-map) to load only
+relevant modules. Keep project guidance in those shared owners rather than
+duplicating it here. Preserve the Windows-only product and its human-facing
+tray and CLI behavior.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6c63998..00c58dd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,6 +10,9 @@ on:
- dev
- main
+permissions:
+ contents: read
+
env:
CARGO_TARGET_DIR: target
@@ -31,6 +34,7 @@ jobs:
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
+ components: rustfmt, clippy
- name: Cache Cargo and target
uses: actions/cache@v4
@@ -42,18 +46,31 @@ jobs:
restore-keys: |
${{ runner.os }}-${{ matrix.rust }}-cargo-
- - name: Cargo check
- run: cargo check
+ - name: Full local checks
+ shell: pwsh
+ run: .\scripts\check.ps1 -Mode Full
+
+ - name: Developer tooling tests
+ shell: pwsh
+ run: .\tests\developer_checks.ps1
- - name: Cargo test
- run: cargo test
+ - name: Smoke safety tests
+ shell: pwsh
+ run: .\tests\smoke_safety.ps1
- - name: Cargo build --release
- run: cargo build --release
+ - name: Release guard tests
+ shell: pwsh
+ run: .\tests\release_guards.ps1
- name: Smoke tests
shell: pwsh
- run: .\tests\smoke_test.ps1
+ run: |
+ $before = (Get-FileHash target/release/wardoff.exe -Algorithm SHA256).Hash
+ .\tests\smoke_test.ps1 -UseExistingBinary
+ if ($LASTEXITCODE -ne 0) { throw 'Smoke failed.' }
+ if ((Get-FileHash target/release/wardoff.exe -Algorithm SHA256).Hash -ne $before) {
+ throw 'Smoke changed the checked binary.'
+ }
- name: Upload release binary
uses: actions/upload-artifact@v4
@@ -61,3 +78,4 @@ jobs:
name: wardoff-windows-release
path: target/release/wardoff.exe
if-no-files-found: error
+ retention-days: 7
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 296e3f4..b34cfab 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,85 +1,137 @@
-name: Release
+name: Release draft
on:
push:
tags:
- - "v*"
+ - 'v*'
permissions:
- contents: write
+ contents: read
+
+concurrency:
+ group: release-${{ github.ref }}
+ cancel-in-progress: false
env:
CARGO_TARGET_DIR: target
+ RELEASE_TAG: ${{ github.ref_name }}
jobs:
- release:
+ validate:
+ if: github.repository == 'RomainROCH/Wardoff' && github.ref_type == 'tag'
runs-on: windows-latest
-
+ permissions:
+ contents: read
+ actions: read
+ outputs:
+ artifact-id: ${{ steps.artifact.outputs.artifact-id }}
+ binary-sha256: ${{ steps.binary.outputs.sha256 }}
steps:
- - name: Checkout
+ - name: Checkout exact candidate
uses: actions/checkout@v4
with:
+ ref: ${{ github.sha }}
fetch-depth: 0
- fetch-tags: true
+ persist-credentials: false
+
+ - name: Validate tag, versions, main provenance and exact CI
+ shell: pwsh
+ env:
+ GH_TOKEN: ${{ github.token }}
+ run: .\scripts\release-candidate.ps1 -Mode Validate -ContextPath "$env:RUNNER_TEMP/release-context.json"
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
- toolchain: stable
+ toolchain: stable-x86_64-pc-windows-msvc
+ components: rustfmt, clippy
- - name: Build release binary
- run: cargo build --release
+ - name: Full local checks
+ shell: pwsh
+ run: .\scripts\check.ps1 -Mode Full
- - name: Generate changelog
- id: changelog
+ - name: Developer tooling tests
shell: pwsh
- run: |
- $currentTag = "${{ github.ref_name }}"
- $previousTag = git describe --tags --abbrev=0 "$currentTag^" 2>$null
-
- if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($previousTag)) {
- $previousTag = $null
- }
-
- if ($previousTag) {
- $commitRange = "$previousTag..$currentTag"
- $changelogHeader = "## Changes since $previousTag"
- } else {
- $commitRange = $currentTag
- $changelogHeader = "## Changes"
- }
-
- $changelog = git log --oneline $commitRange
-
- if ([string]::IsNullOrWhiteSpace($changelog)) {
- $changelog = "- No changes found."
- }
-
- $releaseBody = @(
- "This is an unsigned binary built by CI. For a signed binary, see [TODO: Gumroad link]."
- ""
- $changelogHeader
- ""
- $changelog
- ) -join [Environment]::NewLine
-
- "release_body<> $env:GITHUB_OUTPUT
- $releaseBody >> $env:GITHUB_OUTPUT
- "EOF" >> $env:GITHUB_OUTPUT
-
- - name: Create GitHub Release
+ run: .\tests\developer_checks.ps1
+
+ - name: Smoke safety tests
+ shell: pwsh
+ run: .\tests\smoke_safety.ps1
+
+ - name: Release guard tests
+ shell: pwsh
+ run: .\tests\release_guards.ps1
+
+ - name: Record the built binary hash
+ id: binary
+ shell: pwsh
+ run: '"sha256=$((Get-FileHash target/release/wardoff.exe -Algorithm SHA256).Hash)" >> $env:GITHUB_OUTPUT'
+
+ - name: Smoke tests on the same binary
+ shell: pwsh
+ run: .\tests\smoke_test.ps1 -UseExistingBinary
+
+ - name: Verify and package the exact checked binary
shell: pwsh
env:
- GH_TOKEN: ${{ github.token }}
- RELEASE_BODY: ${{ steps.changelog.outputs.release_body }}
+ CHECKED_SHA256: ${{ steps.binary.outputs.sha256 }}
+ run: .\scripts\release-candidate.ps1 -Mode Package -ContextPath "$env:RUNNER_TEMP/release-context.json" -PackageDirectory "$env:RUNNER_TEMP/release-package" -ExpectedSha256 $env:CHECKED_SHA256
+
+ - name: Save immutable candidate artifact
+ id: artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: wardoff-release-candidate
+ path: ${{ runner.temp }}/release-package/*
+ if-no-files-found: error
+ retention-days: 7
+
+ draft:
+ needs: validate
+ runs-on: windows-latest
+ permissions:
+ contents: write
+ actions: read
+ steps:
+ - name: Checkout the same candidate
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.sha }}
+ fetch-depth: 0
+ persist-credentials: false
+
+ - name: Require an exact artifact ID and hash
+ shell: pwsh
+ env:
+ CHECKED_ARTIFACT_ID: ${{ needs.validate.outputs.artifact-id }}
+ CHECKED_SHA256: ${{ needs.validate.outputs.binary-sha256 }}
run: |
- gh release create "${{ github.ref_name }}" `
- --title "${{ github.ref_name }}" `
- --notes "$env:RELEASE_BODY"
+ . .\scripts\release-guard.ps1
+ Assert-ReleaseTransferInputs -ArtifactId $env:CHECKED_ARTIFACT_ID -Sha256 $env:CHECKED_SHA256
+
+ - name: Download the exact artifact from validation
+ uses: actions/download-artifact@v4
+ with:
+ artifact-ids: ${{ needs.validate.outputs.artifact-id }}
+ path: ${{ runner.temp }}/release-package
+ merge-multiple: true
- - name: Upload release asset
+ - name: Recheck and create a draft only
shell: pwsh
env:
GH_TOKEN: ${{ github.token }}
+ CHECKED_SHA256: ${{ needs.validate.outputs.binary-sha256 }}
run: |
- gh release upload "${{ github.ref_name }}" target/release/wardoff.exe --clobber
+ .\scripts\release-candidate.ps1 -Mode Validate -ContextPath "$env:RUNNER_TEMP/rechecked-context.json"
+ if ($LASTEXITCODE -ne 0) { throw 'Release preflight failed.' }
+ . .\scripts\release-guard.ps1
+ $package = "$env:RUNNER_TEMP/release-package"
+ $null = Assert-ReleaseArtifact -PackageDirectory $package -CandidateCommit $env:GITHUB_SHA -TagName $env:RELEASE_TAG -ExpectedSha256 $env:CHECKED_SHA256 -ExpectedBuildRunId ([long]$env:GITHUB_RUN_ID)
+ # --verify-tag checks existence only. Resolve again, including annotated tags.
+ $refs = @(git ls-remote --exit-code "https://github.com/$env:GITHUB_REPOSITORY.git" "refs/tags/$env:RELEASE_TAG" "refs/tags/$env:RELEASE_TAG^{}")
+ if ($LASTEXITCODE -ne 0) { throw 'Cannot recheck the remote release tag.' }
+ if ((Resolve-ReleaseTagCommit -TagName $env:RELEASE_TAG -RemoteRefs $refs) -ne $env:GITHUB_SHA) { throw 'Remote tag moved after validation.' }
+ gh release create $env:RELEASE_TAG "$package/wardoff.exe" "$package/build-info.json" "$package/SHA256SUMS.txt" --repo $env:GITHUB_REPOSITORY --verify-tag --draft --title $env:RELEASE_TAG --notes-file docs/RELEASE_NOTES_DRAFT.md
+ if ($LASTEXITCODE -ne 0) { throw 'Draft creation failed; inspect any partial draft manually.' }
+ $created = gh release view $env:RELEASE_TAG --repo $env:GITHUB_REPOSITORY --json isDraft,tagName | ConvertFrom-Json
+ if ($LASTEXITCODE -ne 0 -or $created.isDraft -ne $true -or $created.tagName -cne $env:RELEASE_TAG) { throw 'The created release was not confirmed as a draft.' }
diff --git a/.gitignore b/.gitignore
index 3e1beb3..f241620 100644
Binary files a/.gitignore and b/.gitignore differ
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..7aae43c
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,71 @@
+# Working on Wardoff
+
+Wardoff is a Windows-only Rust application for shutdown protection and idle-power
+requests. Keep the tray and CLI usable by people; agent guidance belongs in the
+development docs, not in the product interface.
+
+## Find the owner before editing
+
+Read [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow, then use the
+[task-to-code map](docs/DEVELOPMENT.md#task-to-code-map) to open only the relevant
+modules and tests. [docs/README.md](docs/README.md) indexes the rest.
+
+| Decision | Canonical source |
+| --- | --- |
+| Product scope and next work | [PLAN.md](PLAN.md) |
+| Intended architecture and intentional deviations | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) |
+| Supported commands and user-visible limits | [README.md](README.md) |
+| Validation and Windows-dependent acceptance | [docs/MVP_VALIDATION_MATRIX.md](docs/MVP_VALIDATION_MATRIX.md) |
+| Business, sponsorship, signing and paid support | [docs/BUSINESS_MODEL.md](docs/BUSINESS_MODEL.md) |
+
+Report material conflicts. Do not silently redefine architecture to match code
+drift or promote roadmap items into shipped features. Read the business-model
+document when the task touches that subject. Dated audits, benchmarks and drafts
+are evidence or working copy, not a replacement for these owners.
+
+## Build and validate
+
+Use Windows 10/11, Rust stable with the MSVC x64 toolchain, Git and PowerShell
+5.1 or newer. Run from the repository root:
+
+```powershell
+powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1
+powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1 -Mode Full
+powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1 -Mode Docs
+```
+
+Default `Fast` checks documentation, formatting, compilation and unit tests.
+`Full` also runs strict Clippy and builds the release binary. `Docs` only checks
+local documentation links and encoding. The scripts stop on failure. Cargo tests
+can launch read-only CLI commands with isolated logs; they never start the
+protection runtime. Details and focused tests live in
+[DEVELOPMENT.md](docs/DEVELOPMENT.md#validation).
+
+`tests/smoke_test.ps1` is a separate, state-changing integration suite: it runs
+Block/Allow and can change scheduled tasks. It refuses an existing runtime in
+the same session or a pre-existing Wardoff autostart task and only stops its own
+test processes.
+Use an isolated Windows test environment; see the validation matrix. A successful
+build or unit test is not evidence of actual shutdown, suspend or tray behavior.
+
+## Preserve the important boundaries
+
+- `src/main.rs` owns effects and the application loop;
+ `src/runtime_policy.rs` owns pure startup, command and tray decisions.
+- Read-only CLI actions must stay non-elevating. Keep control and status pipes
+ separate and session-scoped; preserve same-user access checks.
+- Preserve layer activation rollback, handle ownership, cleanup and wake restore.
+- Keep Layer 2 ETW wording conservative. Do not promise forced zero-second
+ shutdown blocking or an explicit Sleep/Hibernate veto.
+- Follow [CONTRIBUTING.md](CONTRIBUTING.md) for conventions and branch workflow.
+ Do not add dependencies, CI/release infrastructure or later-phase product
+ features as incidental cleanup.
+
+## Finish a change
+
+Run focused checks while iterating and `Full` for Rust changes. For docs-only
+changes use `Docs`; for developer-tooling changes also run
+`tests/developer_checks.ps1` and `tests/smoke_safety.ps1`. Record failures and
+skipped Windows/manual checks.
+Update the owning doc when its contract changes and keep links working. Do not
+duplicate this guide into harness-specific files.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3fce0e5..a0caeeb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,10 +4,23 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
+Target version: `0.2.1`. This is a local candidate, not a published release.
+
### Changed
+- Gate release tags on matching package/lock/manifest versions, main-branch provenance and successful Windows checks for the exact commit. Build and transfer the same checked binary into a draft only; publication remains manual.
+- Bound newline-terminated control IPC requests to 4096 bytes and one total second, preserving independent status availability and rejection/recovery behavior.
+- Validate autostart path access with identification tokens, and record disposable-VM idle-power acceptance without claiming physical hardware coverage.
+- Bounded `--log --tail N` to 100000 lines and made line-buffer reservation incremental and fallible, so extreme values return a readable error instead of a capacity-overflow panic.
+- Ensure the runtime unregisters callbacks and shuts down its resources even when the Windows message loop fails; preserve both errors if cleanup also fails.
+- Make the Windows smoke suite refuse existing runtime/autostart state and restrict cleanup to resources created by the test.
+- Align CI and release validation with local documentation, formatting, strict Clippy, Rust tests and PowerShell fixtures, using the existing standard Windows jobs.
- Replaced the sleep layer's periodic `SetThreadExecutionState` worker with owned system/display Power Requests and an identifiable Wardoff reason. Activation failures now reach the coordinator synchronously, and Allow/exit release the request object.
- Kept the existing tray wake-restore flow and added only a request-pair renewal to the existing resume callback when the runtime remains in Block, based on the documented termination of requests at user-initiated sleep. No additional resume state machine, display notifications or polling was introduced.
- Corrected sleep claims throughout maintained docs, CLI help and runtime logs: protection concerns idle sleep and automatic display timeout, subject to Windows policy. Explicit Sleep/Hibernate are not vetoed; Modern Standby on battery has additional limits. The original v0.1.0 hibernation claim below was too broad.
+
+## [0.2.0] - 2026-05-03
+
+### Changed
- Hardened the session-scoped `WardoffControl` and `WardoffStatus` pipes against same-session squatting by claiming first pipe instances with bounded startup retries, failing closed until both IPC servers own their initial instances, and probing the singleton before `wardoff --status` opens IPC endpoints.
- Scoped the singleton mutex plus the `WardoffControl` and `WardoffStatus` named pipes to the current Windows session so cross-session mutex or pipe squatting no longer breaks Wardoff's single-instance model across all sessions.
- Hardened structured JSONL logging under `%LOCALAPPDATA%\Wardoff\logs` so Wardoff now creates its managed log directories one component at a time, refuses reparse points in the managed log tree and rotated files, and uses reparse-aware no-follow opens for active and read-only log file access.
@@ -19,7 +32,7 @@ All notable changes to this project will be documented in this file.
- Hardened `\\.\pipe\WardoffControl` with explicit local-only security that grants the current user SID, SYSTEM, and Builtin Administrators access so the same interactive user can send `--block`/`--allow` across elevation boundaries, while remaining access-denied cases now surface a clear Wardoff message instead of raw `os error 5`.
- Clarified in README, architecture notes, and agent guidance that Layer 3 is skipped normally on editions such as LTSC when `\Microsoft\Windows\UpdateOrchestrator\Reboot` is absent.
- Aligned docs on the non-elevated read-only CLI contract, the `\\.\pipe\WardoffControl` and `\\.\pipe\WardoffStatus` split, default startup honesty, and current exit-code wording.
-- Clarified in the docs that `wardoff --status` is quick when a runtime is active but can currently take roughly 4 seconds to return `{"state":"inactive"}` when no instance is running because the client exhausts sequential status-pipe and control-pipe retry loops.
+- Clarified that `wardoff --status` returns inactive without pipe retries when the session mutex is free. Roughly four seconds of sequential pipe retries remain possible when the mutex is occupied but both IPC endpoints are unavailable.
- Refreshed the documentation truth-source and read order so new contributors and agents can identify the current MVP status, documentation entrypoints, and likely next work from the repository alone.
- Hardened Allow-mode deactivation so switching to Allow clears Block-mode behavior more cleanly.
- Tightened autostart tray-sync honesty so elevated task changes are reflected accurately in the tray menu state.
diff --git a/CLAUDE.md b/CLAUDE.md
index 403e931..6c2e6dd 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,42 +1,6 @@
-# --- CLAUDE.md pour Wardoff (racine du repo) ---
+@AGENTS.md
-# Projet
+# Claude entrypoint
-Application Rust Windows : bloqueur de shutdown en 4 couches.
-MVP tagué `v0.1.0-mvp`. Repo public, licence MIT.
-
-# Build et vérification
-
-```
-cargo build --release
-cargo test
-cargo clippy -- -D warnings
-```
-
-Exécute les trois après chaque changement. Binary cible < 2MB, zéro runtime deps.
-
-# Architecture
-
-4 couches de blocage shutdown — consulter `src/` directement.
-Architecture détaillée : @docs/ARCHITECTURE.md
-Business model : @docs/BUSINESS_MODEL.md
-
-# Tests
-
-`cargo test` couvre les tests unitaires et tourne sans privilèges.
-Les couches 3 (Update Orchestrator) et 4 (remote shutdown) ne s'arment qu'en session élevée — leur validation est manuelle.
-Procédure complète et matrice : @docs/MVP_VALIDATION_MATRIX.md
-
-# Git
-
-- Branche principale : `main`
-- Tags sémantiques : `v0.x.y`
-- Commits atomiques
-- Format Conventional Commits : `type: sujet` en minuscules. Types utilisés : `feat`, `fix`, `docs`, `chore`, `refactor`, `test`, `merge`. Sujet à l'impératif présent, sans point final.
-
-# Ne PAS faire
-
-- Pas de portabilité cross-platform — Windows only, c'est intentionnel
-- Pas de telemetry, pas de paywall, pas de tracking
-- Ne pas ajouter de dépendances sans demander
-- Ne pas utiliser `unwrap()` en production
+The shared repository instructions are in [AGENTS.md](AGENTS.md).
+Use its task routing and validation commands; maintain project guidance there.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bc7f88b..9e28362 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,114 +1,98 @@
# Contributing to Wardoff
-Thanks for contributing to Wardoff. Please also review the
-[Code of Conduct](CODE_OF_CONDUCT.md).
+Start with the [README](README.md) for the product and the
+[development guide](docs/DEVELOPMENT.md) to find code and tests for your task.
+Please follow the [Code of Conduct](CODE_OF_CONDUCT.md).
+Agents start at [AGENTS.md](AGENTS.md); humans and agents use the same workflow.
-This repository now contains a working Windows MVP runtime, but the docs should remain conservative: describe what is clearly implemented and supported, and do not turn later-phase ideas into shipped features.
+## Set up and check the project
-## Read this first
-
-If you are new to the repo, read these before making changes:
-
-1. `README.md` for the current MVP summary
-2. `PLAN.md` for scope boundaries and the current "what's next" answer
-3. `docs/ARCHITECTURE.md` for the code map
-
-## Business-model messaging guardrail
-
-If your change touches sponsor, funding, signed-binary, paid-support, consulting, or commercialization messaging, read `docs/BUSINESS_MODEL.md` first and keep the wording aligned with it. Do not invent offers or promises ad hoc.
-
-## Prerequisites
-
-For local development on Windows, use:
-
-- Windows 10 or Windows 11
-- Rust stable
-- MSVC Build Tools for the `x86_64-pc-windows-msvc` target
-- Git
-
-Administrator rights are required for some manual validation paths and some runtime features, especially Update Orchestrator task handling and autostart task changes.
-
-## Build
-
-The main build command to use and document is:
+Use Windows 10 or 11, Git, PowerShell 5.1 or newer, and Rust stable targeting
+`x86_64-pc-windows-msvc`. Install MSVC C++ build tools and a Windows SDK.
+The normal development checks do not require administrator rights.
```powershell
-cargo build --release
+powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1
```
-Useful supporting commands:
+For Rust changes, finish with the full check, including strict Clippy and the
+release build:
```powershell
-cargo fmt --check
-cargo clippy --all-targets --all-features
-cargo test
+powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1 -Mode Full
```
-## Smoke test
+The [development guide](docs/DEVELOPMENT.md#validation) lists individual commands,
+focused test filters, documentation checks and troubleshooting.
-Run the repo smoke test with:
+## Runtime validation is separate
+
+The [validation matrix](docs/MVP_VALIDATION_MATRIX.md) owns runtime acceptance.
+The smoke suite starts Block/Allow runtimes, appends logs, and can change Task
+Scheduler entries. It refuses a pre-existing runtime in the current session or
+a Wardoff autostart task, and cleans up only its own processes. Run it in an
+isolated Windows test environment where those effects are acceptable:
```powershell
-powershell -ExecutionPolicy Bypass -File tests\smoke_test.ps1
+powershell -NoProfile -ExecutionPolicy Bypass -File tests/smoke_test.ps1
```
-For the current MVP validation split between automated coverage, manual checks, admin-only checks, and VM-only checks, see [`docs/MVP_VALIDATION_MATRIX.md`](docs/MVP_VALIDATION_MATRIX.md).
-
-Use a disposable VM for disruptive shutdown, reboot, sleep, hibernate, or Task Scheduler validation.
-
-## Current implementation boundaries
-
-Keep documentation and PR descriptions aligned with the current supported MVP surface:
-
-- interactive shutdown/sign-out blocking is implemented
-- Update Orchestrator reboot-task protection is implemented
-- remote shutdown abort polling is implemented
-- idle-sleep and automatic display-timeout prevention are implemented; explicit Sleep/Hibernate remain controlled by Windows
-- tray, CLI, logging, IPC, autostart, and single-instance coordination are implemented
-
-Do **not** claim the following as implemented unless your change really adds and validates them:
-
-- IFEO interception
-- Windows Event Log integration
-- toast notifications
-- timers
-- profiles
-- settings UI
-
-Be especially careful with local `shutdown.exe` wording:
-
-- do not promise that Wardoff blocks `shutdown /t 0 /f`
-- do not turn experimental or cautiously documented behavior into a marketing claim
-
-## Branch workflow
-
-Use this workflow unless a maintainer tells you otherwise:
-
-1. branch from `dev`
-2. use a branch name such as `feat/xxx` or `fix/xxx`
-3. merge completed work back into `dev`
-4. open the PR to `main` from the appropriate integrated branch state
-
-Keep changes focused and reviewable.
-
-## Pull request checklist
-
-In each PR:
-
-- explain what changed
-- explain what you tested
-- call out any admin requirement
-- call out any behavior that is intentionally still planned rather than shipped
-- keep docs and code wording consistent
-
-## Coding and documentation conventions
-
-- keep documentation in English
-- prefer `cargo build --release` when describing the real build process
-- use fenced code blocks with language tags
-- use `rustfmt` and `clippy`
-- avoid `unwrap()` and `expect()` in production paths where failure should be surfaced cleanly
-- add `///` comments to public Rust items where appropriate
-- keep claims honest and source-verifiable
-
-Small, accurate PRs are much easier to review than broad speculative rewrites.
+Administrator rights enable additional coverage. A missing UpdateOrchestrator
+Reboot task is an expected skip on some Windows editions. Use a disposable VM
+for shutdown/reboot/sign-out and suitable test hardware or a capable VM for
+physical sleep/hibernate. Record skips and untested behavior rather than
+equating unit tests with end-to-end acceptance.
+
+## Scope and authority
+
+- [PLAN.md](PLAN.md) owns product scope and priorities.
+- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) owns intended architecture. Record
+ intentional changes with their reason; report drift instead of silently
+ rewriting the design to fit it.
+- [docs/BUSINESS_MODEL.md](docs/BUSINESS_MODEL.md) owns monetization, sponsorship,
+ signed binaries and paid support. Read it before changing related messaging.
+- [docs/WINDOWS_SHUTDOWN_LAYERS.md](docs/WINDOWS_SHUTDOWN_LAYERS.md) explains layer
+ limits. Do not promise to stop `shutdown /t 0 /f` or explicit sleep/hibernate.
+
+Keep IFEO, Event Log, toasts, timers, profiles, settings and packaging as backlog
+unless the task explicitly changes that scope. Existing CI/release workflows
+are infrastructure to maintain when requested, not evidence of a new product
+feature. Do not add CI, release automation or benchmarks as incidental cleanup.
+
+## Branches and commits
+
+Unless the task specifies a starting point, branch from `dev`, use a focused
+feature/fix branch (agents may use `codex/`), and target `dev` for
+integration. Releases reach `main` from the integrated state. Preserve existing
+work when continuing from another branch and state which base you used.
+
+Use atomic Conventional Commits: `type: imperative subject`, lowercase with no
+trailing period. Explain the change and validation; reference an issue only
+when one exists. A local change does not by itself authorize publication.
+
+## Code and documentation conventions
+
+- Keep documentation, code comments and user-visible copy in English.
+- Use Rust 2021, `rustfmt` and Clippy. Keep the Windows x64 MSVC target.
+- Handle recoverable production errors rather than using `unwrap()` or
+ `expect()`; test assertions and fail-fast build-script diagnostics differ.
+- Document public Rust items and non-obvious Win32 ownership/thread constraints.
+- Use `log` macros for operational messages and the existing structured logger
+ for events; preserve machine-readable CLI output and exit codes.
+- Preserve red Block / green Allow tray semantics, the non-elevating read-only
+ CLI, session-scoped IPC, admin boundaries and transactional cleanup.
+- Keep pure decisions separate from Windows effects when that makes the change
+ easier to test. Avoid framework layers or module splits without a concrete need.
+- Discuss new project dependencies with the maintainer. Keep protection free
+ of telemetry, tracking and paywalls.
+- Link to an existing documentation owner instead of duplicating its rules.
+ Use relative Markdown links and fenced code blocks with language tags.
+- Keep dated evidence and unpublished drafts clearly labeled. Do not turn
+ measurements from one machine into a general guarantee.
+
+## Review checklist
+
+Explain delivered behavior, affected modules, tests run and remaining
+manual/admin checks. Update relevant docs when a contract changes. Report
+architecture deviations, security implications and product limits explicitly.
+Use the [pull request template](.github/PULL_REQUEST_TEMPLATE.md) for a PR.
diff --git a/Cargo.lock b/Cargo.lock
index 17d0228..62933ef 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1446,7 +1446,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wardoff"
-version = "0.2.0"
+version = "0.2.1"
dependencies = [
"chrono",
"clap",
diff --git a/Cargo.toml b/Cargo.toml
index 38f6d15..44984c0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "wardoff"
-version = "0.2.0"
+version = "0.2.1"
edition = "2021"
authors = ["Romain ROCH"]
description = "The first modern open-source tool for taking control of Windows shutdowns."
diff --git a/PLAN.md b/PLAN.md
index 4372e0c..956324b 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -2,18 +2,17 @@
This file is the repo-level status and roadmap summary for Wardoff.
-If you are new here, read in this order:
-
-1. `README.md` for the current user-facing MVP snapshot
-2. `PLAN.md` for current status, boundaries, and likely next work
-3. `docs/ARCHITECTURE.md` for the code map
-4. `CONTRIBUTING.md` and `.github/copilot-instructions.md` for workflow and scope guardrails
+For the product, start with [README.md](README.md). For development, use
+[CONTRIBUTING.md](CONTRIBUTING.md) and the
+[task-to-code map](docs/DEVELOPMENT.md#task-to-code-map). Agents start at
+[AGENTS.md](AGENTS.md). This plan owns scope and priorities, not setup commands.
For monetization, sponsorship, signed-binary, paid-support, or broader commercialization decisions, follow `docs/BUSINESS_MODEL.md` rather than inferring policy from engineering docs.
## Current repository status
-Wardoff is currently a shipped, source-first **0.1.0-style MVP** for Windows.
+Wardoff is a source-first Windows MVP. [Cargo.toml](Cargo.toml) owns the current
+package version; the scope below describes supported behavior, not release status.
The branch already contains a working runtime plus CLI centered on one main promise: keep a machine in a visible **Block** state using conservative, documented Windows techniques where possible.
@@ -58,7 +57,7 @@ Keep improving confidence in the features that already exist:
- tighten documentation around actual runtime behavior and limits
- improve manual validation guidance for shutdown, sign-out, sleep, hibernate, remote shutdown, autostart, and elevation-sensitive paths
- fix bugs or rough edges in tray, IPC, logging, and Task Scheduler flows
-- reduce the current roughly 4-second inactive `wardoff --status` path caused by sequential IPC retry loops
+- reduce status fallback latency when the session mutex is occupied but both IPC endpoints are unavailable (up to roughly four seconds of sequential retries); the ordinary inactive path already returns without pipe retries
- keep admin versus non-admin behavior explicit
- keep LTSC-style Layer 3 skip behavior documented as normal when the UpdateOrchestrator reboot task is absent
diff --git a/README.md b/README.md
index f0db140..6452af8 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,28 @@
Wardoff is a Windows-native Rust utility for people who want a visible, scriptable way to keep a machine in a protected **Block** state during gaming sessions, overnight jobs, remote work, or maintenance windows. The project is intentionally honest about what the current MVP does today and what still belongs to later releases.
+## Measured resource usage
+
+Wardoff is lightweight while protecting a machine in the background. In our
+v0.2.0 benchmark on an Intel Core i7-6700HQ running Windows 11 IoT Enterprise
+LTSC, Block mode averaged approximately **14 MiB of resident memory** and
+**less than 0.01% total-machine CPU** across three five-minute background runs.
+CPU is normalized across all eight logical processors.
+
+| Mean process resource usage | Allow | Block |
+|---|---:|---:|
+| Resident memory / Working Set (MiB) | 12.57 | 13.95 |
+| Private committed memory (MiB) | 1.96 | 3.25 |
+| CPU (% of total machine capacity) | 0.0024% | 0.0050% |
+
+The [dated benchmark evidence](docs/benchmarks/2026-09-29-v0.2.0/README.md)
+includes the protocol, 2,700 raw samples, system information, tested binary
+hash, per-run statistics, limitations, and an integrity/reproduction checker.
+These are measurements on **one machine**, not universal guarantees. The
+UpdateOrchestrator Reboot task was absent, so its protection layer was inactive.
+Actual shutdown blocking, startup cost, heavy command workloads, battery use,
+and long-term memory growth were not tested.
+
## Current MVP status
Wardoff currently ships a working tray/runtime app plus CLI with these MVP-level capabilities:
@@ -25,16 +47,13 @@ Wardoff currently ships a working tray/runtime app plus CLI with these MVP-level
## Documentation entrypoints
-If you are brand-new to the repo, read these in order:
-
-1. **`README.md`** - current user-facing MVP snapshot
-2. **[`PLAN.md`](PLAN.md)** - current status, boundaries, and prioritized next steps
-3. **[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)** - where the runtime pieces live in code
-4. **[`docs/BUSINESS_MODEL.md`](docs/BUSINESS_MODEL.md)** - source of truth for monetization, signed binaries, sponsorship, consulting/support, and commercialization decisions
-5. **[`docs/WINDOWS_SHUTDOWN_LAYERS.md`](docs/WINDOWS_SHUTDOWN_LAYERS.md)** - detailed shutdown-layer behavior, including Layer 2 ETW/local-shutdown nuances and limits
-6. **[`docs/MVP_VALIDATION_MATRIX.md`](docs/MVP_VALIDATION_MATRIX.md)** - acceptance and validation guide covering smoke coverage, tray and Explorer-restart checks, handoff-focused spot checks, and admin-only validation
-7. **[`CONTRIBUTING.md`](CONTRIBUTING.md)** - workflow, testing, and documentation guardrails
-8. **[`.github/copilot-instructions.md`](.github/copilot-instructions.md)** - agent-specific read order and scope rules
+- **Using Wardoff:** continue with installation and usage below.
+- **Developing Wardoff:** start with [CONTRIBUTING.md](CONTRIBUTING.md), then the
+ [development guide](docs/DEVELOPMENT.md) for task-to-code routing and checks.
+- **Working as an agent:** start with [AGENTS.md](AGENTS.md); it uses the same
+ workflow and documentation as human contributors.
+- **Finding a specific topic:** use the [documentation index](docs/README.md).
+- **Choosing the next product change:** read [PLAN.md](PLAN.md).
## Not implemented yet
@@ -144,8 +163,9 @@ wardoff --version
- `wardoff --status` prints compact JSON for scripts
- `wardoff --log` prints recent structured log entries
- `wardoff --log --tail 10` prints the newest 10 structured log entries
+- `--tail` accepts 0 through 100000 lines; larger values return a readable error without allocating the requested capacity
- `wardoff --autostart on|off` enables or disables the scheduled-task autostart entry
-- `wardoff --version` prints the package version, for example `wardoff 0.1.0`
+- `wardoff --version` prints the package version as `wardoff `
- direct PowerShell invocations of `wardoff --help`, `--version`, `--status`, and `--log --tail N` now behave like normal console commands with real stdout, stderr, and exit codes
Read-only commands stay non-elevated:
@@ -154,7 +174,7 @@ Read-only commands stay non-elevated:
- `--status` reads status through the dedicated session-scoped `WardoffStatus` named pipe when a primary runtime is active
- `--log` and `--log --tail N` read the rotating JSONL log files directly
- those read-only commands stay attached to the calling shell so direct PowerShell CLI invocations can capture their output inline
-- today, `--status` can still take a few seconds to return `{"state":"inactive"}` when no primary runtime is running; when a runtime is active, the status-pipe path should return quickly
+- when no primary runtime owns the session mutex, `--status` returns `{"state":"inactive"}` without retrying the pipes; if the mutex is occupied but both IPC endpoints are unavailable, the fallback retries can still take about four seconds
State-changing/default behavior uses the normal runtime path:
diff --git a/SECURITY.md b/SECURITY.md
index 1bcdccf..14c1710 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -7,7 +7,7 @@ Wardoff is a Windows-native utility that intentionally runs elevated for some fe
| Version | Status |
| --- | --- |
| `dev` branch | Supported |
-| `v0.1.0-mvp` (latest tagged release) | Supported |
+| `v0.2.0` (latest published release) | Supported |
Older versions are not supported for security reporting.
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index 282fe05..467fab4 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -42,6 +42,22 @@ Owns application bootstrap and shutdown:
This is the best entry point for understanding the whole runtime.
+`run_with_cleanup` always executes shutdown after the message loop returns,
+including a failed `WaitMessage`. It unregisters both callbacks and clears the
+application pointer before releasing runtime resources. If the loop and shutdown
+both fail, the returned error retains both causes. This closes the former early
+return that could leave callbacks pointing at a dropped application.
+
+### `src/runtime_policy.rs` (intentional responsibility extraction)
+
+Pure decisions formerly embedded in `main.rs` live together with their unit tests:
+startup mode and tray surface, secondary CLI-to-IPC mapping, pending wake restore,
+and the autostart checkbox fallback. This makes those rules discoverable and
+testable without navigating Win32 orchestration. The runtime behavior, protocol,
+thread ownership and effectful lifecycle remain unchanged; `main.rs` still applies
+the decisions. The empty `config.rs` placeholder was removed because it owned no
+configuration behavior.
+
### `src/blocker/`
Contains the layered protection logic.
@@ -70,6 +86,10 @@ Contains the background tray thread and tray UI state management.
- file rotation
- recent-log tail reading for CLI output
+Tail requests are bounded by the [CLI contract](../README.md#usage).
+The reader grows its line buffer as it encounters records and uses fallible
+reservation, rather than allocating a caller-supplied capacity before reading.
+
### `src/ipc.rs`
Contains the named-pipe IPC transport used by secondary commands to talk to the primary runtime.
@@ -86,6 +106,7 @@ Contains Task Scheduler integration for Start with Windows behavior.
- `src/cli.rs` — argument parsing and status output
- `src/windows_util.rs` — elevation checks, relaunch, and Windows-specific helpers
+- `src/session_scope.rs` — shared Windows session ID and mutex/pipe names
- `build.rs` + `wardoff.manifest` — release-manifest embedding and requested execution level
## Core runtime object: `BlockerCoordinator`
@@ -259,7 +280,7 @@ The control pipe is now created with explicit local-only security instead of the
- a medium-integrity mandatory label allows the same interactive Windows user to send control commands to an elevated primary runtime
- if a caller still hits access denied, Wardoff maps that to a clear product message instead of returning a raw Win32 pipe error
-At the moment, the inactive `wardoff --status` path is intentionally conservative but slow: when no primary runtime is present, the client first retries the read-only status pipe and then retries the control pipe before concluding that Wardoff is inactive. Each pipe path currently uses 20 attempts with a 100 ms delay, so the fully inactive path accumulates to roughly 4 seconds before returning `{"state":"inactive"}`. This current delay comes from the sequential named-pipe retry loops, not from UAC.
+`handle_status_request` first probes the session mutex. If it can claim the primary instance, it releases that temporary claim and returns `{"state":"inactive"}` without connecting to either pipe. When the mutex is already occupied, it tries the read-only status pipe and then the control fallback. If both endpoints are unavailable, their sequential retries (20 attempts with a 100 ms delay per pipe) can still take roughly four seconds. That delay belongs to the occupied-mutex fallback, not the ordinary inactive path or UAC.
### Why the UI thread handles requests
@@ -431,7 +452,9 @@ That code exists and is wired in, but current top-level user-facing MVP docs del
## Suggested reading order for new developers
-If you are new to the codebase, read in this order:
+For a focused change, start with the
+[task-to-code map](DEVELOPMENT.md#task-to-code-map). For a full runtime walkthrough,
+read in this order:
1. `src/main.rs`
2. `src/blocker/mod.rs`
diff --git a/docs/BUSINESS_MODEL.md b/docs/BUSINESS_MODEL.md
index 27f8c5f..61b27ef 100644
--- a/docs/BUSINESS_MODEL.md
+++ b/docs/BUSINESS_MODEL.md
@@ -149,7 +149,7 @@ This section tracks when to reassess or add new monetization elements.
## What this document does NOT cover
-- Technical architecture (see `ARCHITECTURE.md`)
-- Product roadmap and feature scope (see `../PLAN.md`)
-- Community outreach strategy (see `EARLY_ADOPTER_OUTREACH_PLAN.md`)
-- Manual validation (see `MVP_VALIDATION_MATRIX.md` and `MANUAL_VALIDATION_PLAN.md`)
+- Technical architecture (see [Architecture](ARCHITECTURE.md))
+- Product roadmap and feature scope (see [Plan](../PLAN.md))
+- Community outreach copy (see the unpublished [Outreach drafts](OUTREACH_DRAFTS.md))
+- Manual validation (see [MVP validation matrix](MVP_VALIDATION_MATRIX.md))
diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md
new file mode 100644
index 0000000..5911880
--- /dev/null
+++ b/docs/DEVELOPMENT.md
@@ -0,0 +1,153 @@
+# Development guide
+
+This guide helps humans and agents make a focused change without reading the
+whole repository. [CONTRIBUTING.md](../CONTRIBUTING.md) owns workflow and coding
+conventions; [ARCHITECTURE.md](ARCHITECTURE.md) owns the design.
+
+## First working checkout
+
+Use Windows 10/11 with Rust stable, the `x86_64-pc-windows-msvc` toolchain, MSVC
+C++ build tools, a Windows SDK, Git and PowerShell 5.1+. From the repository root:
+
+```powershell
+rustc -Vv
+cargo -V
+powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1
+```
+
+The first Cargo invocation downloads locked dependencies. Keep `Cargo.lock`
+checked in; routine validation uses `--locked` so it cannot silently resolve a
+different dependency set. Cargo commands use the configured target directory.
+The default release output is `target/release/wardoff.exe`; an explicit
+`CARGO_BUILD_TARGET` adds a target-triple subdirectory.
+
+Building does not launch Wardoff. `cargo run` does: default startup can ask for
+elevation and arm protection. For runtime testing, first read the
+[validation matrix](MVP_VALIDATION_MATRIX.md).
+
+## Task-to-code map
+
+Open the owner and its tests first. Expand to the companion when the change
+crosses that boundary. Unit tests live in `#[cfg(test)]` modules beside the code.
+
+| Task | First code | Companion / acceptance |
+| --- | --- | --- |
+| CLI arguments, conflicts, JSON status | [cli.rs](../src/cli.rs) | [main.rs](../src/main.rs) dispatch; README command contract |
+| Startup mode, tray visibility, command mapping | [runtime_policy.rs](../src/runtime_policy.rs) | `run_main`, `handle_primary_runtime_request` in main |
+| Elevation, console detach, relaunch | [windows_util.rs](../src/windows_util.rs) | `prepare_default_launch`, `prepare_runtime_console_launch` in main; smoke manifest/CLI checks |
+| Mode transitions, activation rollback | [blocker/mod.rs](../src/blocker/mod.rs) | `Application::set_mode` in main; affected layer |
+| Interactive shutdown and Windows callbacks | [blocker/shutdown.rs](../src/blocker/shutdown.rs) | main callbacks; VM-only shutdown acceptance |
+| Idle-power requests, cleanup and resume | [blocker/sleep.rs](../src/blocker/sleep.rs) | runtime policy wake tests; main `handle_power_broadcast`; physical resume checks |
+| Update reboot task | [blocker/update.rs](../src/blocker/update.rs) | validation matrix admin/absent-task cases |
+| Remote abort / local ETW | [blocker/remote.rs](../src/blocker/remote.rs), [blocker/local.rs](../src/blocker/local.rs) | [abort.rs](../src/blocker/abort.rs); shutdown-layer limits |
+| Control/status transport, retries, access checks | [ipc.rs](../src/ipc.rs) | main `handle_ipc_request`; security audit residual risks |
+| Session names and singleton handoff | [session_scope.rs](../src/session_scope.rs), [instance.rs](../src/instance.rs) | main `forward_request_to_primary`; handoff acceptance |
+| Tray menu, Explorer restart, icon | [tray/mod.rs](../src/tray/mod.rs), [tray/icon.rs](../src/tray/icon.rs) | main `handle_tray_action`; manual tray checks |
+| Autostart / trusted executable path | [autostart.rs](../src/autostart.rs) | runtime policy checkbox fallback; elevated smoke checks |
+| JSONL events, rotation and tail | [logger/mod.rs](../src/logger/mod.rs) | [log_tail_cli.rs](../tests/log_tail_cli.rs) exercises real CLI with isolated log fixtures |
+| Release manifest | [build.rs](../build.rs), [wardoff.manifest](../wardoff.manifest) | release build and smoke manifest check |
+| Developer checks and docs links | [check.ps1](../scripts/check.ps1), [check-docs.ps1](../scripts/check-docs.ps1) | [developer_checks.ps1](../tests/developer_checks.ps1) |
+| Safe smoke setup and cleanup | [smoke_test.ps1](../tests/smoke_test.ps1) | [smoke_safety.ps1](../tests/smoke_safety.ps1); validation matrix |
+
+## Runtime flow and invariants
+
+`cli::parse_cli` determines intent. `main::run_main` handles read-only status/log
+before runtime bootstrap. Runtime commands claim the session mutex: a secondary
+forwards to IPC; a primary prepares elevation/console behavior and calls
+`bootstrap`, then `run`.
+
+The main application thread owns mode changes and cleanup. Pipe workers and the
+tray thread send work back to it. Preserve this ownership when changing callbacks:
+the global application pointer is only valid while `run` owns the application
+and the callbacks are registered.
+
+`runtime_policy` contains decisions without Windows effects: initial mode/tray
+surface, secondary command mapping, wake restoration and autostart checkbox
+fallback. It must not acquire handles, spawn threads, access tasks or log events.
+Effects remain in the existing runtime and subsystem owners.
+
+The two pipes have different contracts: status reads must remain available
+without elevation; control commands retain same-user/session access checks.
+The ordinary inactive status path checks the session mutex and returns without
+pipe retries. If the mutex is occupied but neither pipe responds, the sequential
+fallback can take about four seconds; that case is tracked in [PLAN.md](../PLAN.md).
+
+## Validation
+
+| Scope | Command | What it establishes |
+| --- | --- | --- |
+| Normal iteration | `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1` | Docs, formatting, compilation and unit tests |
+| Rust change ready for review | `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1 -Mode Full` | Fast checks, strict Clippy, release build |
+| Documentation only | `powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1 -Mode Docs` | Local Markdown destinations exist; valid UTF-8 without NUL bytes |
+| Developer scripts | `powershell -NoProfile -ExecutionPolicy Bypass -File tests/developer_checks.ps1` | Checker success/failure paths in temporary fixtures |
+| Smoke safety helpers | `powershell -NoProfile -ExecutionPolicy Bypass -File tests/smoke_safety.ps1` | Guard and cleanup behavior with fake processes/tasks; no runtime launched |
+| Runtime integration | `powershell -NoProfile -ExecutionPolicy Bypass -File tests/smoke_test.ps1` | State-changing Windows integration; isolated environment |
+
+The check script resolves the repository from its own location, stops at the
+first failed command and returns a nonzero exit code. It does not install tools
+or run the smoke suite. Cargo tests include brief real Windows Power Request
+acquisition/release and token checks, plus read-only CLI subprocesses with
+isolated log fixtures. They do not launch the long-lived runtime, edit scheduled
+tasks or cause a physical power transition.
+
+Individual Cargo commands, useful for focused diagnosis:
+
+```powershell
+cargo fmt --all -- --check
+cargo check --locked
+cargo test --locked
+cargo clippy --locked --all-targets --all-features -- -D warnings
+cargo build --release --locked
+```
+
+Examples of focused tests:
+
+```powershell
+cargo test --locked cli::tests
+cargo test --locked runtime_policy::tests
+cargo test --locked blocker::sleep::tests
+cargo test --locked ipc::tests
+cargo test --locked instance::tests
+cargo test --locked session_scope::tests
+cargo test --locked autostart::tests
+cargo test --locked --test log_tail_cli
+```
+
+The docs checker covers tracked and untracked, non-ignored Markdown. It checks
+local link destinations, not heading fragments, external websites or factual
+accuracy. Review those explicitly when changing them. Dated benchmark scripts
+remain separate from development checks.
+
+Both [CI](../.github/workflows/ci.yml) and the
+[release workflow](../.github/workflows/release.yml) run the same Full check,
+developer-tooling fixtures, smoke-safety fixtures and the real smoke suite on
+Windows. Full includes the brief native Power Request test and does not run the
+state-changing smoke suite. A failed required check prevents draft creation.
+
+CI retains one standard Windows job; tag releases separate read-only validation
+from a draft-only writer, with no added matrix or scheduled runs. The checked
+binary is reused by smoke without compilation. See [RELEASING.md](RELEASING.md)
+for provenance, exact-artifact gates and manual publication. Standard GitHub-hosted runners are
+[free for public repositories](https://docs.github.com/en/actions/concepts/billing-and-usage).
+CI binary artifacts expire after seven days. Reassess billing before making the
+repository private or moving to a larger or paid runner.
+
+## Common problems
+
+| Symptom | Next step |
+| --- | --- |
+| Linker or resource compiler missing | Check MSVC C++ tools and Windows SDK; use the MSVC toolchain |
+| Building from Linux/WSL fails | Build on Windows; this repository intentionally uses Windows-only APIs |
+| Release executable locked | Quit the repo-built app deliberately, or use a separate `CARGO_TARGET_DIR`; do not kill an unrelated runtime |
+| Cargo waits for its build lock | Let the owning build finish; avoid concurrent builds sharing a target directory |
+| Formatting failure | Run `cargo fmt --all`, then inspect the diff |
+| `--locked` rejects dependency resolution | Check whether the task intentionally changed Cargo.toml; update and review the lockfile only for an intended dependency change |
+| Smoke refuses an existing runtime or autostart task | Use an isolated environment with neither present; do not remove someone else's state to make the test pass |
+| Unit tests pass but tray/power behavior is uncertain | Use the specific manual row in the validation matrix and report the environment |
+
+## Keep the next change easy
+
+Update this map when an owner moves. Put a short module comment beside
+non-obvious lifecycle boundaries and test pure decisions near their owner.
+Keep measured evidence separate from intended contracts. A human should be
+able to use the same instructions and review the same evidence as an agent.
diff --git a/docs/MVP_VALIDATION_MATRIX.md b/docs/MVP_VALIDATION_MATRIX.md
index 324cbf1..3984e84 100644
--- a/docs/MVP_VALIDATION_MATRIX.md
+++ b/docs/MVP_VALIDATION_MATRIX.md
@@ -2,6 +2,15 @@
Use this as the MVP acceptance checklist for Wardoff as it exists today. It keeps automated coverage, manual spot checks, admin-only validation, and disruptive VM-only checks separate.
+For everyday development, use the [local check commands](DEVELOPMENT.md#validation).
+The smoke suite is state-changing: it starts protection, writes real logs and
+may modify scheduled tasks. It refuses a runtime already present in the current
+session or a pre-existing Wardoff autostart task, and only stops processes it
+started. Use an isolated Windows test environment even when not requesting a
+shutdown or suspend; preflight checks cannot prevent concurrent external changes.
+Run [smoke_safety.ps1](../tests/smoke_safety.ps1) to check those guards with fakes
+without changing the live session.
+
## Scope and honesty rules
This matrix covers only the current MVP surface:
@@ -27,7 +36,7 @@ Keep validation language conservative:
| Area | Notes |
| --- | --- |
| OS | Windows 10 or Windows 11 |
-| Build target | `cargo build --release` then validate `target\release\wardoff.exe` |
+| Build target | `cargo build --release --locked` then validate `target\release\wardoff.exe` |
| Logs | `%LOCALAPPDATA%\Wardoff\logs\wardoff.jsonl` |
| Admin rights | Required for Layer 3, Layer 4, Update Orchestrator task checks, and autostart task changes |
| Trusted install path | Required if you expect `wardoff --autostart on` to create or update the `Wardoff` task; from an untrusted or user-writable path Wardoff should refuse safely and leave the scheduled-task state unchanged |
@@ -37,7 +46,7 @@ Keep validation language conservative:
| Check | What the script proves today | Admin needed |
| --- | --- | --- |
-| Release build | `cargo build --release` succeeds | No |
+| Release build | `cargo build --release --locked` succeeds | No |
| Release artifact | `target\release\wardoff.exe` exists | No |
| CLI help | `wardoff --help` exits `0` and mentions `wardoff` | No |
| CLI version | `wardoff --version` exits `0` and prints the package version | No |
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..b76de45
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,44 @@
+# Documentation
+
+Choose the page for your task. There is no need to read every document before a
+small change.
+
+## Start here
+
+| Need | Read |
+| --- | --- |
+| Install and use Wardoff | [Project README](../README.md) |
+| Set up a development environment | [Contributing](../CONTRIBUTING.md) |
+| Find code, tests and common pitfalls | [Development guide](DEVELOPMENT.md) |
+| Start an agent session | [Agent entrypoint](../AGENTS.md) |
+| Understand current scope and priorities | [Plan](../PLAN.md) |
+
+## Maintained contracts
+
+| Topic | Owner |
+| --- | --- |
+| Architecture, threads and resource lifecycle | [Architecture](ARCHITECTURE.md) |
+| Shutdown layers and Windows limits | [Shutdown layers](WINDOWS_SHUTDOWN_LAYERS.md) |
+| Automated and manual acceptance | [Validation matrix](MVP_VALIDATION_MATRIX.md) |
+| Why aggressive interception is excluded | [IFEO warning](IFEO_WARNING.md) |
+| Sponsorship, signed binaries and paid support | [Business model](BUSINESS_MODEL.md) |
+| Reporting security issues | [Security policy](../SECURITY.md) |
+| Questions and support | [Support](../SUPPORT.md) |
+| Released changes | [Changelog](../CHANGELOG.md) |
+| Release validation, drafts and manual publication | [Releasing](RELEASING.md) |
+
+## Evidence, comparisons and drafts
+
+These pages have their own date, scope or draft status. Re-check findings against
+the code you are changing; they do not redefine product or architecture contracts.
+
+- [Security audit](SECURITY_AUDIT.md): findings and residual risks at the audited state.
+- [Resource benchmark](benchmarks/2026-09-29-v0.2.0/README.md): protocol, raw data,
+ limitations and reproduction tools for one machine and binary.
+- [Product comparison](COMPARISON.md): comparative background.
+- [Release notes draft](RELEASE_NOTES_DRAFT.md): unpublished release copy.
+- [Outreach drafts](OUTREACH_DRAFTS.md): unpublished community messages.
+
+Keep each rule in its owning document and update links when moving a page.
+Claude and Copilot entrypoints route to the same agent guide; they are not
+independent copies of project policy.
diff --git a/docs/RELEASE_NOTES_DRAFT.md b/docs/RELEASE_NOTES_DRAFT.md
index 46e9ee3..f59c89d 100644
--- a/docs/RELEASE_NOTES_DRAFT.md
+++ b/docs/RELEASE_NOTES_DRAFT.md
@@ -1,44 +1,41 @@
-# Wardoff v0.2.0 (draft, unreleased)
-
-> Draft only — this version has not shipped yet.
-
-## What's new since v0.1.0-mvp
-
-### Fixed
-- Fixed non-elevated CLI launch paths so read-only commands behave like normal PowerShell and console commands, with more honest exit codes and status output.
-- Fixed status and control IPC edge cases across elevation boundaries, including same-user control-pipe access, mutex access-denied handling, and inactive/handoff reporting.
-- Fixed tray/runtime rough edges around delayed startup, secondary handoff recovery, wake-capable tray actions, allow-mode teardown, and recovery-failure reporting.
-- Fixed autostart tray sync wording so admin-only behavior is reported honestly.
-- Fixed Block mode not restoring after tray-initiated sleep/hibernate wake.
-- Resolved the five original pre-release security blockers: writable-path autostart, log-directory symlink abuse, named-pipe squatting, cross-session mutex exposure, and WM_ENDSESSION spoofing. Same-session mutex hardening remains local follow-up work.
-
-### Improved
-- Added best-effort internal Layer 2 local `shutdown.exe` detection and abort handling in Block mode, while keeping it out of headline MVP claims and documenting the limits conservatively.
-- Improved Windows launch UX so long-lived runtime launches detach more cleanly from shell sessions and background startup behaves more predictably.
-- Hardened the release manifest and non-elevating read-only CLI dispatch to reduce privilege surprises and keep read-only flows safer.
-- Tightened smoke and validation coverage for read-only CLI paths and process cleanup timing.
-- Added internal security audit (docs/SECURITY_AUDIT.md).
-- Console window no longer flashes on startup.
-
-### Documentation
-- Added GitHub issue forms for bug reports, compatibility reports, documentation issues, and feature requests.
-- Added `docs/MVP_VALIDATION_MATRIX.md` and expanded manual validation guidance for tray behavior, Explorer restart recovery, handoff cases, and admin-only paths.
-- Refreshed README, contributing guidance, shutdown-layer docs, CLI exit-code docs, and repo guidance to better reflect the current conservative MVP surface.
-- Cleaned up repo documentation links and removed the old session-tracker status file.
-
-## Known limits
-- Layer 3 (UpdateOrchestrator) is automatically skipped on LTSC editions that lack the `UpdateOrchestrator\Reboot` scheduled task. This is normal.
-- Idle-power requests support S3 and Modern Standby, subject to Windows power policy. Explicit Sleep/Hibernate, lid and power-button actions are not vetoed. Hardware sleep behavior must be tested on a capable machine; VM request visibility alone is not proof.
-- `shutdown /t 0 /f` is not guaranteed blockable. This is a Windows limitation, not a Wardoff bug.
-- The product is source-first: no installer, no package manager distribution yet
-
-## How to test
-- Clone the repo and run `cargo build --release`
-- Binary: `target\release\wardoff.exe`
-- Requires Windows 10 or later
-- Some features require admin rights (layers 2-4, autostart)
-
-## How to report issues
-- Bugs: use the bug report issue form
-- Compatibility: use the compatibility report form
-- Questions and feedback: use GitHub Discussions
+# Wardoff v0.2.1 (draft, unreleased)
+
+This candidate has not been published. The tag workflow prepares a draft only
+after validation; a maintainer must review and publish it separately.
+
+## Changes since v0.2.0
+
+- Bound each newline-terminated control request to 4096 wire bytes and one total
+ second. Malformed, oversized, incomplete and disconnected clients cannot hold
+ the control reader indefinitely; status remains independently available.
+- Use process-owned system/display Power Requests for idle-power protection.
+ Report activation errors synchronously, release on Allow/exit, and renew after
+ the existing resume notification. Explicit Sleep/Hibernate are not vetoed.
+- Fix autostart access checks to use identification tokens. Keep the existing
+ trusted-path and same-user/elevation boundaries.
+- Reject excessive log-tail requests with a readable error and bound allocation.
+ Clean up runtime resources when the Windows message loop fails.
+- Isolate Windows smoke cleanup, consolidate developer instructions and checks,
+ and validate release provenance, versions and the exact binary before creating
+ a draft. No automatic public release or signing is added.
+
+## Validation and limits
+
+The draft includes `build-info.json` and `SHA256SUMS.txt` for its exact unsigned
+MSVC binary and the Windows workflow run. Review the run and its explicit smoke
+skips before publishing. A green run on another commit is not release evidence.
+
+- Disposable-VM idle-power results are recorded in
+ [IDLE_POWER_VALIDATION.md](IDLE_POWER_VALIDATION.md); physical S3/monitor,
+ Hibernate and Modern Standby acceptance remains incomplete.
+- Missing UpdateOrchestrator Reboot tasks and unavailable interactive linked
+ tokens cause documented smoke skips, not successful coverage of those paths.
+- Same-session mutex denial of service, the status pipe DACL and other residual
+ local hardening debt remain documented in [SECURITY_AUDIT.md](SECURITY_AUDIT.md).
+- Forced zero-second shutdown and explicit power actions are not guaranteed
+ blockable. This remains a source-first utility for self-administered machines.
+- Official signed downloads and paid support are not available. The source
+ remains MIT and support remains community-only.
+
+The resource benchmark retained in the repository covers its dated v0.2.0
+artifact; it has not been rerun or requalified for this candidate.
diff --git a/docs/RELEASING.md b/docs/RELEASING.md
new file mode 100644
index 0000000..e862306
--- /dev/null
+++ b/docs/RELEASING.md
@@ -0,0 +1,121 @@
+# Releasing Wardoff
+
+The supported flow is **tag -> Windows validation -> exact binary -> draft ->
+manual publication**. A tag does not authorize an automatic public release.
+The current `0.2.1` source version is provisional; no matching release is shipped.
+
+## Why drafts rather than automatic publication
+
+Automatic builds and draft preparation remove repetitive packaging work. Keep
+publication manual for this small source-first project: binaries are unsigned,
+some interactive UAC cases are skipped on hosted runners, and physical S3,
+Hibernate and Modern Standby acceptance is incomplete. A maintainer must review
+the actual evidence and wording before making a binary available publicly.
+
+Fully manual packaging would avoid automation but make source/asset mismatches
+easier. Fully automatic public releases would give a green job more authority
+than the evidence supports. The draft flow preserves automation's useful part
+without adding certificates, services, secrets, paid runners or commercial claims.
+See [BUSINESS_MODEL.md](BUSINESS_MODEL.md) and [SUPPORT.md](../SUPPORT.md).
+
+## Before requesting a tag
+
+1. Integrate the reviewed candidate through `dev` into `main`. Keep other agents'
+ worktrees and unique branches intact.
+2. Choose a stable `vX.Y.Z` with no leading zeroes, prerelease or build suffix.
+ Match `[package]` in Cargo.toml, the `wardoff` entry in Cargo.lock and manifest
+ assembly version `X.Y.Z.0`; keep `asInvoker` and `uiAccess=false`.
+3. Update [CHANGELOG.md](../CHANGELOG.md) and
+ [RELEASE_NOTES_DRAFT.md](RELEASE_NOTES_DRAFT.md) from the previous published tag.
+ Keep dated benchmark and VM evidence bound to their original binary.
+4. Wait for the exact commit's latest **push/main** CI run and its Windows steps
+ to succeed. A PR run, another branch/SHA, a newer failed rerun, missing evidence
+ or a skipped required step cannot satisfy the gate. Do not filter failed runs
+ away or add `continue-on-error` to make publication proceed.
+5. Obtain authorization for the actual integration/push/tag and its draft effect.
+ Local preparation and local success do not authorize those external actions.
+
+The tag's commit must be reachable from current remote `main`; it need not be
+the tip. The remote tag must still peel to the checked-out commit, including an
+annotated tag. Git/API errors fail closed. If CI is pending, rerun the tag workflow
+only after it succeeds; there is no bypass or polling service.
+
+## What the workflow does
+
+[release.yml](../.github/workflows/release.yml) uses two standard Windows jobs.
+The release API driver supports Windows PowerShell 5.1 and PowerShell 7.5+;
+PowerShell 6 through 7.4 are not supported by that driver and fail closed on
+converted timestamps. The newer host uses `ConvertFrom-Json -DateKind String`
+to preserve the UTC evidence, as described in the
+[PowerShell reference](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/convertfrom-json#-datekind).
+The validation job has only `contents: read` and `actions: read`. It validates
+provenance and versions, runs Full checks, developer fixtures, smoke safety and
+release guards, then the state-changing Windows smoke in the disposable hosted
+runner. Native Power Request tests are not excluded there. Full builds with
+`--locked`; smoke uses `-UseExistingBinary` and cannot compile a replacement.
+
+The hash is taken before smoke and must match afterward. Package checks verify
+help/version, the real embedded manifest resource, Windows file version and MSVC
+host. They copy that binary without rebuilding it and produce:
+
+The Windows version check reads the fixed four-component PE version resource;
+its display string can omit the trailing `.0` without changing that resource.
+
+- `wardoff.exe`: the exact unsigned checked binary;
+- `SHA256SUMS.txt`: its SHA-256;
+- `build-info.json`: tag, full source SHA, main CI run/attempt, build run URL,
+ Rust version/target, hash, unsigned status, tests and known limits.
+
+The draft job depends on successful validation. Only this job receives
+`contents: write`, with `actions: read` for evidence. It downloads the immutable
+artifact ID emitted by validation, verifies the binary hash and metadata, and
+rechecks provenance and CI. It then resolves the remote tag again immediately
+before `gh release create --verify-tag --draft`. `--verify-tag` alone proves only
+existence, as documented in the [GitHub CLI manual](https://cli.github.com/manual/gh_release_create).
+
+Any existing release **or draft** for the tag blocks creation. There is no asset
+clobber, automatic draft edit or publication command. After a failed upload,
+inspect a partial draft manually; rerunning will refuse to overwrite it. The
+write-job check matters because read-only API responses can omit drafts.
+
+## Review before manual publication
+
+Verify the draft tag still identifies the recorded SHA, download the actual
+assets and check their hash, inspect the exact run's tests and explicit smoke
+skips, and ensure the release notes match its scope. Keep hardware/UAC and local
+security debt visible. Successful VM/request checks do not establish universal
+power behavior; see [IDLE_POWER_VALIDATION.md](IDLE_POWER_VALIDATION.md),
+[MVP_VALIDATION_MATRIX.md](MVP_VALIDATION_MATRIX.md) and
+[SECURITY_AUDIT.md](SECURITY_AUDIT.md). Publication requires separate authorization.
+
+## Limits of repository-only guards
+
+These guards apply to the workflow committed at the new tag. An older tag can
+carry an older workflow, and a maintainer able to change workflows can remove
+checks. Repository scripts are not a security boundary against that maintainer.
+External tag rules/permissions could address that separately, but no account or
+branch/tag protection settings are changed by this work.
+
+There is a small race between the final remote-tag read and draft creation;
+manual review must check the tag again before publication. Drafts remain editable
+on GitHub. Neither SHA-256 nor these checks is an Authenticode signature or an
+attestation service. Do not add a PAT or broader permission to bypass a denied
+release creation; inspect the integration and GitHub error instead.
+
+## Local verification without system effects
+
+```powershell
+powershell -NoProfile -ExecutionPolicy Bypass -File scripts/check.ps1 -Mode Docs
+powershell -NoProfile -ExecutionPolicy Bypass -File tests/developer_checks.ps1
+powershell -NoProfile -ExecutionPolicy Bypass -File tests/smoke_safety.ps1
+powershell -NoProfile -ExecutionPolicy Bypass -File tests/release_guards.ps1
+```
+
+These fixture suites use fake metadata/processes and owned temporary files, not
+network mutation or the protection runtime. `Fast`/`Full` also execute a real
+Power Request test; the full smoke starts Block/Allow and can edit tasks. When
+those effects are not authorized locally, run individual Cargo checks and
+explicitly exclude only
+`blocker::sleep::tests::activation_reports_an_acquired_request_before_returning`.
+Record that exclusion as NOT RUN. It does not replace the complete hosted checks
+required for a draft. Local fixture success is not hosted workflow acceptance.
diff --git a/docs/SECURITY_AUDIT.md b/docs/SECURITY_AUDIT.md
index f6656b9..0048553 100644
--- a/docs/SECURITY_AUDIT.md
+++ b/docs/SECURITY_AUDIT.md
@@ -7,7 +7,7 @@
## Summary
-Wardoff is materially safer than it was at the previous audit point and is acceptable for distribution to source-first technical early adopters on self-administered machines, but it is still **not yet hardened** for a hostile local-attacker model or multi-user deployment scenarios. The five original pre-release blockers around writable-path autostart, log-directory symlink abuse, named-pipe squatting, cross-session mutex scope, and spoofed `WM_ENDSESSION` teardown are resolved in the current `dev` state. The remaining concerns are same-session/local hardening debt: residual log file targeting, same-session mutex denial of service, the status pipe's default DACL, and the control pipe's unbounded single-client request read path.
+Wardoff is materially safer than it was at the previous audit point and is acceptable for distribution to source-first technical early adopters on self-administered machines, but it is still **not yet hardened** for a hostile local-attacker model or multi-user deployment scenarios. The five original pre-release blockers around writable-path autostart, log-directory symlink abuse, named-pipe squatting, cross-session mutex scope, and spoofed `WM_ENDSESSION` teardown are resolved in the current `dev` state. The remaining concerns are same-session/local hardening debt: residual log file targeting, same-session mutex denial of service, and the status pipe's default DACL. The follow-up below records the bounded control-request reader.
## Findings
@@ -91,15 +91,16 @@ Wardoff is materially safer than it was at the previous audit point and is accep
- **Fix status:** **still open**
- **Recommended fix:** Apply an explicit reviewed security descriptor to the status pipe as well.
-### [MEDIUM] Control pipe request handling still allows single-client read denial of service
+### [INFORMATIONAL] Fixed: control pipe request reads are bounded
-- **Location:** `src/ipc.rs:430-537`, `src/ipc.rs:899-914`
+- **Location:** `src/ipc.rs` (`read_request`, `read_request_until_deadline`), `tests/ipc_request_limits.rs`
- **Attack surface:** Named pipe security
-- **Description:** The control server still accepts one client at a time and blocks on `BufRead::read_line` with no explicit size cap or read timeout. A client that connects and never finishes a line can still stall command processing.
-- **Exploitability:** Any local client that can connect to the control pipe can deny service to other control requests for the duration of that stalled read.
-- **Risk for early-adopter release:** **fix before broader distribution**
-- **Fix status:** **still open**
-- **Recommended fix:** Add request-size caps plus read timeouts or a more defensive multi-client/overlapped handling model.
+- **Description:** The original single-client server blocked on an unbounded `BufRead::read_line`. The 2026-10-04 follow-up limits each control frame to 4096 wire bytes including its required newline and applies a one-second total read deadline. Nonblocking Win32 byte reads distinguish temporary lack of data from EOF; incoming fragments do not renew the deadline. Rejected connections retain nonblocking writes so a client refusing its error reply cannot stall the next accept.
+- **Exploitability:** One incomplete client can occupy the serial reader only until its deadline, rather than indefinitely. Repeated connections and existing UI/valid-response waits remain outside this targeted fix; this is not a general hostile-client or multi-user hardening claim.
+- **Risk for early-adopter release:** **informational for the original unbounded-read finding**
+- **Fix status:** **resolved in source**
+- **Validation:** An isolated test runs the production control/status loops on process-unique endpoints with an inert UI consumer. It covers valid and malformed JSON, empty input, UTF-8 errors, size boundaries and fragmented oversized input, missing newline, silent and trickling clients, disconnect/recovery, independent status response before the control deadline, and orderly shutdown while a client is incomplete. No power protections or autostart changes are required. Run `cargo test --test ipc_request_limits -- --nocapture`.
+- **Recommended follow-up:** Retain this regression test and validate supported Windows environments before broader distribution. The same-user/elevation policy and status-pipe ACL are unchanged.
### [MEDIUM] Scheduled-task ACL hardening is still not explicit
@@ -154,4 +155,4 @@ Additional notes:
## Conclusion
-Wardoff is acceptable for distribution to source-first technical early adopters on self-administered machines. The five original pre-release blockers (writable-path autostart, log-directory symlink abuse, named-pipe squatting, cross-session mutex, WM_ENDSESSION spoofing) are resolved. Known remaining items (same-session mutex DoS, status pipe default DACL, control pipe unbounded read, residual log file targeting) are local hardening debt against same-session adversaries, not exploitable privilege escalation. Wardoff is not yet hardened against a hostile local-attacker model or multi-user deployment scenarios.
+Wardoff is acceptable for distribution to source-first technical early adopters on self-administered machines. The five original pre-release blockers (writable-path autostart, log-directory symlink abuse, named-pipe squatting, cross-session mutex, WM_ENDSESSION spoofing) are resolved, and the follow-up bounds the control-request read. Known remaining items (same-session mutex DoS, status pipe default DACL, residual log file targeting) are local hardening debt against same-session adversaries, not exploitable privilege escalation. Wardoff is not yet hardened against a hostile local-attacker model or multi-user deployment scenarios.
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/.gitattributes b/docs/benchmarks/2026-09-29-v0.2.0/.gitattributes
new file mode 100644
index 0000000..c4b3d3a
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/.gitattributes
@@ -0,0 +1,2 @@
+# Preserve evidence bytes and checksums on every checkout, including Windows.
+* -text whitespace=blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/Measure-Wardoff.ps1 b/docs/benchmarks/2026-09-29-v0.2.0/Measure-Wardoff.ps1
new file mode 100644
index 0000000..4d333c7
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/Measure-Wardoff.ps1
@@ -0,0 +1,97 @@
+param([int]$Seconds=300,[int]$Warmup=30,[int]$Repeats=3,[string]$OutputName='results')
+$ErrorActionPreference='Stop'
+[Threading.Thread]::CurrentThread.CurrentCulture=[Globalization.CultureInfo]::InvariantCulture
+$out=Join-Path $PSScriptRoot $OutputName
+New-Item -ItemType Directory -Force $out | Out-Null
+$exe=Join-Path $PSScriptRoot 'wardoff.exe'
+$expected='96D1700C492B1689E6CB3A18847481EB9A203E30DB4D4BA273D4B458ED6A84BC'
+if((Get-FileHash $exe).Hash -ne $expected){throw 'Executable hash mismatch'}
+if(Get-Process wardoff -ErrorAction SilentlyContinue){throw 'Existing Wardoff process: preserve it and stop.'}
+Add-Type @'
+using System;
+using System.Runtime.InteropServices;
+public static class BenchNative {
+ [DllImport("kernel32.dll",SetLastError=true)] public static extern bool GetSystemTimes(out ulong idle,out ulong kernel,out ulong user);
+ [DllImport("user32.dll",SetLastError=true)] public static extern bool PostThreadMessage(uint thread,uint msg,UIntPtr w,IntPtr l);
+ [DllImport("kernel32.dll",SetLastError=true)] public static extern bool GetProcessIoCounters(IntPtr h,out IO v);
+ [DllImport("kernel32.dll")] public static extern uint SetThreadExecutionState(uint flags);
+ [StructLayout(LayoutKind.Sequential)] public struct IO {public ulong ReadOps,WriteOps,OtherOps,ReadBytes,WriteBytes,OtherBytes;}
+ public static ulong[] Times(){ulong i,k,u;if(!GetSystemTimes(out i,out k,out u))throw new Exception("GetSystemTimes failed");return new ulong[]{i,k,u};}
+ public static IO Counters(IntPtr h){IO v;if(!GetProcessIoCounters(h,out v))throw new Exception("GetProcessIoCounters failed");return v;}
+}
+'@
+function Save-Json($value,$path){$value | ConvertTo-Json -Depth 10 | Set-Content -Encoding UTF8 $path}
+function Status { $text= & $exe --status; if($LASTEXITCODE -ne 0){throw 'Status failed'}; return ($text | ConvertFrom-Json) }
+function Stop-Owned($p){
+ if($null -eq $p){return}; $p.Refresh(); if($p.HasExited){throw 'Runtime exited unexpectedly'}
+ $main=$p.Threads | Sort-Object StartTime | Select-Object -First 1
+ if(-not [BenchNative]::PostThreadMessage([uint32]$main.Id,0x12,[UIntPtr]::Zero,[IntPtr]::Zero)){throw 'WM_QUIT failed'}
+ if(-not $p.WaitForExit(20000)){throw 'Graceful exit timed out; process preserved'}
+ if(Get-Process wardoff -ErrorAction SilentlyContinue){throw 'Unexpected surviving Wardoff process'}
+}
+$owned=$null
+try {
+ $admin=[Security.Principal.WindowsPrincipal]::new([Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
+ $cpu=Get-CimInstance Win32_Processor
+ $os=Get-CimInstance Win32_OperatingSystem
+ $logical=($cpu | Measure-Object NumberOfLogicalProcessors -Sum).Sum
+ $meta=[ordered]@{startedUtc=[DateTime]::UtcNow.ToString('o');seconds=$Seconds;warmupSeconds=$Warmup;repeats=$Repeats;admin=$admin;cpu=@($cpu | Select-Object Name,NumberOfCores,NumberOfLogicalProcessors);os=($os | Select-Object Caption,Version,BuildNumber,TotalVisibleMemorySize);logicalProcessors=$logical;powerPlan=(powercfg /getactivescheme | Out-String).Trim();binarySha256=$expected;version='0.2.0';releaseTag='v0.2.0';releaseCommit='9f6c0375c851d0a5b933da0bd69bafc75b215cf5';mainCommit='aa40e8982273fa66b86b806ec1424a547affdbd3';cpuDefinition='100 * process CPU seconds / actual elapsed seconds / logical processors';ramUnit='MiB = 1048576 bytes';ioDefinition='Process I/O includes file/device/network operations, not physical disk traffic';p95Definition='nearest rank';collectorPid=$PID}
+ Save-Json $meta (Join-Path $out 'metadata.json')
+ # Keep system awake equally in every condition; no change to display or power plan.
+ [void][BenchNative]::SetThreadExecutionState([uint32]2147483649)
+ $orders=@(@('baseline','allow','block'),@('allow','block','baseline'),@('block','baseline','allow'))
+ $collector=Get-Process -Id $PID
+ for($r=1;$r -le $Repeats;$r++){
+ foreach($scenario in $orders[($r-1)%3]){
+ $label="run-$r-$scenario"
+ "$(Get-Date -Format o) START $label" | Add-Content (Join-Path $out 'progress.log')
+ if($scenario -ne 'baseline'){
+ Start-Process -FilePath $exe -ArgumentList '--allow' -WindowStyle Hidden
+ Start-Sleep -Seconds 3
+ $ps=@(Get-Process wardoff -ErrorAction SilentlyContinue)
+ if($ps.Count -ne 1){throw 'Expected exactly one runtime'}
+ $owned=$ps[0]
+ if($owned.Path -ne $exe){throw 'Unexpected executable path'}
+ if($scenario -eq 'block'){ & $exe --block | Out-Null; if($LASTEXITCODE -ne 0){throw 'Block command failed'} }
+ }
+ Start-Sleep -Seconds $Warmup
+ if($owned){$s=Status; if($s.state -ne $scenario){throw 'Wrong runtime state'}; Save-Json $s (Join-Path $out "$label-start.json")}
+ elseif(Get-Process wardoff -ErrorAction SilentlyContinue){throw 'Baseline contaminated'}
+ $rows=[Collections.Generic.List[object]]::new()
+ $watch=[Diagnostics.Stopwatch]::StartNew()
+ $lastT=$watch.Elapsed.TotalSeconds; $lastSys=[BenchNative]::Times()
+ $collector.Refresh(); $lastCollector=$collector.TotalProcessorTime.TotalSeconds
+ $lastCpu=0.; $lastIo=$null
+ if($owned){$owned.Refresh();$lastCpu=$owned.TotalProcessorTime.TotalSeconds;$lastIo=[BenchNative]::Counters($owned.Handle)}
+ for($i=1;$i -le $Seconds;$i++){
+ $wait=1000*($i-$watch.Elapsed.TotalSeconds); if($wait -gt 0){Start-Sleep -Milliseconds ([int]$wait)}
+ $now=$watch.Elapsed.TotalSeconds;$dt=$now-$lastT;$sys=[BenchNative]::Times()
+ $total=($sys[1]-$lastSys[1])+($sys[2]-$lastSys[2]);$idle=$sys[0]-$lastSys[0]
+ $collector.Refresh();$cc=$collector.TotalProcessorTime.TotalSeconds
+ $row=[ordered]@{run=$r;scenario=$scenario;sample=$i;utc=[DateTime]::UtcNow.ToString('o');elapsed_s=$now;interval_s=$dt;system_cpu_pct=100*($total-$idle)/$total;collector_cpu_pct=100*($cc-$lastCollector)/$dt/$logical;pid='';process_cpu_s='';cpu_pct='';private_mib='';working_set_mib='';threads='';handles='';io_read_bytes_s='';io_write_bytes_s=''}
+ if($owned){
+ $owned.Refresh();if($owned.HasExited){throw 'Runtime died during measurement'}
+ $pc=$owned.TotalProcessorTime.TotalSeconds;$io=[BenchNative]::Counters($owned.Handle)
+ $row.pid=$owned.Id;$row.process_cpu_s=$pc-$lastCpu;$row.cpu_pct=100*($pc-$lastCpu)/$dt/$logical
+ $row.private_mib=$owned.PrivateMemorySize64/1MB;$row.working_set_mib=$owned.WorkingSet64/1MB
+ $row.threads=$owned.Threads.Count;$row.handles=$owned.HandleCount
+ $row.io_read_bytes_s=($io.ReadBytes-$lastIo.ReadBytes)/$dt;$row.io_write_bytes_s=($io.WriteBytes-$lastIo.WriteBytes)/$dt
+ $lastCpu=$pc;$lastIo=$io
+ }
+ $rows.Add([pscustomobject]$row);$lastT=$now;$lastSys=$sys;$lastCollector=$cc
+ }
+ $rows | Export-Csv -NoTypeInformation -Encoding UTF8 (Join-Path $out "$label.csv")
+ if($owned){$s=Status;Save-Json $s (Join-Path $out "$label-end.json");if($s.state -ne $scenario){throw 'State changed'};Stop-Owned $owned;$owned=$null}
+ elseif(Get-Process wardoff -ErrorAction SilentlyContinue){throw 'Baseline contaminated'}
+ "$(Get-Date -Format o) COMPLETE $label samples=$($rows.Count)" | Add-Content (Join-Path $out 'progress.log')
+ }
+ }
+ 'SUCCESS' | Set-Content (Join-Path $out 'status.txt')
+} catch {
+ $_ | Out-String | Set-Content (Join-Path $out 'error.txt')
+ 'FAILED' | Set-Content (Join-Path $out 'status.txt')
+ throw
+} finally {
+ if($owned){Stop-Owned $owned}
+ [void][BenchNative]::SetThreadExecutionState([uint32]2147483648)
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/RAPPORT.md b/docs/benchmarks/2026-09-29-v0.2.0/RAPPORT.md
new file mode 100644
index 0000000..b6b39bb
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/RAPPORT.md
@@ -0,0 +1,108 @@
+# Benchmark Wardoff 0.2.0
+
+
+## Comparaison des moyennes
+
+| Mesure | Allow | Block |
+|---|---:|---:|
+| Mémoire résidente (MiB) | 12.57 | 13.95 |
+| Mémoire privée (MiB) | 1.96 | 3.25 |
+| CPU (% du total machine) | 0.0024 | 0.0050 |
+
+**Allow** : protections désactivées. **Block** : protections actives en arrière-plan. Les valeurs CPU sont des pourcentages de la capacité totale de la machine.
+
+Mesures locales commencées le 2026-09-29 (UTC). Binaire officiel de la dernière release disponible au moment de cette campagne, vérifié avant exécution.
+
+## Résultats
+
+| Scénario | Mesure | Moyenne | Médiane | P95 | Maximum |
+|---|---|---:|---:|---:|---:|
+| Allow | Mémoire privée (MiB) | 1.955 | 1.957 | 2.020 | 2.043 |
+| Allow | Working Set (MiB) | 12.568 | 12.562 | 12.715 | 12.754 |
+| Allow | CPU Wardoff (% du total machine) | 0.00239 | 0.00000 | 0.00000 | 0.19715 |
+| Allow | Threads | 5.986 | 5.000 | 8.000 | 8.000 |
+| Block | Mémoire privée (MiB) | 3.251 | 3.246 | 3.336 | 3.359 |
+| Block | Working Set (MiB) | 13.946 | 14.047 | 14.266 | 14.277 |
+| Block | CPU Wardoff (% du total machine) | 0.00499 | 0.00000 | 0.00000 | 0.19705 |
+| Block | Threads | 10.333 | 10.000 | 13.000 | 13.000 |
+
+Les moyennes CPU sont pondérées par la durée réelle des intervalles. Médiane, P95 et maximum décrivent les échantillons d’environ une seconde. Un maximum ici ne représente pas un pic instantané.
+
+## Répétitions et activité ambiante
+
+| Répétition | Scénario | CPU Wardoff moyen (%) | Working Set moyen (MiB) | CPU système moyen (%) |
+|---|---|---:|---:|---:|
+| 1 | baseline | — | — | 9.427 |
+| 1 | allow | 0.00260 | 12.527 | 9.332 |
+| 1 | block | 0.00391 | 14.069 | 8.863 |
+| 2 | baseline | — | — | 9.093 |
+| 2 | allow | 0.00326 | 12.607 | 9.528 |
+| 2 | block | 0.00846 | 13.670 | 9.669 |
+| 3 | baseline | — | — | 9.412 |
+| 3 | allow | 0.00130 | 12.568 | 8.561 |
+| 3 | block | 0.00260 | 14.100 | 8.549 |
+
+La baseline sert à documenter l’activité ambiante. Elle n’est pas soustraite aux mesures du processus. Le CPU système inclut toutes les applications, dont le collecteur et l’environnement de travail ; il ne mesure pas le coût causal de Wardoff.
+
+## Protocole
+
+- 3 répétitions × 3 scénarios × 300 secondes : 45 minutes mesurées, 900 échantillons par scénario.
+- Baseline : aucun processus Wardoff. Allow : icône visible, protections désactivées. Block : même interface visible, protections en fonctionnement normal, sans tentative réelle d’arrêt.
+- Ordres : baseline/allow/block, allow/block/baseline, block/baseline/allow. Nouveau processus pour chaque phase avec Wardoff ; stabilisation de 30 secondes exclue avant chaque mesure.
+- Échantillonnage sur horloge monotone, cible d’une seconde. CPU = différence de temps processeur / temps réel / 8 processeurs logiques × 100. 100 % correspond à toute la machine ; multiplier par 8 pour la convention où un cœur logique vaut 100 %.
+- Mémoire privée : PrivateMemorySize64, engagement privé du processus, pas nécessairement résident. Working Set : mémoire résidente du processus, pages partagées incluses. Ce ne sont pas deux mesures à additionner. 1 MiB = 1 048 576 octets.
+- P95 : rang le plus proche par excès (ceil(0,95 × N)). Statistiques descriptives ; les secondes consécutives ne sont pas des répétitions indépendantes.
+- État et couches contrôlés hors mesure au début et à la fin ; sortie normale via WM_QUIT, avec attente de fermeture. Aucun arrêt Windows, redémarrage, suspension, changement de démarrage automatique ou fermeture d’applications tierces.
+- Le collecteur empêche la veille système de manière identique dans tous les scénarios ; le plan d’alimentation reste inchangé. Données conservées en mémoire pendant chaque phase, exportées entre phases.
+
+## Machine et provenance
+
+- CPU : Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz, 4 cœurs / 8 processeurs logiques.
+- RAM visible par Windows : 15.867 GiB (machine équipée de 16 Go).
+- Système : Microsoft Windows 11 IoT Enterprise LTSC, 10.0.26100, build 26100.9445 (révision vérifiée après mesure).
+- Alimentation : Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced). Exécution administrateur : True.
+- Release : [v0.2.0](https://github.com/RomainROCH/Wardoff/releases/tag/v0.2.0). Version affichée par le binaire : wardoff 0.2.0.
+- SHA-256 du binaire : `96d1700c492b1689e6cb3a18847481eb9a203e30db4d4ba273d4b458ed6a84bc` ; correspond au digest de l’asset GitHub.
+- Commit du tag : `9f6c0375c851d0a5b933da0bd69bafc75b215cf5`. HEAD local/main distant vérifié : `aa40e8982273fa66b86b806ec1424a547affdbd3`.
+- Après récupération des références distantes, aucune différence de code applicatif, manifeste, script de build ou dépendances entre le tag, main et dev. Les différences concernent la documentation et les consignes.
+- Tentative de reconstruction avec cargo build --release --locked refusée par Cargo car le verrou des dépendances nécessite une mise à jour. Les mesures concernent donc explicitement le binaire distribué, pas une reconstruction locale. Le rattachement à la release et son digest sont vérifiés ; aucune reproductibilité binaire n’est revendiquée.
+
+## Couches réellement actives
+
+- `shutdown` : active.
+- `local_shutdown` : active.
+- `update` : inactive.
+- `remote` : active.
+- `sleep` : active.
+
+Le journal du runtime administrateur confirme que la tâche `Microsoft\Windows\UpdateOrchestrator\Reboot` est absente sur cette machine LTSC. La couche Update est donc ignorée normalement. Ces résultats couvrent seulement cette combinaison effective de couches. La surveillance locale signalée active par le runtime ne constitue pas une preuve d’efficacité contre un arrêt forcé.
+
+## Contrôles et limites
+
+- Validation : 2700 échantillons, 9 phases complètes, état et identité du processus vérifiés.
+- Intervalles > 1,25 s : 0 ; intervalle maximal : 1.025 s.
+- Le CPU du collecteur figure dans summary.csv et dans les données brutes. Il reste inclus dans le CPU système.
+- CPU système pendant les baselines : moyenne 9.31 %, P95 17.12 %, maximum 86.92 %. Le bureau n’était donc pas au repos absolu. Aucun échantillon n’a été supprimé.
+- CPU moyen du collecteur : baseline 0.014 %, Allow 0.049 %, Block 0.040 % du total machine. Son coût reste distinct du processus Wardoff.
+- Les moyennes CPU et Working Set ont été recalculées indépendamment en PowerShell à partir des CSV ; elles concordent avec les résultats Python.
+- Le processus CPU peut être quantifié par le compteur Windows : un échantillon à zéro ne prouve pas une absence absolue de travail. La moyenne intégrée sur 15 minutes par mode est plus informative.
+- Mesure sur une machine utilisée normalement, avec ses services et applications ouverts, pas sur une image Windows isolée. Pas de contrôle des températures, fréquences instantanées ou activité utilisateur. Ne pas attribuer une différence de CPU système à Wardoff.
+- Démarrage exclu ; pas de test de charge de commandes, de vrai blocage d’arrêt, de batterie ou de fuite mémoire sur plusieurs heures. Résultats non généralisables à toutes les machines ou toutes les protections.
+- Les compteurs I/O sont ceux du processus (fichiers, périphériques, réseau), pas une mesure du trafic physique du disque.
+
+## Fichiers et reproduction
+
+- `Measure-Wardoff.ps1` : collecteur autonome PowerShell ; lancer en administrateur avec le binaire vérifié dans le même dossier.
+- `results/` : CSV bruts, états JSON, métadonnées, journal des phases et statut final.
+- `analyze.py` : validation et calcul des statistiques avec Python standard, sans dépendances supplémentaires.
+- `summary.csv`, `summary.json`, `validation.json` : résultats et contrôles reproductibles.
+- Le pilote technique court est exclu des statistiques et de ce dossier de preuves ; il reste dans l’archive locale initiale.
+- L’empreinte du collecteur n’a pas été enregistrée au démarrage de la campagne. Le script conservé est identique à la copie de l’archive initiale ; le manifeste ultérieur protège cette copie sans constituer une attestation cryptographique de son exécution.
+
+Ce dossier conserve les preuves de la campagne. Son état de sauvegarde distante doit être vérifié par la référence Git distante ; la présence de ces fichiers ne constitue pas à elle seule une sauvegarde hors machine.
+
+## Formulation utilisable avec son contexte
+
+> On an Intel Core i7-6700HQ running Windows 11 IoT Enterprise LTSC, Wardoff 0.2.0 averaged approximately 14 MiB resident memory and less than 0.01% total-system CPU in Block mode across three five-minute background runs. UpdateOrchestrator task protection was unavailable because the task was absent.
+
+Cette formulation décrit une mesure du processus sur cette machine ; elle ne promet ni la même consommation partout, ni une protection contre tous les arrêts Windows.
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/README.md b/docs/benchmarks/2026-09-29-v0.2.0/README.md
new file mode 100644
index 0000000..254d218
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/README.md
@@ -0,0 +1,94 @@
+# Wardoff v0.2.0 resource benchmark — 2026-09-29
+
+This directory preserves the report, protocol, retained measurement script, raw
+samples, executable identity, system information, and analysis for this campaign.
+Use this dated evidence when citing resource usage; do not generalize it to other
+versions, hardware, or protection configurations.
+
+## Mean process resource usage
+
+| Metric | Allow | Block |
+|---|---:|---:|
+| Resident memory / Working Set (MiB) | 12.57 | 13.95 |
+| Private committed memory (MiB) | 1.96 | 3.25 |
+| CPU (% of total machine capacity) | 0.0024% | 0.0050% |
+
+**Allow:** application running with protection disabled. **Block:** normal
+background protection enabled. Both use the visible tray interface. Private
+committed memory and Working Set are different measures and must not be added.
+
+The machine was an Intel Core i7-6700HQ (4 cores / 8 logical processors), 16 GiB
+installed RAM, Windows 11 IoT Enterprise LTSC build 26100.9445, Balanced power
+plan. Wardoff ran elevated. The UpdateOrchestrator Reboot task was absent, so its
+protection layer was inactive. The other four layers reported active in Block.
+No real shutdown attempt was part of the workload.
+
+## Preserved evidence
+
+- [Detailed report and protocol (French)](RAPPORT.md): means, medians, nearest-rank
+ P95, maxima, individual repetitions, sampling method, and limitations.
+- [Retained collection script](Measure-Wardoff.ps1): one-second target intervals,
+ monotonic elapsed time, process and system CPU, private memory, Working Set,
+ threads, handles and process I/O. Its bytes match the original local archive.
+- [Raw data](results/): nine CSV files containing 2,700 samples; runtime state
+ snapshots, phase log, completion status and Update-layer evidence.
+- [System and measurement metadata](results/metadata.json) and
+ [source provenance](provenance.json).
+- [Binary identity](binary.json): version, release URL, source tag and SHA-256
+ verified against the downloaded executable and GitHub release asset digest.
+- [Analysis script](analyze.py), [statistics](summary.csv), and
+ [validation results](validation.json).
+- [File integrity manifest](SHA256SUMS.txt): SHA-256 of every other file in this
+ directory. The scoped `.gitattributes` preserves their bytes across platforms.
+
+The executable is not duplicated in Git. Retrieve it from the URL in
+`binary.json` and require the recorded SHA-256 before using it. The preliminary
+pilot, redundant console output, and full GitHub API response are not part of
+this evidence set. All final-run CSV and state files are preserved unchanged.
+
+No collector-script checksum was recorded at run startup. The archived copy
+matches the initial local archive, and the later manifest protects its bytes;
+this is not cryptographic attestation that those bytes executed. A future
+collector should record its own digest at startup. This historical collector
+and the original run metadata have not been retroactively modified to claim it.
+
+## Audit without rerunning the experiment
+
+From this directory, use Python 3 (standard library only):
+
+```powershell
+python verify.py
+```
+
+The verifier checks manifest coverage and every file digest, then reruns the
+analysis in a temporary directory and compares the generated statistics,
+validation and detailed report. It does not launch Wardoff or alter the stored
+evidence. Checks require nine phases of 300 samples, each phase within 1.25
+seconds of its target duration, no sample interval above 1.25 seconds, consistent
+elapsed-time totals, and consistent runtime states. These tolerances are for
+this recorded campaign, not a universal acceptance rule for future experiments.
+
+To conduct a **new** experiment, copy `Measure-Wardoff.ps1` and the verified
+executable into a separate new directory, then run the script in an elevated
+PowerShell session. Do not overwrite this dated evidence set. The collector is
+an exact historical script; its version/hash and source metadata are pinned to
+this campaign and must be reviewed for a different build.
+
+## Interpretation and retention
+
+There were three 300-second repetitions per scenario, with 30 seconds of
+excluded warmup and rotated scenario order: 45 minutes measured in total.
+CPU is normalized across all eight logical processors and uses actual elapsed
+time. A zero median/P95 reflects timer quantization and does not mean zero CPU
+work. Maxima represent approximately one-second intervals, not instantaneous
+peaks. The desktop was not isolated; baseline system CPU averaged 9.31%.
+
+The figures describe Wardoff's process, not the complete causal cost of Windows
+services or kernel activity. Startup, actual shutdown blocking, sustained
+foreground workloads, battery use, and long-term leaks were not measured.
+
+Keep the whole directory together. Corrections to the report or analysis must
+be explicit Git changes followed by manifest regeneration; never silently edit
+raw measurements. A future campaign belongs in a new dated directory. Local
+files, a ZIP, and a local commit alone are not an off-machine backup: completion
+requires the evidence commit on an authorized remote, with its SHA read back.
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/SHA256SUMS.txt b/docs/benchmarks/2026-09-29-v0.2.0/SHA256SUMS.txt
new file mode 100644
index 0000000..9a168fa
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/SHA256SUMS.txt
@@ -0,0 +1,36 @@
+f9161820b4789e216033dc3e0860bf6bd027e8e9336f834acd2927615efd5a8f .gitattributes
+f1b00c24bd5d40dd334c12f641a45f122853ca58dd0adac9063c4c79bfe84ca0 analyze.py
+ccd539b23c4b9d597d9c1b7f0fcc74a4b569f5a76e9846c855fb5daad94d3886 binary.json
+c19f1edb4cb3c6523b9e4c96a4a1391e901e94e507b871ce1f519cbdab989ff9 Measure-Wardoff.ps1
+d31f75278c92b7fff43aa975094dc56c923fb8d190bc9c1451be7544da897911 provenance.json
+9beaa33ffa568ba8af79996cfe26a8d8beac9c13dccf5e8ef2b569d977228f51 RAPPORT.md
+44a46bb90fbfcd5e3b9f2eadbc5d6bf55dd6d81925a675c1a5ac58962776de9d README.md
+d01b00e39e2a123f56e2248e5d244f4ab5a3c15d5b07e412d3153f35d7e0f756 results/metadata.json
+fca1b4a18d3bf2621765981169f1b363959ded313ce9fa2087f8a8abb11f74b5 results/progress.log
+9b59ba196116e27d5de0a83bb1b06cf5acaec4930babe0ead12389fedca4f6b3 results/run-1-allow-end.json
+db9298d58b5fdf3c082422ae729b7d05b0d4719f5f3392072e5bb61fd3aa4466 results/run-1-allow-start.json
+95615320b11fdd267d9c04907aa4d24b28420bdc9f19d9d6fb34616c0310781d results/run-1-allow.csv
+b84725b414bdf183e96e8587854fcbff3e500b5f9ffc949f63d9cce01e27e319 results/run-1-baseline.csv
+337329cbd5eb256bc3755bed597be49e6e9948ae445dea55c8cd65dcb6bae3ef results/run-1-block-end.json
+5f2095d4586cc5fb1c4e54dcb330d67beef4f93acdfa8a26f39af1bc1c4f642a results/run-1-block-start.json
+bb4047216e7ab3f6e41507bc167ef281be3a85e7694312269e7350ab5642d7c3 results/run-1-block.csv
+9b59ba196116e27d5de0a83bb1b06cf5acaec4930babe0ead12389fedca4f6b3 results/run-2-allow-end.json
+db9298d58b5fdf3c082422ae729b7d05b0d4719f5f3392072e5bb61fd3aa4466 results/run-2-allow-start.json
+99fa208a15314ecf65675adab4f178d4b3ba600f9c8c43b4c06df70d94ecaa2d results/run-2-allow.csv
+0e929531bc267972059b671e3e0f5a84a0931473ec00bd4d382b4fbffa8c5f1b results/run-2-baseline.csv
+337329cbd5eb256bc3755bed597be49e6e9948ae445dea55c8cd65dcb6bae3ef results/run-2-block-end.json
+271819b5b1ec995a656952f71b90434aeb52038818243f0712c75fdd51fbf267 results/run-2-block-start.json
+8b345a7f6569a50aa45f51854effc96fed061e3ffd1404568d5f5e428f34f054 results/run-2-block.csv
+9b59ba196116e27d5de0a83bb1b06cf5acaec4930babe0ead12389fedca4f6b3 results/run-3-allow-end.json
+db9298d58b5fdf3c082422ae729b7d05b0d4719f5f3392072e5bb61fd3aa4466 results/run-3-allow-start.json
+62b75edc3084aaca6ec510224805e2a5f7b1cda5d39f2bfae59edd3678d4656c results/run-3-allow.csv
+9436e862238f13d23f92a9d31249e878a37689233b41514dcd01b16459e9fc30 results/run-3-baseline.csv
+337329cbd5eb256bc3755bed597be49e6e9948ae445dea55c8cd65dcb6bae3ef results/run-3-block-end.json
+271819b5b1ec995a656952f71b90434aeb52038818243f0712c75fdd51fbf267 results/run-3-block-start.json
+8f1e994dde69f7b2e152b07d69e46ca9f9c2e39ef412608dba0d37d0a8f88f08 results/run-3-block.csv
+421a244564c34296e185cdcf70d2269227ae102f2e7eeef94afddd495c4e06c2 results/status.txt
+1921846910314078141a41cb6284825266c39dad955c9550f187d50d86e81998 results/update-layer-evidence.jsonl
+37fb6904743ebb615cc676a0b77b882b94d0152a64b53e2a3da429202b557e4a summary.csv
+4d91f1eb0d231658a790ecd4ce9ac994c58ea028f26368ae7a38782e988cff83 summary.json
+0a83d3cb04e61b2bf7f99249fc70438e9a4c27c000ac504ef47884ef9ed40250 validation.json
+08e31b82234bbc30665c268851faa7d3a9586d06fba516dabb2cb207f1807f84 verify.py
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/analyze.py b/docs/benchmarks/2026-09-29-v0.2.0/analyze.py
new file mode 100644
index 0000000..2720541
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/analyze.py
@@ -0,0 +1,147 @@
+"""Validate all samples and compute reproducible nearest-rank descriptive statistics."""
+import csv, json, math, statistics
+from pathlib import Path
+
+root = Path(__file__).resolve().parent
+folder = root / 'results'
+meta = json.loads((folder / 'metadata.json').read_text(encoding='utf-8-sig'))
+provenance = json.loads((root/'provenance.json').read_text(encoding='utf-8-sig')) if (root/'provenance.json').exists() else {}
+assert (folder / 'status.txt').read_text(encoding='utf-8-sig').strip() == 'SUCCESS'
+metrics = ['cpu_pct','private_mib','working_set_mib','threads','handles',
+ 'io_read_bytes_s','io_write_bytes_s','system_cpu_pct','collector_cpu_pct','interval_s']
+all_rows = []
+checks = []
+layer_sets = {}
+for run in range(1, meta['repeats'] + 1):
+ for scenario in ['baseline','allow','block']:
+ label = f'run-{run}-{scenario}'
+ with (folder / f'{label}.csv').open(encoding='utf-8-sig', newline='') as stream:
+ rows = list(csv.DictReader(stream))
+ assert len(rows) == meta['seconds'], (label, len(rows))
+ assert [int(r['sample']) for r in rows] == list(range(1,len(rows)+1))
+ assert all(r['scenario']==scenario and int(r['run'])==run for r in rows)
+ for r in rows:
+ for key in metrics + ['elapsed_s','process_cpu_s']:
+ r[key] = float(r[key]) if r[key] else None
+ assert r[key] is None or math.isfinite(r[key])
+ assert 0 < r['interval_s'] <= 1.25, (label, 'Sampling interval outside campaign tolerance')
+ assert 0 <= r['system_cpu_pct'] <= 100
+ assert all(rows[i]['elapsed_s'] > rows[i-1]['elapsed_s'] for i in range(1,len(rows)))
+ assert abs(rows[-1]['elapsed_s'] - meta['seconds']) <= 1.25, (label, 'Incorrect phase duration')
+ # The stopwatch starts before the initial counter snapshot; retain that offset.
+ initial_offset = rows[0]['elapsed_s'] - rows[0]['interval_s']
+ assert 0 <= initial_offset < 0.1, (label, 'Unexpected initial timing offset')
+ assert abs(sum(r['interval_s'] for r in rows) - (rows[-1]['elapsed_s'] - initial_offset)) < 0.000001, (label, 'Inconsistent elapsed time')
+ if scenario != 'baseline':
+ assert len({r['pid'] for r in rows}) == 1
+ assert all(0 <= r['cpu_pct'] <= 100 and r['private_mib'] > 0 for r in rows)
+ start=json.loads((folder/f'{label}-start.json').read_text(encoding='utf-8-sig'))
+ end=json.loads((folder/f'{label}-end.json').read_text(encoding='utf-8-sig'))
+ assert start['state'] == end['state'] == scenario
+ assert start['layers'] == end['layers'], label
+ assert start['layers'] == layer_sets.setdefault(scenario, start['layers']), label
+ assert end['blocked_count'] == start['blocked_count'], (label, 'Unexpected shutdown activity')
+ assert end['uptime_seconds'] >= start['uptime_seconds'] + meta['seconds'] - 2
+ checks.append({'run':run,'scenario':scenario,'samples':len(rows),
+ 'elapsed_s':rows[-1]['elapsed_s'],
+ 'intervals_over_1_25s':sum(r['interval_s']>1.25 for r in rows),
+ 'max_interval_s':max(r['interval_s'] for r in rows)})
+ all_rows.extend(rows)
+
+summaries=[]
+for scope in ['pooled', *range(1, meta['repeats']+1)]:
+ for scenario in ['baseline','allow','block']:
+ rows=[r for r in all_rows if r['scenario']==scenario and (scope=='pooled' or int(r['run'])==scope)]
+ for metric in metrics:
+ values=sorted(r[metric] for r in rows if r[metric] is not None)
+ if not values: continue
+ mean=statistics.mean(values)
+ if metric in ['cpu_pct','collector_cpu_pct','system_cpu_pct','io_read_bytes_s','io_write_bytes_s']:
+ mean=sum(r[metric]*r['interval_s'] for r in rows)/sum(r['interval_s'] for r in rows)
+ summaries.append(dict(scope=scope,scenario=scenario,metric=metric,n=len(values),mean=mean,
+ median=statistics.median(values),p95=values[math.ceil(.95*len(values))-1],
+ maximum=max(values),minimum=min(values)))
+with (root/'summary.csv').open('w',encoding='utf-8',newline='') as stream:
+ writer=csv.DictWriter(stream,fieldnames=list(summaries[0]));writer.writeheader();writer.writerows(summaries)
+(root/'validation.json').write_text(json.dumps({'passed':True,'samples':len(all_rows),'runs':checks},indent=2))
+(root/'summary.json').write_text(json.dumps(summaries,indent=2))
+def stat(scenario, metric, scope='pooled'):
+ return next(s for s in summaries if s['scope']==scope and s['scenario']==scenario and s['metric']==metric)
+
+comparison = ['', '## Comparaison des moyennes', '',
+ '| Mesure | Allow | Block |', '|---|---:|---:|']
+for metric, label, digits in [('working_set_mib', 'Mémoire résidente (MiB)', 2),
+ ('private_mib', 'Mémoire privée (MiB)', 2),
+ ('cpu_pct', 'CPU (% du total machine)', 4)]:
+ comparison.append(f"| {label} | {stat('allow', metric)['mean']:.{digits}f} | {stat('block', metric)['mean']:.{digits}f} |")
+comparison += ['', '**Allow** : protections désactivées. **Block** : protections actives en arrière-plan. Les valeurs CPU sont des pourcentages de la capacité totale de la machine.', '']
+lines = ['# Benchmark Wardoff 0.2.0', '', *comparison,
+ f"Mesures locales commencées le {meta['startedUtc'][:10]} (UTC). Binaire officiel de la dernière release disponible au moment de cette campagne, vérifié avant exécution.", '',
+ '## Résultats', '',
+ '| Scénario | Mesure | Moyenne | Médiane | P95 | Maximum |',
+ '|---|---|---:|---:|---:|---:|']
+for scenario in ['allow','block']:
+ for metric, label in [('private_mib','Mémoire privée (MiB)'),('working_set_mib','Working Set (MiB)'),('cpu_pct','CPU Wardoff (% du total machine)'),('threads','Threads')]:
+ s=stat(scenario,metric)
+ digits=5 if metric=='cpu_pct' else 3
+ vals=' | '.join(f'{s[k]:.{digits}f}' for k in ['mean','median','p95','maximum'])
+ lines.append(f'| {scenario.title()} | {label} | {vals} |')
+lines += ['', 'Les moyennes CPU sont pondérées par la durée réelle des intervalles. Médiane, P95 et maximum décrivent les échantillons d’environ une seconde. Un maximum ici ne représente pas un pic instantané.', '',
+ '## Répétitions et activité ambiante', '',
+ '| Répétition | Scénario | CPU Wardoff moyen (%) | Working Set moyen (MiB) | CPU système moyen (%) |',
+ '|---|---|---:|---:|---:|']
+for run in range(1,meta['repeats']+1):
+ for scenario in ['baseline','allow','block']:
+ cpu='—' if scenario=='baseline' else f"{stat(scenario,'cpu_pct',run)['mean']:.5f}"
+ ram='—' if scenario=='baseline' else f"{stat(scenario,'working_set_mib',run)['mean']:.3f}"
+ system=stat(scenario,'system_cpu_pct',run)['mean']
+ lines.append(f'| {run} | {scenario} | {cpu} | {ram} | {system:.3f} |')
+lines += ['', 'La baseline sert à documenter l’activité ambiante. Elle n’est pas soustraite aux mesures du processus. Le CPU système inclut toutes les applications, dont le collecteur et l’environnement de travail ; il ne mesure pas le coût causal de Wardoff.', '',
+ '## Protocole', '',
+ f"- {meta['repeats']} répétitions × 3 scénarios × {meta['seconds']} secondes : {meta['repeats']*3*meta['seconds']/60:g} minutes mesurées, {meta['repeats']*meta['seconds']} échantillons par scénario.",
+ '- Baseline : aucun processus Wardoff. Allow : icône visible, protections désactivées. Block : même interface visible, protections en fonctionnement normal, sans tentative réelle d’arrêt.',
+ '- Ordres : baseline/allow/block, allow/block/baseline, block/baseline/allow. Nouveau processus pour chaque phase avec Wardoff ; stabilisation de 30 secondes exclue avant chaque mesure.',
+ f"- Échantillonnage sur horloge monotone, cible d’une seconde. CPU = différence de temps processeur / temps réel / {meta['logicalProcessors']} processeurs logiques × 100. 100 % correspond à toute la machine ; multiplier par {meta['logicalProcessors']} pour la convention où un cœur logique vaut 100 %.",
+ '- Mémoire privée : PrivateMemorySize64, engagement privé du processus, pas nécessairement résident. Working Set : mémoire résidente du processus, pages partagées incluses. Ce ne sont pas deux mesures à additionner. 1 MiB = 1 048 576 octets.',
+ '- P95 : rang le plus proche par excès (ceil(0,95 × N)). Statistiques descriptives ; les secondes consécutives ne sont pas des répétitions indépendantes.',
+ '- État et couches contrôlés hors mesure au début et à la fin ; sortie normale via WM_QUIT, avec attente de fermeture. Aucun arrêt Windows, redémarrage, suspension, changement de démarrage automatique ou fermeture d’applications tierces.',
+ '- Le collecteur empêche la veille système de manière identique dans tous les scénarios ; le plan d’alimentation reste inchangé. Données conservées en mémoire pendant chaque phase, exportées entre phases.', '',
+ '## Machine et provenance', '',
+ f"- CPU : {meta['cpu'][0]['Name']}, {sum(c['NumberOfCores'] for c in meta['cpu'])} cœurs / {meta['logicalProcessors']} processeurs logiques.",
+ f"- RAM visible par Windows : {meta['os']['TotalVisibleMemorySize']/1024/1024:.3f} GiB (machine équipée de 16 Go).",
+ f"- Système : {meta['os']['Caption']}, {meta['os']['Version']}, build {provenance.get('osBuild',meta['os']['BuildNumber'])} (révision vérifiée après mesure).",
+ f"- Alimentation : {meta['powerPlan']}. Exécution administrateur : {meta['admin']}.",
+ '- Release : [v0.2.0](https://github.com/RomainROCH/Wardoff/releases/tag/v0.2.0). Version affichée par le binaire : wardoff 0.2.0.',
+ f"- SHA-256 du binaire : `{meta['binarySha256'].lower()}` ; correspond au digest de l’asset GitHub.",
+ f"- Commit du tag : `{meta['releaseCommit']}`. HEAD local/main distant vérifié : `{meta['mainCommit']}`.",
+ '- Après récupération des références distantes, aucune différence de code applicatif, manifeste, script de build ou dépendances entre le tag, main et dev. Les différences concernent la documentation et les consignes.',
+ '- Tentative de reconstruction avec cargo build --release --locked refusée par Cargo car le verrou des dépendances nécessite une mise à jour. Les mesures concernent donc explicitement le binaire distribué, pas une reconstruction locale. Le rattachement à la release et son digest sont vérifiés ; aucune reproductibilité binaire n’est revendiquée.', '',
+ '## Couches réellement actives', '']
+block_status=json.loads((folder/'run-1-block-start.json').read_text(encoding='utf-8-sig'))
+for layer, active in block_status['layers'].items():
+ lines.append(f"- `{layer}` : {'active' if active else 'inactive'}.")
+lines += ['', 'Le journal du runtime administrateur confirme que la tâche `Microsoft\\Windows\\UpdateOrchestrator\\Reboot` est absente sur cette machine LTSC. La couche Update est donc ignorée normalement. Ces résultats couvrent seulement cette combinaison effective de couches. La surveillance locale signalée active par le runtime ne constitue pas une preuve d’efficacité contre un arrêt forcé.', '',
+ '## Contrôles et limites', '',
+ f"- Validation : {len(all_rows)} échantillons, {len(checks)} phases complètes, état et identité du processus vérifiés.",
+ f"- Intervalles > 1,25 s : {sum(c['intervals_over_1_25s'] for c in checks)} ; intervalle maximal : {max(c['max_interval_s'] for c in checks):.3f} s.",
+ '- Le CPU du collecteur figure dans summary.csv et dans les données brutes. Il reste inclus dans le CPU système.',
+ f"- CPU système pendant les baselines : moyenne {stat('baseline','system_cpu_pct')['mean']:.2f} %, P95 {stat('baseline','system_cpu_pct')['p95']:.2f} %, maximum {stat('baseline','system_cpu_pct')['maximum']:.2f} %. Le bureau n’était donc pas au repos absolu. Aucun échantillon n’a été supprimé.",
+ f"- CPU moyen du collecteur : baseline {stat('baseline','collector_cpu_pct')['mean']:.3f} %, Allow {stat('allow','collector_cpu_pct')['mean']:.3f} %, Block {stat('block','collector_cpu_pct')['mean']:.3f} % du total machine. Son coût reste distinct du processus Wardoff.",
+ '- Les moyennes CPU et Working Set ont été recalculées indépendamment en PowerShell à partir des CSV ; elles concordent avec les résultats Python.',
+ '- Le processus CPU peut être quantifié par le compteur Windows : un échantillon à zéro ne prouve pas une absence absolue de travail. La moyenne intégrée sur 15 minutes par mode est plus informative.',
+ '- Mesure sur une machine utilisée normalement, avec ses services et applications ouverts, pas sur une image Windows isolée. Pas de contrôle des températures, fréquences instantanées ou activité utilisateur. Ne pas attribuer une différence de CPU système à Wardoff.',
+ '- Démarrage exclu ; pas de test de charge de commandes, de vrai blocage d’arrêt, de batterie ou de fuite mémoire sur plusieurs heures. Résultats non généralisables à toutes les machines ou toutes les protections.',
+ '- Les compteurs I/O sont ceux du processus (fichiers, périphériques, réseau), pas une mesure du trafic physique du disque.', '',
+ '## Fichiers et reproduction', '',
+ '- `Measure-Wardoff.ps1` : collecteur autonome PowerShell ; lancer en administrateur avec le binaire vérifié dans le même dossier.',
+ '- `results/` : CSV bruts, états JSON, métadonnées, journal des phases et statut final.',
+ '- `analyze.py` : validation et calcul des statistiques avec Python standard, sans dépendances supplémentaires.',
+ '- `summary.csv`, `summary.json`, `validation.json` : résultats et contrôles reproductibles.',
+ '- Le pilote technique court est exclu des statistiques et de ce dossier de preuves ; il reste dans l’archive locale initiale.',
+ '- L’empreinte du collecteur n’a pas été enregistrée au démarrage de la campagne. Le script conservé est identique à la copie de l’archive initiale ; le manifeste ultérieur protège cette copie sans constituer une attestation cryptographique de son exécution.', '',
+ 'Ce dossier conserve les preuves de la campagne. Son état de sauvegarde distante doit être vérifié par la référence Git distante ; la présence de ces fichiers ne constitue pas à elle seule une sauvegarde hors machine.', '']
+lines += ['## Formulation utilisable avec son contexte', '',
+ '> On an Intel Core i7-6700HQ running Windows 11 IoT Enterprise LTSC, Wardoff 0.2.0 averaged approximately 14 MiB resident memory and less than 0.01% total-system CPU in Block mode across three five-minute background runs. UpdateOrchestrator task protection was unavailable because the task was absent.', '',
+ 'Cette formulation décrit une mesure du processus sur cette machine ; elle ne promet ni la même consommation partout, ni une protection contre tous les arrêts Windows.', '']
+(root/'RAPPORT.md').write_text('\n'.join(lines),encoding='utf-8')
+print(json.dumps([s for s in summaries if s['scope']=='pooled'],indent=2))
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/binary.json b/docs/benchmarks/2026-09-29-v0.2.0/binary.json
new file mode 100644
index 0000000..d1d5c6a
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/binary.json
@@ -0,0 +1,13 @@
+{
+ "version": "0.2.0",
+ "filename": "wardoff.exe",
+ "sizeBytes": 1825280,
+ "sha256": "96d1700c492b1689e6cb3a18847481eb9a203e30db4d4ba273d4b458ed6a84bc",
+ "releaseUrl": "https://github.com/RomainROCH/Wardoff/releases/tag/v0.2.0",
+ "downloadUrl": "https://github.com/RomainROCH/Wardoff/releases/download/v0.2.0/wardoff.exe",
+ "releasePublishedAt": "2026-05-03T10:53:31Z",
+ "sourceTag": "v0.2.0",
+ "sourceCommit": "9f6c0375c851d0a5b933da0bd69bafc75b215cf5",
+ "verification": "Downloaded executable hash matched the GitHub asset digest before measurement and again after measurement; --version returned wardoff 0.2.0.",
+ "limitation": "Source association is through the release tag; no reproducible-build claim. Local cargo build --release --locked failed because the checked-in lockfile required an update."
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/provenance.json b/docs/benchmarks/2026-09-29-v0.2.0/provenance.json
new file mode 100644
index 0000000..9d635a1
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/provenance.json
@@ -0,0 +1,19 @@
+{
+ "checkedUtc": "2026-09-29T02:29:58.5370137Z",
+ "branch": "main",
+ "head": "aa40e8982273fa66b86b806ec1424a547affdbd3",
+ "upstream": "origin/main",
+ "workingTreeClean": true,
+ "sourceTreeRelease": "89c6f08a6b9e010034ba312473655893b9345e69",
+ "sourceTreeMain": "89c6f08a6b9e010034ba312473655893b9345e69",
+ "sourceTreeDev": "89c6f08a6b9e010034ba312473655893b9345e69",
+ "remoteRefs": [
+ "aa40e8982273fa66b86b806ec1424a547affdbd3\tHEAD",
+ "2c6d772d4ecfcb0a30a37b5cd345cd5b39167ddf\trefs/heads/dev",
+ "aa40e8982273fa66b86b806ec1424a547affdbd3\trefs/heads/main",
+ "9f6c0375c851d0a5b933da0bd69bafc75b215cf5\trefs/tags/v0.2.0"
+ ],
+ "wardoffRunning": false,
+ "osBuild": "26100.9445",
+ "physicalRamBytes": 17179869184
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/metadata.json b/docs/benchmarks/2026-09-29-v0.2.0/results/metadata.json
new file mode 100644
index 0000000..e475d57
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/metadata.json
@@ -0,0 +1,32 @@
+{
+ "startedUtc": "2026-09-29T01:38:30.4908143Z",
+ "seconds": 300,
+ "warmupSeconds": 30,
+ "repeats": 3,
+ "admin": true,
+ "cpu": [
+ {
+ "Name": "Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz",
+ "NumberOfCores": 4,
+ "NumberOfLogicalProcessors": 8
+ }
+ ],
+ "os": {
+ "Caption": "Microsoft Windows 11 IoT Enterprise LTSC",
+ "Version": "10.0.26100",
+ "BuildNumber": "26100",
+ "TotalVisibleMemorySize": 16637696
+ },
+ "logicalProcessors": 8,
+ "powerPlan": "Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)",
+ "binarySha256": "96D1700C492B1689E6CB3A18847481EB9A203E30DB4D4BA273D4B458ED6A84BC",
+ "version": "0.2.0",
+ "releaseTag": "v0.2.0",
+ "releaseCommit": "9f6c0375c851d0a5b933da0bd69bafc75b215cf5",
+ "mainCommit": "aa40e8982273fa66b86b806ec1424a547affdbd3",
+ "cpuDefinition": "100 * process CPU seconds / actual elapsed seconds / logical processors",
+ "ramUnit": "MiB = 1048576 bytes",
+ "ioDefinition": "Process I/O includes file/device/network operations, not physical disk traffic",
+ "p95Definition": "nearest rank",
+ "collectorPid": 16356
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/progress.log b/docs/benchmarks/2026-09-29-v0.2.0/results/progress.log
new file mode 100644
index 0000000..32462fa
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/progress.log
@@ -0,0 +1,18 @@
+2026-09-29T03:38:30.6211706+02:00 START run-1-baseline
+2026-09-29T03:44:00.6786970+02:00 COMPLETE run-1-baseline samples=300
+2026-09-29T03:44:00.6817761+02:00 START run-1-allow
+2026-09-29T03:49:33.9134732+02:00 COMPLETE run-1-allow samples=300
+2026-09-29T03:49:33.9155803+02:00 START run-1-block
+2026-09-29T03:55:07.0833654+02:00 COMPLETE run-1-block samples=300
+2026-09-29T03:55:07.0853594+02:00 START run-2-allow
+2026-09-29T04:00:40.2110218+02:00 COMPLETE run-2-allow samples=300
+2026-09-29T04:00:40.2132790+02:00 START run-2-block
+2026-09-29T04:06:13.3630262+02:00 COMPLETE run-2-block samples=300
+2026-09-29T04:06:13.3652464+02:00 START run-2-baseline
+2026-09-29T04:11:43.6871983+02:00 COMPLETE run-2-baseline samples=300
+2026-09-29T04:11:43.6892391+02:00 START run-3-block
+2026-09-29T04:17:16.8447559+02:00 COMPLETE run-3-block samples=300
+2026-09-29T04:17:16.8461691+02:00 START run-3-baseline
+2026-09-29T04:22:46.8746987+02:00 COMPLETE run-3-baseline samples=300
+2026-09-29T04:22:46.8768976+02:00 START run-3-allow
+2026-09-29T04:28:19.9941616+02:00 COMPLETE run-3-allow samples=300
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow-end.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow-end.json
new file mode 100644
index 0000000..14f27af
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow-end.json
@@ -0,0 +1,12 @@
+{
+ "state": "allow",
+ "layers": {
+ "shutdown": false,
+ "local_shutdown": false,
+ "update": false,
+ "remote": false,
+ "sleep": false
+ },
+ "uptime_seconds": 333,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow-start.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow-start.json
new file mode 100644
index 0000000..d41852d
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow-start.json
@@ -0,0 +1,12 @@
+{
+ "state": "allow",
+ "layers": {
+ "shutdown": false,
+ "local_shutdown": false,
+ "update": false,
+ "remote": false,
+ "sleep": false
+ },
+ "uptime_seconds": 32,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow.csv
new file mode 100644
index 0000000..67afdf6
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-allow.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"1","allow","1","2026-09-29T01:44:34.8208793Z","1.0071993","1.0071959","7.03125","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","2","2026-09-29T01:44:35.8147327Z","2.0007542","0.9935549","6.8359375","0.393158948740528","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","3","2026-09-29T01:44:36.8275183Z","3.0135132","1.012759","6.73076923076923","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","4","2026-09-29T01:44:37.8265025Z","4.0125915","0.9990783","8.59375","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","5","2026-09-29T01:44:38.8292329Z","5.0153445","1.002753","7.421875","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","6","2026-09-29T01:44:39.8218578Z","6.0078652","0.9925207","13.4920634920635","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","7","2026-09-29T01:44:40.8215352Z","7.0075465","0.999681300000001","14.0625","0.195374765937904","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","8","2026-09-29T01:44:41.8329992Z","8.0189825","1.011436","8.65384615384615","0.193104160816898","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","9","2026-09-29T01:44:42.8193121Z","9.0054358","0.986453299999999","4.36507936507936","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","10","2026-09-29T01:44:43.8287856Z","10.0149963","1.0095605","7.11538461538461","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","11","2026-09-29T01:44:44.8256384Z","11.0116241","0.996627799999999","17.1875","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","12","2026-09-29T01:44:45.8248034Z","12.0108113","0.999187200000001","41.2109375","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","13","2026-09-29T01:44:46.8195620Z","13.0058502","0.995038899999999","24.4047619047619","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","14","2026-09-29T01:44:47.8301866Z","14.0164084","1.0105582","17.1153846153846","0.193271896660677","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","15","2026-09-29T01:44:48.8150721Z","15.0010277","0.9846193","7.73809523809524","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","16","2026-09-29T01:44:49.8254435Z","16.0115384","1.0105107","10.2119460500963","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","17","2026-09-29T01:44:50.8236009Z","17.0096437","0.998105299999999","12.4756335282651","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","18","2026-09-29T01:44:51.8204289Z","18.0065532","0.996909500000001","12.3015873015873","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","19","2026-09-29T01:44:52.8204953Z","19.0065256","0.999972400000001","8.43137254901961","0.195317890773785","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","20","2026-09-29T01:44:53.8205382Z","20.0067029","1.0001773","8.94941634241245","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","21","2026-09-29T01:44:54.8214131Z","21.0075635","1.0008606","4.8828125","0.195144558592875","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","22","2026-09-29T01:44:55.8247459Z","22.0107565","1.003193","7.69230769230769","0.194690852109215","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","23","2026-09-29T01:44:56.8270108Z","23.0130389","1.0022824","7.421875","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","24","2026-09-29T01:44:57.8273094Z","24.0133544","1.0003155","10.7421875","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","25","2026-09-29T01:44:58.8135901Z","24.9996121","0.986257700000003","5.95238095238095","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","26","2026-09-29T01:44:59.8203213Z","26.0064104","1.0067983","6.4453125","0","12788","0","0","2","12.57421875","8","176","0","0"
+"1","allow","27","2026-09-29T01:45:00.8189653Z","27.0049596","0.998549199999999","8.3984375","0.195596271070069","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","28","2026-09-29T01:45:01.8195956Z","28.0056817","1.0007221","10.7421875","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","29","2026-09-29T01:45:02.8326358Z","29.0187666","1.0130849","17.3076923076923","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","30","2026-09-29T01:45:03.8294050Z","30.0152776","0.996510999999998","18.5546875","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","31","2026-09-29T01:45:04.8259252Z","31.0120128","0.9967352","11.328125","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","32","2026-09-29T01:45:05.8207280Z","32.0067061","0.994693299999998","33.1349206349206","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","33","2026-09-29T01:45:06.8190654Z","33.0051886","0.998482500000001","5.859375","0.195609337169154","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","34","2026-09-29T01:45:07.8314215Z","34.0174828","1.0122942","10.7692307692308","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","35","2026-09-29T01:45:08.8282068Z","35.0142989","0.996816100000004","7.8125","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","36","2026-09-29T01:45:09.8259210Z","36.0119269","0.997627999999999","6.0546875","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","37","2026-09-29T01:45:10.8261807Z","37.0122356","1.0003087","5.2734375","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","38","2026-09-29T01:45:11.8292992Z","38.0154371","1.0032015","6.4453125","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","39","2026-09-29T01:45:12.8268343Z","39.0127586","0.997321499999998","14.2578125","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","40","2026-09-29T01:45:13.8196105Z","40.0055856","0.992826999999998","27.1825396825397","0","12788","0","0","1.97265625","12.55859375","7","176","0","0"
+"1","allow","41","2026-09-29T01:45:14.8301554Z","41.016229","1.0106434","16.9230769230769","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","42","2026-09-29T01:45:15.8163257Z","42.002306","0.986077000000002","4.16666666666667","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","43","2026-09-29T01:45:16.8275248Z","43.0137178","1.0114118","6.34615384615385","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","44","2026-09-29T01:45:17.8278421Z","44.0140042","1.0002864","10.9375","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","45","2026-09-29T01:45:18.8296378Z","45.015739","1.0017348","6.8359375","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","46","2026-09-29T01:45:19.8188580Z","46.0048705","0.989131499999999","3.76984126984127","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","47","2026-09-29T01:45:20.8191545Z","47.0052261","1.0003556","6.0546875","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","48","2026-09-29T01:45:21.8312880Z","48.0172922","1.01206610000001","7.30769230769231","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","49","2026-09-29T01:45:22.8285978Z","49.0141529","0.996860699999999","5.859375","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","50","2026-09-29T01:45:23.8285962Z","50.0146478","1.0004949","6.0546875","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","51","2026-09-29T01:45:24.8146175Z","51.0007159","0.986068099999997","4.76190476190476","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","52","2026-09-29T01:45:25.8216398Z","52.0078996","1.0071837","7.03125","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","53","2026-09-29T01:45:26.8220548Z","53.0080225","1.0001229","9.5703125","0.195288499043467","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","54","2026-09-29T01:45:27.8232959Z","54.0092677","1.0012452","11.1328125","0.195069599334908","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","55","2026-09-29T01:45:28.8185483Z","55.0045049","0.995237200000005","7.6171875","0.196247186097946","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","56","2026-09-29T01:45:29.8185066Z","56.0045875","1.0000826","6.0665362035225","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","57","2026-09-29T01:45:30.8333859Z","57.0193056","1.0147181","5.75815738963532","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","58","2026-09-29T01:45:31.8186206Z","58.0045872","0.9852816","5.35714285714286","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","59","2026-09-29T01:45:32.8335171Z","59.0195652","1.014978","10","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","60","2026-09-29T01:45:33.8337594Z","60.0197818","1.0002166","7.6171875","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","61","2026-09-29T01:45:34.8206719Z","61.0065752","0.986793400000003","6.34920634920635","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","62","2026-09-29T01:45:35.8201516Z","62.006109","0.999533799999995","5.078125","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","63","2026-09-29T01:45:36.8249810Z","63.0111272","1.0050182","9.23076923076923","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","64","2026-09-29T01:45:37.8194817Z","64.0054392","0.994312000000001","14.0873015873016","0","12788","0.015625","0.196429792660654","1.97265625","12.515625","7","176","0","0"
+"1","allow","65","2026-09-29T01:45:38.8282011Z","65.0142717","1.0088325","10.3846153846154","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","66","2026-09-29T01:45:39.8143885Z","66.0003684","0.986096700000004","5.75396825396825","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","67","2026-09-29T01:45:40.8171172Z","67.0038483","1.0034799","4.8828125","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","68","2026-09-29T01:45:41.8329013Z","68.0189734","1.01512509999999","5.76923076923077","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","69","2026-09-29T01:45:42.8219484Z","69.0079333","0.988959899999998","4.96031746031746","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","70","2026-09-29T01:45:43.8221185Z","70.0081749","1.00024160000001","9.9609375","0.195265323897744","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","71","2026-09-29T01:45:44.8208321Z","71.0067852","0.998610299999996","6.45792563600783","0.195584303506584","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","72","2026-09-29T01:45:45.8188586Z","72.0048121","0.998026899999999","8.96686159844055","0.195698632972719","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","73","2026-09-29T01:45:46.8239350Z","73.0098602","1.0050481","8.26923076923077","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","74","2026-09-29T01:45:47.8251015Z","74.0112474","1.00138720000001","9.765625","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","75","2026-09-29T01:45:48.8283921Z","75.0143428","1.00309539999999","16.40625","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","76","2026-09-29T01:45:49.8178668Z","76.0042844","0.989941600000009","10.7142857142857","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","77","2026-09-29T01:45:50.8202002Z","77.0060704","1.001786","6.4453125","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","78","2026-09-29T01:45:51.8332638Z","78.0191806","1.0131102","5.76923076923077","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","79","2026-09-29T01:45:52.8299633Z","79.0160211","0.996840500000005","5.2734375","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","80","2026-09-29T01:45:53.8158217Z","80.0018741","0.985852999999992","7.73809523809524","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","81","2026-09-29T01:45:54.8326368Z","81.0188789","1.0170048","7.30769230769231","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","82","2026-09-29T01:45:55.8299564Z","82.0159042","0.997025300000004","19.7265625","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","83","2026-09-29T01:45:56.8992626Z","83.040758","1.0248538","32.6530612244898","0.190575963127618","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","84","2026-09-29T01:45:57.8212419Z","84.0073544","0.9665964","23.6897274633124","0.202062101617593","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","85","2026-09-29T01:45:58.8213728Z","85.0075118","1.00015740000001","17.96875","0.195281762650558","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","86","2026-09-29T01:45:59.8238428Z","86.0098747","1.00236289999999","10.5769230769231","0.194852084010692","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","87","2026-09-29T01:46:00.8249782Z","87.0110942","1.0012195","8.0078125","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","88","2026-09-29T01:46:01.8242898Z","88.0104581","0.999363899999992","10.9375","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","89","2026-09-29T01:46:02.8255183Z","89.0114308","1.00097270000001","7.421875","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","90","2026-09-29T01:46:03.8290937Z","90.0152979","1.00386709999999","5.46875","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","91","2026-09-29T01:46:04.8150543Z","91.0010184","0.985720499999999","5.75396825396825","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","92","2026-09-29T01:46:05.8206358Z","92.0072992","1.0062808","9.375","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","93","2026-09-29T01:46:06.8275797Z","93.0138921","1.0065929","10.3846153846154","0.194033258132458","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","94","2026-09-29T01:46:07.8278337Z","94.0140226","1.0001305","4.1015625","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","95","2026-09-29T01:46:08.8144138Z","95.0004565","0.986433900000009","7.53968253968254","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","96","2026-09-29T01:46:09.8173619Z","96.0033615","1.002905","6.8359375","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","97","2026-09-29T01:46:10.8309004Z","97.0168503","1.0134888","7.30769230769231","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","98","2026-09-29T01:46:11.8204146Z","98.0063707","0.989520399999989","5.75396825396825","0","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","99","2026-09-29T01:46:12.8223745Z","99.0084636","1.00209290000001","16.40625","0.194904584195735","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","100","2026-09-29T01:46:13.8210402Z","100.0071295","0.998665899999992","11.5234375","0.195573414492276","12788","0","0","1.97265625","12.515625","7","176","0","0"
+"1","allow","101","2026-09-29T01:46:14.8198733Z","101.0058863","0.99875680000001","7.421875","0.195555614740243","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","102","2026-09-29T01:46:15.8322845Z","102.0184203","1.01253399999999","6.92307692307692","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","103","2026-09-29T01:46:16.8316676Z","103.0177388","0.999318500000001","5.859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","104","2026-09-29T01:46:17.8283567Z","104.0144184","0.996679600000007","9.5703125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","105","2026-09-29T01:46:18.8269295Z","105.0129537","0.9985353","8.203125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","106","2026-09-29T01:46:19.8247283Z","106.0108122","0.997858499999992","4.4921875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","107","2026-09-29T01:46:20.8212842Z","107.0073287","0.996516500000013","8.13492063492063","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","108","2026-09-29T01:46:21.8223590Z","108.00863","1.00130129999999","12.6953125","0.195058670152532","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","109","2026-09-29T01:46:22.8202555Z","109.0062223","0.997592299999994","9.9609375","0.195783888869232","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","110","2026-09-29T01:46:23.8207912Z","110.0067317","1.0005094","6.0546875","0.195213058468017","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","111","2026-09-29T01:46:24.8331370Z","111.0190754","1.0123437","8.26923076923077","0.192931017400513","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","112","2026-09-29T01:46:25.8336677Z","112.0196395","1.00056410000001","6.25","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","113","2026-09-29T01:46:26.8192507Z","113.005207","0.985567500000002","5.55555555555556","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","114","2026-09-29T01:46:27.8327670Z","114.0187476","1.0135406","5.57692307692308","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","115","2026-09-29T01:46:28.8200416Z","115.0063012","0.987553599999998","9.32539682539683","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","116","2026-09-29T01:46:29.8185217Z","116.0045131","0.998211900000001","6.25","0.195662363872841","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","117","2026-09-29T01:46:30.8304399Z","117.016512","1.01199889999999","5.38461538461539","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","118","2026-09-29T01:46:31.8156181Z","118.0013971","0.9848851","4.96031746031746","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","119","2026-09-29T01:46:32.8282845Z","119.0143369","1.0129398","5.96153846153846","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","120","2026-09-29T01:46:33.8255508Z","120.0117286","0.997391700000009","11.71875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","121","2026-09-29T01:46:34.8294369Z","121.015502","1.0037734","3.515625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","122","2026-09-29T01:46:35.8269063Z","122.0128831","0.997381099999998","4.8828125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","123","2026-09-29T01:46:36.8234781Z","123.0096922","0.996809099999993","13.8671875","0.195937717663293","12788","0.015625","0.195937717663293","1.9140625","12.4921875","5","174","0","0"
+"1","allow","124","2026-09-29T01:46:37.8206714Z","124.0067917","0.997099500000004","16.8650793650794","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","125","2026-09-29T01:46:38.8324488Z","125.0185253","1.0117336","13.6538461538462","0.193047359502541","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","126","2026-09-29T01:46:39.8190182Z","126.0053185","0.986793200000008","5.95238095238095","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","127","2026-09-29T01:46:40.8211696Z","127.0071752","1.00185669999999","7.421875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","128","2026-09-29T01:46:41.8248080Z","128.0108556","1.00368039999999","17.6923076923077","0.194596307748962","12788","0.015625","0.194596307748962","1.9140625","12.4921875","5","174","0","0"
+"1","allow","129","2026-09-29T01:46:42.8334151Z","129.0189828","1.00812720000002","5.859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","130","2026-09-29T01:46:43.8331380Z","130.019318","1.00033519999999","5.46875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","131","2026-09-29T01:46:44.8307485Z","131.0167073","0.997389300000009","3.90625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","132","2026-09-29T01:46:45.8260767Z","132.0120679","0.995360599999998","13.671875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","133","2026-09-29T01:46:46.8268580Z","133.0129937","1.00092579999998","5.46875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","134","2026-09-29T01:46:47.8250010Z","134.0112331","0.998239400000017","6.25","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","135","2026-09-29T01:46:48.8290650Z","135.015093","1.00385990000001","7.6171875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","136","2026-09-29T01:46:49.8147900Z","136.0007566","0.985663599999981","8.73015873015873","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","137","2026-09-29T01:46:50.8141864Z","137.000193","0.999436400000008","5.0880626223092","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","138","2026-09-29T01:46:51.8180800Z","138.0042903","1.00409729999998","5.45808966861598","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","139","2026-09-29T01:46:52.8291956Z","139.0151653","1.01087500000003","6.34615384615385","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","140","2026-09-29T01:46:53.8286877Z","140.01474","0.999574699999982","7.6171875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","141","2026-09-29T01:46:54.8270411Z","141.0131003","0.998360300000002","5.46875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","142","2026-09-29T01:46:55.8255229Z","142.0115288","0.998428500000017","4.8828125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","143","2026-09-29T01:46:56.8301852Z","143.0165374","1.0050086","5.859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","144","2026-09-29T01:46:57.8158748Z","144.0019342","0.98539679999999","7.53968253968254","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","145","2026-09-29T01:46:58.8348644Z","145.0204294","1.01849519999999","10.9615384615385","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","146","2026-09-29T01:46:59.8332539Z","146.0193391","0.998909700000013","6.8359375","0.195525681650701","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","147","2026-09-29T01:47:00.8316479Z","147.0176048","0.99826569999999","6.0546875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","148","2026-09-29T01:47:01.8202996Z","148.0064185","0.988813700000009","5.55555555555556","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","149","2026-09-29T01:47:02.8339705Z","149.0201599","1.01374139999999","26.1538461538462","0.192665012990495","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","150","2026-09-29T01:47:03.8187265Z","150.0047231","0.984563200000025","5.36779324055666","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","151","2026-09-29T01:47:04.8223754Z","151.0083614","1.00363829999998","7.40740740740741","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","152","2026-09-29T01:47:05.8244450Z","152.010502","1.00214060000002","13.4615384615385","0.194895307105606","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","153","2026-09-29T01:47:06.8266915Z","153.0127075","1.0022055","13.28125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","154","2026-09-29T01:47:07.8144899Z","154.0004334","0.987725899999987","7.73809523809524","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","155","2026-09-29T01:47:08.8238225Z","155.0098752","1.00944179999999","4.42307692307692","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","156","2026-09-29T01:47:09.8227624Z","156.0088227","0.998947500000014","17.8571428571429","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","157","2026-09-29T01:47:10.8228961Z","157.0089168","1.00009409999998","11.9140625","0.195294122823045","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","158","2026-09-29T01:47:11.8212966Z","158.0073173","0.998400500000002","7.8125","0.195625402831829","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","159","2026-09-29T01:47:12.8196967Z","159.0056788","0.998361500000016","9.5703125","0.19563304474381","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","160","2026-09-29T01:47:13.8191323Z","160.0050573","0.999378500000006","8.203125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","161","2026-09-29T01:47:14.8186654Z","161.0046766","0.999619299999978","5.46875","0.195386883786662","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","162","2026-09-29T01:47:15.8325326Z","162.0184812","1.01380460000001","16.5384615384615","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","163","2026-09-29T01:47:16.8199455Z","163.0059131","0.98743189999999","5.95238095238095","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","164","2026-09-29T01:47:17.8196877Z","164.0056945","0.999781400000018","7.421875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","165","2026-09-29T01:47:18.8348087Z","165.0203917","1.0146972","6.15384615384615","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","166","2026-09-29T01:47:19.8338782Z","166.0197965","0.999404799999979","9.1796875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","167","2026-09-29T01:47:20.8315426Z","167.0175181","0.997721600000006","7.2265625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","168","2026-09-29T01:47:21.8208517Z","168.0069046","0.989386499999995","7.93650793650794","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","169","2026-09-29T01:47:22.8245768Z","169.0105175","1.00361290000001","12.1153846153846","0.194609395714223","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","170","2026-09-29T01:47:23.8232372Z","170.0098903","0.999372800000003","13.0859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","171","2026-09-29T01:47:24.8209993Z","171.0069185","0.997028199999988","29.7619047619048","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","172","2026-09-29T01:47:25.8276461Z","172.0136304","1.0067119","39.2307692307692","0.19401032211897","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","173","2026-09-29T01:47:26.8247490Z","173.010752","0.997121600000014","14.84375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","174","2026-09-29T01:47:27.8209983Z","174.0070007","0.996248699999995","11.1111111111111","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","175","2026-09-29T01:47:28.8229974Z","175.0091385","1.00213780000001","19.921875","0.194895851648343","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","176","2026-09-29T01:47:29.8211499Z","176.0072325","0.99809399999998","18.359375","0.195685476518248","12788","0.015625","0.195685476518248","1.9140625","12.4921875","5","174","0","0"
+"1","allow","177","2026-09-29T01:47:30.8230977Z","177.0090351","1.00180260000002","9.9609375","0.194961063187495","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","178","2026-09-29T01:47:31.8229811Z","178.0090167","0.999981599999984","12.109375","0.195316093816129","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","179","2026-09-29T01:47:32.8294482Z","179.0154331","1.00641640000001","6.34615384615385","0.194067286661862","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","180","2026-09-29T01:47:33.8289440Z","180.0149372","0.999504099999996","10.3515625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","181","2026-09-29T01:47:34.8161081Z","181.0021988","0.987261600000011","7.53968253968254","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","182","2026-09-29T01:47:35.8326884Z","182.0187579","1.01655909999999","6.15384615384615","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","183","2026-09-29T01:47:36.8338873Z","183.0199792","1.0012213","5.078125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","184","2026-09-29T01:47:37.8309694Z","184.017531","0.997551799999997","7.03125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","185","2026-09-29T01:47:38.8332897Z","185.0191861","1.00165509999999","6.8359375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","186","2026-09-29T01:47:39.8186745Z","186.0047864","0.985600300000016","8.53174603174603","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","187","2026-09-29T01:47:40.8212348Z","187.0072906","1.0025042","6.0546875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","188","2026-09-29T01:47:41.8221188Z","188.008287","1.00099639999999","11.9140625","0.195118084340765","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","189","2026-09-29T01:47:42.8210388Z","189.0069578","0.998670799999985","5.859375","0.195572454907065","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","190","2026-09-29T01:47:43.8237931Z","190.0098011","1.00284330000002","14.0655105973025","0.194758742467537","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","191","2026-09-29T01:47:44.8271717Z","191.0128156","1.00301449999998","6.04288499025341","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","192","2026-09-29T01:47:45.8299433Z","192.0155194","1.00270380000001","5.859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","193","2026-09-29T01:47:46.8256884Z","193.0117843","0.9962649","4.6875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","194","2026-09-29T01:47:47.8146700Z","194.0006878","0.988903499999992","6.34920634920635","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","195","2026-09-29T01:47:48.8146507Z","195.0012628","1.000575","3.90625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","196","2026-09-29T01:47:49.8284588Z","196.0145017","1.0132389","12.3076923076923","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","197","2026-09-29T01:47:50.8282075Z","197.0141804","0.999678700000004","5.6640625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","198","2026-09-29T01:47:51.8242772Z","198.0103749","0.996194500000001","9.765625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","199","2026-09-29T01:47:52.8235682Z","199.0096656","0.999290699999989","7.8125","0.195451133488986","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","200","2026-09-29T01:47:53.8242737Z","200.0102289","1.00056330000001","8.6105675146771","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","201","2026-09-29T01:47:54.8299291Z","201.0159255","1.00569659999999","5.65302144249513","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","202","2026-09-29T01:47:55.8155920Z","202.0016228","0.985697299999998","5.75396825396825","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","203","2026-09-29T01:47:56.8220943Z","203.0080578","1.00643500000001","5.46875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","204","2026-09-29T01:47:57.8227109Z","204.00869","1.00063220000001","8.984375","0.195189101450061","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","205","2026-09-29T01:47:58.8216006Z","205.0075552","0.998865199999983","6.640625","0.195534392428531","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","206","2026-09-29T01:47:59.8200049Z","206.0060287","0.998473500000017","10.546875","0.195611100344673","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","207","2026-09-29T01:48:00.8198685Z","207.0058383","0.999809599999992","6.8359375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","208","2026-09-29T01:48:01.8328407Z","208.0188136","1.01297529999999","8.26923076923077","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","209","2026-09-29T01:48:02.8192700Z","209.0054253","0.986611699999997","4.76190476190476","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","210","2026-09-29T01:48:03.8272305Z","210.0132933","1.007868","7.88461538461539","0.193787777764548","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","211","2026-09-29T01:48:04.8258934Z","211.011854","0.998560700000013","5.859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","212","2026-09-29T01:48:05.8295225Z","212.0156504","1.0037964","6.8359375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","213","2026-09-29T01:48:06.8175137Z","213.003628","0.987977599999994","7.73809523809524","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","214","2026-09-29T01:48:07.8211578Z","214.0071267","1.00349869999999","7.421875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","215","2026-09-29T01:48:08.8336482Z","215.0196221","1.01249540000001","7.11538461538461","0.192902110962676","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","216","2026-09-29T01:48:09.8303697Z","216.0163106","0.996688500000005","8.984375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","217","2026-09-29T01:48:10.8256570Z","217.0117888","0.99547819999998","8.0078125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","218","2026-09-29T01:48:11.8261293Z","218.0122064","1.00041760000002","7.2265625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","219","2026-09-29T01:48:12.8239354Z","219.0098882","0.997681799999981","9.9609375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","220","2026-09-29T01:48:13.8223455Z","220.0078289","0.997940700000015","24.0079365079365","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","221","2026-09-29T01:48:14.8333622Z","221.0193877","1.01155879999999","31.7307692307692","0.193080718589964","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","222","2026-09-29T01:48:15.8299383Z","222.0161249","0.996737200000013","6.4453125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","223","2026-09-29T01:48:16.8148219Z","223.0004449","0.984319999999997","6.34920634920635","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","224","2026-09-29T01:48:17.8281210Z","224.0140276","1.0135827","8.07692307692308","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","225","2026-09-29T01:48:18.8170261Z","225.0029409","0.988913300000007","7.14285714285714","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","226","2026-09-29T01:48:19.8272167Z","226.0131012","1.0101603","17.8846153846154","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","227","2026-09-29T01:48:20.8286399Z","227.0146702","1.00156899999999","6.8359375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","228","2026-09-29T01:48:21.8152506Z","228.0012464","0.986576200000002","9.72222222222222","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","229","2026-09-29T01:48:22.8160328Z","229.0020294","1.00078300000001","5.46875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","230","2026-09-29T01:48:23.8329863Z","230.0189716","1.01694219999999","4.61538461538461","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","231","2026-09-29T01:48:24.8307212Z","231.0167744","0.997802800000017","5.859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","232","2026-09-29T01:48:25.8212288Z","232.0072888","0.990514399999995","8.92857142857143","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","233","2026-09-29T01:48:26.8197566Z","233.0058211","0.998532299999994","7.421875","0.195599581505777","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","234","2026-09-29T01:48:27.8309859Z","234.0169604","1.0111393","5.38461538461539","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","235","2026-09-29T01:48:28.8309729Z","235.016856","0.999895600000002","6.8359375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","236","2026-09-29T01:48:29.8144054Z","236.0004786","0.98362259999999","6.94444444444444","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","237","2026-09-29T01:48:30.8292408Z","237.0147321","1.01425350000002","6.73076923076923","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","238","2026-09-29T01:48:31.8171263Z","238.0032051","0.988472999999999","5.55555555555556","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","239","2026-09-29T01:48:32.8186443Z","239.0046835","1.0014784","4.4921875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","240","2026-09-29T01:48:33.8195747Z","240.0057751","1.0010916","8.7890625","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","241","2026-09-29T01:48:34.8187416Z","241.0048749","0.999099799999982","12.109375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","242","2026-09-29T01:48:35.8325330Z","242.0184863","1.0136114","6.9364161849711","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","243","2026-09-29T01:48:36.8320256Z","243.0176747","0.999188400000008","7.40740740740741","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","244","2026-09-29T01:48:37.8285524Z","244.0146697","0.996994999999998","5.859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","245","2026-09-29T01:48:38.8311471Z","245.0171997","1.00253000000001","5.859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","246","2026-09-29T01:48:39.8305510Z","246.01654","0.9993403","4.6875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","247","2026-09-29T01:48:40.8186333Z","247.0045935","0.988053500000007","10.9126984126984","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","248","2026-09-29T01:48:41.8200714Z","248.0060254","1.0014319","8.0078125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","249","2026-09-29T01:48:42.8188852Z","249.0049999","0.998974500000003","7.6171875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","250","2026-09-29T01:48:43.8186643Z","250.0046349","0.999634999999984","5.078125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","251","2026-09-29T01:48:44.8224300Z","251.0085557","1.0039208","6.8359375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","252","2026-09-29T01:48:45.8263702Z","252.012499","1.0039433","10","0.19454534932401","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","253","2026-09-29T01:48:46.8143460Z","253.0004885","0.987989499999998","7.14285714285714","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","254","2026-09-29T01:48:47.8186504Z","254.0046216","1.00413309999999","4.296875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","255","2026-09-29T01:48:48.8331569Z","255.0191358","1.01451420000001","5.76923076923077","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","256","2026-09-29T01:48:49.8195418Z","256.0057687","0.986632899999989","7.14285714285714","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","257","2026-09-29T01:48:50.8335931Z","257.0195484","1.01377969999999","8.46153846153846","0.192657734219774","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","258","2026-09-29T01:48:51.8312198Z","258.0172153","0.997666900000013","6.0546875","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","259","2026-09-29T01:48:52.8227253Z","259.0081624","0.990947100000028","6.54761904761905","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","260","2026-09-29T01:48:53.8283915Z","260.0144852","1.00632279999996","10.1923076923077","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","261","2026-09-29T01:48:54.8188160Z","261.0049262","0.990441000000033","3.96825396825397","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","262","2026-09-29T01:48:55.8328400Z","262.0188041","1.01387790000001","7.88461538461539","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","263","2026-09-29T01:48:56.8212973Z","263.007401","0.988596900000005","5.95238095238095","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","264","2026-09-29T01:48:57.8249242Z","264.0110643","1.00366329999997","9.03846153846154","0.194599623200336","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","265","2026-09-29T01:48:58.8246580Z","265.0107699","0.999705600000027","13.0859375","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","266","2026-09-29T01:48:59.8268963Z","266.0131832","1.0024133","6.4453125","0","12788","0","0","1.9140625","12.4921875","5","174","0","0"
+"1","allow","267","2026-09-29T01:49:00.8174500Z","267.0034315","0.990248299999962","8.53174603174603","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","268","2026-09-29T01:49:01.8321648Z","268.0182","1.0147685","6.34615384615385","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","269","2026-09-29T01:49:02.8327955Z","269.0185213","1.0003213","5.859375","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","270","2026-09-29T01:49:03.8313536Z","270.0172822","0.998760900000036","7.421875","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","271","2026-09-29T01:49:04.8145560Z","271.0006674","0.983385199999987","5.75396825396825","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","272","2026-09-29T01:49:05.8166316Z","272.0025629","1.00189549999999","6.640625","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","273","2026-09-29T01:49:06.8332859Z","273.0192409","1.01667800000001","7.69230769230769","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","274","2026-09-29T01:49:07.8228984Z","274.0090105","0.989769599999988","7.93650793650794","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","275","2026-09-29T01:49:08.8253788Z","275.0115613","1.00255079999999","13.2692307692308","0.194815564458181","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","276","2026-09-29T01:49:09.8286774Z","276.0146912","1.00312990000003","7.03125","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","277","2026-09-29T01:49:10.8245010Z","277.010686","0.995994799999949","8.0078125","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","278","2026-09-29T01:49:11.8288228Z","278.0148034","1.00411740000004","10.15625","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","279","2026-09-29T01:49:12.8274579Z","279.013405","0.998601599999972","8.59375","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","280","2026-09-29T01:49:13.8247533Z","280.0108657","0.997460700000033","13.8671875","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","281","2026-09-29T01:49:14.8322237Z","281.0181733","1.00730759999999","4.4921875","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","282","2026-09-29T01:49:15.8338172Z","282.0198837","1.00171039999998","5.46875","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","283","2026-09-29T01:49:16.8337936Z","283.0198197","0.999935999999991","15.0390625","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","284","2026-09-29T01:49:17.8297075Z","284.0156187","0.995799000000034","36.5234375","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","285","2026-09-29T01:49:18.8237835Z","285.0098164","0.994197699999972","25","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","286","2026-09-29T01:49:19.8228678Z","286.0088788","0.999062400000014","19.8412698412698","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","287","2026-09-29T01:49:20.8274287Z","287.0134404","1.00456159999999","11.3461538461538","0.194425608145884","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","288","2026-09-29T01:49:21.8255179Z","288.0115905","0.998150100000032","7.8125","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","289","2026-09-29T01:49:22.8147839Z","289.000832","0.989241499999991","6.74603174603175","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","290","2026-09-29T01:49:23.8201370Z","290.0063005","1.00546850000001","6.25","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","291","2026-09-29T01:49:24.8225791Z","291.0085932","1.0022927","7.03125","0.194865731337762","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","292","2026-09-29T01:49:25.8216671Z","292.007642","0.999048799999969","11.9140625","0.195498458133383","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","293","2026-09-29T01:49:26.8239635Z","293.0101238","1.0024818","8.46153846153846","0.194828973453683","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","294","2026-09-29T01:49:27.8260835Z","294.0123006","1.00217680000003","9.375","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","295","2026-09-29T01:49:28.8244943Z","295.0110506","0.998749999999973","10.546875","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","296","2026-09-29T01:49:29.8274681Z","296.0135635","1.0025129","6.8359375","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","297","2026-09-29T01:49:30.8189353Z","297.0050425","0.991479000000027","7.93650793650794","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","298","2026-09-29T01:49:31.8241303Z","298.010117","1.00507449999998","14.0384615384615","0.194326390730244","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","299","2026-09-29T01:49:32.8246484Z","299.010722","1.00060500000001","8.59375","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
+"1","allow","300","2026-09-29T01:49:33.8289545Z","300.0151189","1.00439690000002","5.6640625","0","12788","0","0","1.9765625","12.66796875","7","174","0","0"
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-baseline.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-baseline.csv
new file mode 100644
index 0000000..c52aacc
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-baseline.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"1","baseline","1","2026-09-29T01:39:01.6594568Z","1.0082794","1.0070755","6.92307692307692","0","","","","","","","","",""
+"1","baseline","2","2026-09-29T01:39:02.6522932Z","2.0055282","0.9972488","10.3515625","0","","","","","","","","",""
+"1","baseline","3","2026-09-29T01:39:03.6552279Z","3.0078493","1.0023211","9.1796875","0","","","","","","","","",""
+"1","baseline","4","2026-09-29T01:39:04.6574935Z","4.0107926","1.0029433","5.6640625","0","","","","","","","","",""
+"1","baseline","5","2026-09-29T01:39:05.6568503Z","5.0097384","0.9989458","8.984375","0","","","","","","","","",""
+"1","baseline","6","2026-09-29T01:39:06.6564909Z","6.0098175","1.0000791","7.2265625","0","","","","","","","","",""
+"1","baseline","7","2026-09-29T01:39:07.6715114Z","7.0248178","1.0150003","5.19230769230769","0","","","","","","","","",""
+"1","baseline","8","2026-09-29T01:39:08.6528507Z","8.0061119","0.9812941","5.15873015873016","0","","","","","","","","",""
+"1","baseline","9","2026-09-29T01:39:09.6502458Z","9.0034491","0.997337199999999","14.0873015873016","0","","","","","","","","",""
+"1","baseline","10","2026-09-29T01:39:10.6561449Z","10.0095025","1.0060534","24.6153846153846","0","","","","","","","","",""
+"1","baseline","11","2026-09-29T01:39:11.6487899Z","11.0020668","0.9925643","35.3174603174603","0","","","","","","","","",""
+"1","baseline","12","2026-09-29T01:39:12.6472993Z","12.0005746","0.998507800000001","15.8203125","0","","","","","","","","",""
+"1","baseline","13","2026-09-29T01:39:13.6585331Z","13.0117713","1.0111967","12.8846153846154","0","","","","","","","","",""
+"1","baseline","14","2026-09-29T01:39:14.6599908Z","14.0133746","1.0016033","7.8125","0","","","","","","","","",""
+"1","baseline","15","2026-09-29T01:39:15.6472683Z","15.0005802","0.987205600000001","4.36507936507936","0","","","","","","","","",""
+"1","baseline","16","2026-09-29T01:39:16.6593881Z","16.0126579","1.0120777","4.42307692307692","0","","","","","","","","",""
+"1","baseline","17","2026-09-29T01:39:17.6565448Z","17.0099082","0.997250299999997","7.421875","1.37095722107078","","","","","","","","",""
+"1","baseline","18","2026-09-29T01:39:18.6615440Z","18.0143141","1.0044059","7.8125","0","","","","","","","","",""
+"1","baseline","19","2026-09-29T01:39:19.6478395Z","19.0011373","0.9868232","6.54761904761905","0","","","","","","","","",""
+"1","baseline","20","2026-09-29T01:39:20.6482687Z","20.0014386","1.0003013","7.03125","0","","","","","","","","",""
+"1","baseline","21","2026-09-29T01:39:21.6525888Z","21.0057626","1.004324","11.9230769230769","0","","","","","","","","",""
+"1","baseline","22","2026-09-29T01:39:22.6514144Z","22.0047037","0.9989411","15.6746031746032","0","","","","","","","","",""
+"1","baseline","23","2026-09-29T01:39:23.6527574Z","23.0059817","1.001278","12.3314065510597","0.195063209218619","","","","","","","","",""
+"1","baseline","24","2026-09-29T01:39:24.6622677Z","24.0155167","1.009535","7.01754385964912","0","","","","","","","","",""
+"1","baseline","25","2026-09-29T01:39:25.6572556Z","25.01045","0.9949333","7.421875","0","","","","","","","","",""
+"1","baseline","26","2026-09-29T01:39:26.6572477Z","26.0106508","1.0002008","6.25","0","","","","","","","","",""
+"1","baseline","27","2026-09-29T01:39:27.6580745Z","27.011264","1.0006132","6.640625","0","","","","","","","","",""
+"1","baseline","28","2026-09-29T01:39:28.6543034Z","28.0074994","0.996235400000003","4.6875","0","","","","","","","","",""
+"1","baseline","29","2026-09-29T01:39:29.6525914Z","29.0057632","0.998263799999997","12.109375","0","","","","","","","","",""
+"1","baseline","30","2026-09-29T01:39:30.6541161Z","30.0074088","1.0016456","6.8359375","0","","","","","","","","",""
+"1","baseline","31","2026-09-29T01:39:31.6516445Z","31.004555","0.9971462","8.73015873015873","0","","","","","","","","",""
+"1","baseline","32","2026-09-29T01:39:32.6486186Z","32.0017803","0.9972253","11.1328125","0.195855941480827","","","","","","","","",""
+"1","baseline","33","2026-09-29T01:39:33.6508200Z","33.0040629","1.0022826","14.453125","0","","","","","","","","",""
+"1","baseline","34","2026-09-29T01:39:34.6531946Z","34.0064233","1.0023604","10.1923076923077","0","","","","","","","","",""
+"1","baseline","35","2026-09-29T01:39:35.6509344Z","35.004295","0.997871699999997","11.5079365079365","0","","","","","","","","",""
+"1","baseline","36","2026-09-29T01:39:36.6542420Z","36.0074512","1.0031562","12.3076923076923","0.194697994190735","","","","","","","","",""
+"1","baseline","37","2026-09-29T01:39:37.6556256Z","37.0088639","1.0014127","6.4453125","0","","","","","","","","",""
+"1","baseline","38","2026-09-29T01:39:38.6606863Z","38.0140038","1.0051399","4.296875","0","","","","","","","","",""
+"1","baseline","39","2026-09-29T01:39:39.6598125Z","39.0131174","0.999113600000001","11.71875","0","","","","","","","","",""
+"1","baseline","40","2026-09-29T01:39:40.6513400Z","40.0048309","0.991713499999996","9.43025540275049","0.196944480437143","","","","","","","","",""
+"1","baseline","41","2026-09-29T01:39:41.6492209Z","41.002405","0.997574100000001","13.2149901380671","0","","","","","","","","",""
+"1","baseline","42","2026-09-29T01:39:42.6543913Z","42.0077284","1.0053234","12.6923076923077","0","","","","","","","","",""
+"1","baseline","43","2026-09-29T01:39:43.6547835Z","43.0081417","1.0004133","9.375","0","","","","","","","","",""
+"1","baseline","44","2026-09-29T01:39:44.6620303Z","44.0153683","1.0072266","8.7890625","0","","","","","","","","",""
+"1","baseline","45","2026-09-29T01:39:45.6472738Z","45.0004606","0.985092299999998","6.15079365079365","0","","","","","","","","",""
+"1","baseline","46","2026-09-29T01:39:46.6560170Z","46.0093398","1.0088792","8.46153846153846","0","","","","","","","","",""
+"1","baseline","47","2026-09-29T01:39:47.6580363Z","47.0113663","1.0020265","22.265625","0","","","","","","","","",""
+"1","baseline","48","2026-09-29T01:39:48.6592975Z","48.0120891","1.0007228","7.421875","0","","","","","","","","",""
+"1","baseline","49","2026-09-29T01:39:49.6498341Z","49.0031095","0.991020400000004","8.13492063492063","0","","","","","","","","",""
+"1","baseline","50","2026-09-29T01:39:50.6493221Z","50.0027789","0.999669399999995","7.2265625","0","","","","","","","","",""
+"1","baseline","51","2026-09-29T01:39:51.6523652Z","51.0055365","1.0027576","8.84615384615385","0","","","","","","","","",""
+"1","baseline","52","2026-09-29T01:39:52.6565923Z","52.0101232","1.0045867","10.9375","0","","","","","","","","",""
+"1","baseline","53","2026-09-29T01:39:53.6577898Z","53.0110461","1.0009229","7.03125","0","","","","","","","","",""
+"1","baseline","54","2026-09-29T01:39:54.6619713Z","54.0152465","1.0042004","6.4453125","0","","","","","","","","",""
+"1","baseline","55","2026-09-29T01:39:55.6620079Z","55.0154029","1.0001564","8.3984375","0","","","","","","","","",""
+"1","baseline","56","2026-09-29T01:39:56.6613940Z","56.0147422","0.999339300000003","6.640625","0","","","","","","","","",""
+"1","baseline","57","2026-09-29T01:39:57.6604653Z","57.0132261","0.998483899999997","7.2265625","0","","","","","","","","",""
+"1","baseline","58","2026-09-29T01:39:58.6510058Z","58.0041926","0.990966499999999","35.9126984126984","0","","","","","","","","",""
+"1","baseline","59","2026-09-29T01:39:59.6494152Z","59.0027287","0.998536100000003","27.5390625","0","","","","","","","","",""
+"1","baseline","60","2026-09-29T01:40:00.6608508Z","60.0143449","1.0116162","17.6923076923077","0","","","","","","","","",""
+"1","baseline","61","2026-09-29T01:40:01.6467544Z","61.0000578","0.985712900000003","8.73015873015873","0","","","","","","","","",""
+"1","baseline","62","2026-09-29T01:40:02.6513033Z","62.0045192","1.0044614","6.0546875","0","","","","","","","","",""
+"1","baseline","63","2026-09-29T01:40:03.6571614Z","63.0105917","1.0060725","15.5769230769231","0.194133623570866","","","","","","","","",""
+"1","baseline","64","2026-09-29T01:40:04.6516104Z","64.0049428","0.994351099999996","12.37721021611","0.196422068623448","","","","","","","","",""
+"1","baseline","65","2026-09-29T01:40:05.6559392Z","65.0094187","1.0044759","8.3495145631068","0","","","","","","","","",""
+"1","baseline","66","2026-09-29T01:40:06.6576867Z","66.0110198","1.0016011","6.4453125","0","","","","","","","","",""
+"1","baseline","67","2026-09-29T01:40:07.6583174Z","67.0116935","1.00067369999999","5.2734375","0","","","","","","","","",""
+"1","baseline","68","2026-09-29T01:40:08.6591696Z","68.0126318","1.0009383","7.8125","0","","","","","","","","",""
+"1","baseline","69","2026-09-29T01:40:09.6562882Z","69.0095146","0.996882800000009","4.6875","0","","","","","","","","",""
+"1","baseline","70","2026-09-29T01:40:10.6589784Z","70.0121772","1.00266259999999","5.68627450980392","0","","","","","","","","",""
+"1","baseline","71","2026-09-29T01:40:11.6570745Z","71.0105536","0.998376399999998","7.19844357976654","0","","","","","","","","",""
+"1","baseline","72","2026-09-29T01:40:12.6615922Z","72.0149097","1.0043561","6.0546875","0","","","","","","","","",""
+"1","baseline","73","2026-09-29T01:40:13.6622878Z","73.0156202","1.00071050000001","4.4921875","0","","","","","","","","",""
+"1","baseline","74","2026-09-29T01:40:14.6499791Z","74.0032408","0.9876206","8.53174603174603","0","","","","","","","","",""
+"1","baseline","75","2026-09-29T01:40:15.6524439Z","75.0056244","1.0023836","12.1153846153846","0","","","","","","","","",""
+"1","baseline","76","2026-09-29T01:40:16.6567665Z","76.0100867","1.0044623","7.421875","0","","","","","","","","",""
+"1","baseline","77","2026-09-29T01:40:17.6597398Z","77.0131428","1.00305609999999","4.8828125","0","","","","","","","","",""
+"1","baseline","78","2026-09-29T01:40:18.6487646Z","78.0016418","0.988499000000004","6.15079365079365","0","","","","","","","","",""
+"1","baseline","79","2026-09-29T01:40:19.6510197Z","79.0044529","1.00281109999999","9.765625","0","","","","","","","","",""
+"1","baseline","80","2026-09-29T01:40:20.6483263Z","80.001858","0.997405100000009","12.890625","0","","","","","","","","",""
+"1","baseline","81","2026-09-29T01:40:21.6490378Z","81.0021981","1.0003401","6.640625","0","","","","","","","","",""
+"1","baseline","82","2026-09-29T01:40:22.6487136Z","82.0018878","0.99968969999999","5.67514677103718","0","","","","","","","","",""
+"1","baseline","83","2026-09-29T01:40:23.6490185Z","83.0022553","1.00036750000001","6.82261208576998","0","","","","","","","","",""
+"1","baseline","84","2026-09-29T01:40:24.6505677Z","84.003814","1.00155869999999","12.5","0","","","","","","","","",""
+"1","baseline","85","2026-09-29T01:40:25.6497634Z","85.0030412","0.999227200000007","9.5703125","0","","","","","","","","",""
+"1","baseline","86","2026-09-29T01:40:26.6472840Z","86.0007865","0.997745299999991","11.9140625","0","","","","","","","","",""
+"1","baseline","87","2026-09-29T01:40:27.6613162Z","87.0145509","1.0137644","5.96153846153846","0","","","","","","","","",""
+"1","baseline","88","2026-09-29T01:40:28.6614175Z","88.0147895","1.0002386","5.6640625","0","","","","","","","","",""
+"1","baseline","89","2026-09-29T01:40:29.6482561Z","89.0013867","0.986597200000006","4.76190476190476","0","","","","","","","","",""
+"1","baseline","90","2026-09-29T01:40:30.6522424Z","90.0054542","1.0040675","11.7307692307692","0.38904256934917","","","","","","","","",""
+"1","baseline","91","2026-09-29T01:40:31.6515333Z","91.0047235","0.999269299999995","9.46745562130178","0.195455319201742","","","","","","","","",""
+"1","baseline","92","2026-09-29T01:40:32.6517717Z","92.0050089","1.0002854","10.6382978723404","0","","","","","","","","",""
+"1","baseline","93","2026-09-29T01:40:33.6532003Z","93.006435","1.0014261","9.98043052837573","0","","","","","","","","",""
+"1","baseline","94","2026-09-29T01:40:34.6554018Z","94.0086977","1.0022627","7.21247563352826","0","","","","","","","","",""
+"1","baseline","95","2026-09-29T01:40:35.6553473Z","95.0085562","0.999858500000002","7.03125","0","","","","","","","","",""
+"1","baseline","96","2026-09-29T01:40:36.6611212Z","96.0143328","1.00577659999999","6.8359375","0","","","","","","","","",""
+"1","baseline","97","2026-09-29T01:40:37.6475318Z","97.001004","0.986671200000004","7.14285714285714","0","","","","","","","","",""
+"1","baseline","98","2026-09-29T01:40:38.6532012Z","98.0064497","1.0054457","6.73076923076923","0","","","","","","","","",""
+"1","baseline","99","2026-09-29T01:40:39.6521449Z","99.0054653","0.999015600000007","7.03125","0","","","","","","","","",""
+"1","baseline","100","2026-09-29T01:40:40.6549013Z","100.0080644","1.0025991","11.1328125","0","","","","","","","","",""
+"1","baseline","101","2026-09-29T01:40:41.6569690Z","101.0102805","1.0022161","5.6640625","0","","","","","","","","",""
+"1","baseline","102","2026-09-29T01:40:42.6550222Z","102.0083951","0.998114600000008","5.078125","0","","","","","","","","",""
+"1","baseline","103","2026-09-29T01:40:43.6522454Z","103.0054574","0.997062299999996","6.25","0","","","","","","","","",""
+"1","baseline","104","2026-09-29T01:40:44.6515128Z","104.0047789","0.999321499999994","22.4409448818898","0.195445109506802","","","","","","","","",""
+"1","baseline","105","2026-09-29T01:40:45.6554636Z","105.0088715","1.00409260000001","6.0077519379845","0","","","","","","","","",""
+"1","baseline","106","2026-09-29T01:40:46.6512032Z","106.0043779","0.995506399999996","9.52380952380952","0","","","","","","","","",""
+"1","baseline","107","2026-09-29T01:40:47.6511629Z","107.0044642","1.00008630000001","10.546875","0.19529564598575","","","","","","","","",""
+"1","baseline","108","2026-09-29T01:40:48.6582158Z","108.0114028","1.0069386","9.80769230769231","0.19396664305053","","","","","","","","",""
+"1","baseline","109","2026-09-29T01:40:49.6585333Z","109.0118613","1.00045849999999","5.2734375","0","","","","","","","","",""
+"1","baseline","110","2026-09-29T01:40:50.6613275Z","110.0145709","1.0027096","6.640625","0","","","","","","","","",""
+"1","baseline","111","2026-09-29T01:40:51.6463933Z","110.9995062","0.984935300000004","9.92063492063492","0","","","","","","","","",""
+"1","baseline","112","2026-09-29T01:40:52.6596368Z","112.0128171","1.01331089999999","11.7307692307692","0","","","","","","","","",""
+"1","baseline","113","2026-09-29T01:40:53.6572064Z","113.0105197","0.997702599999997","8.203125","0","","","","","","","","",""
+"1","baseline","114","2026-09-29T01:40:54.6571288Z","114.0103047","0.999785000000003","15.4296875","0","","","","","","","","",""
+"1","baseline","115","2026-09-29T01:40:55.6522484Z","115.005455","0.995150300000006","27.34375","0","","","","","","","","",""
+"1","baseline","116","2026-09-29T01:40:56.6555121Z","116.0086693","1.0032143","5.859375","0","","","","","","","","",""
+"1","baseline","117","2026-09-29T01:40:57.6583842Z","117.0116613","1.00299200000001","8.7890625","0","","","","","","","","",""
+"1","baseline","118","2026-09-29T01:40:58.6536252Z","118.0068049","0.995143599999992","13.671875","0","","","","","","","","",""
+"1","baseline","119","2026-09-29T01:40:59.6496137Z","119.0029158","0.996110900000005","16.6666666666667","0","","","","","","","","",""
+"1","baseline","120","2026-09-29T01:41:00.6596089Z","120.0125099","1.0095941","12.3076923076923","0","","","","","","","","",""
+"1","baseline","121","2026-09-29T01:41:01.6587969Z","121.0120616","0.999551699999998","13.28125","0","","","","","","","","",""
+"1","baseline","122","2026-09-29T01:41:02.6570458Z","122.0104056","0.998344000000003","6.25","0","","","","","","","","",""
+"1","baseline","123","2026-09-29T01:41:03.6548089Z","123.007975","0.997569399999989","8.7890625","0","","","","","","","","",""
+"1","baseline","124","2026-09-29T01:41:04.6602457Z","124.0134659","1.00549090000001","9.9609375","0","","","","","","","","",""
+"1","baseline","125","2026-09-29T01:41:05.6501737Z","125.0028657","0.989399800000001","6.16302186878728","0","","","","","","","","",""
+"1","baseline","126","2026-09-29T01:41:06.6501694Z","126.003443","1.00057729999999","6.4327485380117","0","","","","","","","","",""
+"1","baseline","127","2026-09-29T01:41:07.6490096Z","127.0022608","0.998817799999998","13.28125","0","","","","","","","","",""
+"1","baseline","128","2026-09-29T01:41:08.6485971Z","128.0018507","0.999589900000018","5.6640625","0","","","","","","","","",""
+"1","baseline","129","2026-09-29T01:41:09.6532552Z","129.0065787","1.004728","7.69230769230769","0","","","","","","","","",""
+"1","baseline","130","2026-09-29T01:41:10.6527784Z","130.0059916","0.999412899999982","8.7890625","0","","","","","","","","",""
+"1","baseline","131","2026-09-29T01:41:11.6517565Z","131.0049338","0.998942200000016","13.1115459882583","0.195519320337049","","","","","","","","",""
+"1","baseline","132","2026-09-29T01:41:12.6538753Z","132.007145","1.00221119999998","9.55165692007797","0","","","","","","","","",""
+"1","baseline","133","2026-09-29T01:41:13.6528944Z","133.006036","0.998891000000015","12.5","0","","","","","","","","",""
+"1","baseline","134","2026-09-29T01:41:14.6496318Z","134.0034348","0.997398800000013","10.9126984126984","0","","","","","","","","",""
+"1","baseline","135","2026-09-29T01:41:15.6523683Z","135.0050488","1.00161399999999","12.5","0","","","","","","","","",""
+"1","baseline","136","2026-09-29T01:41:16.6517503Z","136.0050169","0.99996809999999","8.984375","0","","","","","","","","",""
+"1","baseline","137","2026-09-29T01:41:17.6520773Z","137.005302","1.00028510000001","15.4296875","0","","","","","","","","",""
+"1","baseline","138","2026-09-29T01:41:18.6515673Z","138.0047979","0.999495899999999","16.8958742632613","0.195411006688472","","","","","","","","",""
+"1","baseline","139","2026-09-29T01:41:19.6521198Z","139.0052817","1.00048379999998","10.873786407767","0","","","","","","","","",""
+"1","baseline","140","2026-09-29T01:41:20.6525240Z","140.0053901","1.00010840000002","8.984375","0","","","","","","","","",""
+"1","baseline","141","2026-09-29T01:41:21.6548301Z","141.0081012","1.0027111","7.2265625","0","","","","","","","","",""
+"1","baseline","142","2026-09-29T01:41:22.6538678Z","142.0071556","0.999054400000006","6.640625","0","","","","","","","","",""
+"1","baseline","143","2026-09-29T01:41:23.6548147Z","143.0080595","1.0009039","8.43137254901961","0","","","","","","","","",""
+"1","baseline","144","2026-09-29T01:41:24.6497618Z","144.0029938","0.994934299999983","8.71287128712871","0","","","","","","","","",""
+"1","baseline","145","2026-09-29T01:41:25.6512896Z","145.004585","1.00159120000001","13.8401559454191","0","","","","","","","","",""
+"1","baseline","146","2026-09-29T01:41:26.6586552Z","146.011823","1.007238","9.61538461538461","0.193908986753875","","","","","","","","",""
+"1","baseline","147","2026-09-29T01:41:27.6561905Z","147.009496","0.997672999999992","8.3984375","0","","","","","","","","",""
+"1","baseline","148","2026-09-29T01:41:28.6518873Z","148.0050567","0.995560699999999","6.0665362035225","0","","","","","","","","",""
+"1","baseline","149","2026-09-29T01:41:29.6497425Z","149.0032859","0.998229199999997","9.10891089108911","0","","","","","","","","",""
+"1","baseline","150","2026-09-29T01:41:30.6497557Z","150.0031132","0.999827300000021","14.453125","0","","","","","","","","",""
+"1","baseline","151","2026-09-29T01:41:31.6484509Z","151.001755","0.998641800000001","9.9609375","0","","","","","","","","",""
+"1","baseline","152","2026-09-29T01:41:32.6489763Z","152.0023464","1.00059139999999","6.8359375","0","","","","","","","","",""
+"1","baseline","153","2026-09-29T01:41:33.6512746Z","153.0045683","1.0022219","12.6953125","0","","","","","","","","",""
+"1","baseline","154","2026-09-29T01:41:34.6526010Z","154.0058703","1.00130200000001","7.30769230769231","0.195058533789005","","","","","","","","",""
+"1","baseline","155","2026-09-29T01:41:35.6545367Z","155.0077025","1.0018322","8.59375","0","","","","","","","","",""
+"1","baseline","156","2026-09-29T01:41:36.6538527Z","156.0070022","0.999299699999995","5.2734375","0","","","","","","","","",""
+"1","baseline","157","2026-09-29T01:41:37.6503606Z","157.0035368","0.996534600000018","8.53174603174603","0","","","","","","","","",""
+"1","baseline","158","2026-09-29T01:41:38.6520343Z","158.0054106","1.0018738","9.03846153846154","0","","","","","","","","",""
+"1","baseline","159","2026-09-29T01:41:39.6522437Z","159.005651","1.0002404","10.15625","0","","","","","","","","",""
+"1","baseline","160","2026-09-29T01:41:40.6489572Z","160.0022035","0.996552499999979","10.1190476190476","0","","","","","","","","",""
+"1","baseline","161","2026-09-29T01:41:41.6620879Z","161.0149325","1.01272900000001","5.57692307692308","0","","","","","","","","",""
+"1","baseline","162","2026-09-29T01:41:42.6610630Z","162.0142803","0.99934780000001","6.4453125","0","","","","","","","","",""
+"1","baseline","163","2026-09-29T01:41:43.6607227Z","163.0138871","0.999606800000009","7.04500978473581","0","","","","","","","","",""
+"1","baseline","164","2026-09-29T01:41:44.6582941Z","164.0114638","0.997576699999996","5.0880626223092","0","","","","","","","","",""
+"1","baseline","165","2026-09-29T01:41:45.6475988Z","165.0009313","0.989467499999989","6.52173913043478","0","","","","","","","","",""
+"1","baseline","166","2026-09-29T01:41:46.6487695Z","166.0021296","1.0011983","7.6171875","0","","","","","","","","",""
+"1","baseline","167","2026-09-29T01:41:47.6506349Z","167.0039506","1.00182100000001","8.7890625","0","","","","","","","","",""
+"1","baseline","168","2026-09-29T01:41:48.6503428Z","168.003628","0.999677399999996","8.7890625","0","","","","","","","","",""
+"1","baseline","169","2026-09-29T01:41:49.6516008Z","169.0048549","1.00122690000001","8.94941634241245","0","","","","","","","","",""
+"1","baseline","170","2026-09-29T01:41:50.6520717Z","170.005274","1.00041909999999","9.26640926640927","0.195230678822508","","","","","","","","",""
+"1","baseline","171","2026-09-29T01:41:51.6563729Z","171.0096626","1.0043886","5.078125","0","","","","","","","","",""
+"1","baseline","172","2026-09-29T01:41:52.6546390Z","172.0078706","0.998208000000005","4.4921875","0","","","","","","","","",""
+"1","baseline","173","2026-09-29T01:41:53.6537274Z","173.0061377","0.998267099999993","6.0546875","0","","","","","","","","",""
+"1","baseline","174","2026-09-29T01:41:54.6550806Z","174.0084113","1.00227360000002","8.7890625","0","","","","","","","","",""
+"1","baseline","175","2026-09-29T01:41:55.6560127Z","175.0092737","1.00086239999999","10.546875","0","","","","","","","","",""
+"1","baseline","176","2026-09-29T01:41:56.6583826Z","176.0115602","1.0022865","5.078125","0","","","","","","","","",""
+"1","baseline","177","2026-09-29T01:41:57.6567157Z","177.0101448","0.998584600000015","7.8125","0","","","","","","","","",""
+"1","baseline","178","2026-09-29T01:41:58.6551835Z","178.0084358","0.998290999999995","5.46875","0","","","","","","","","",""
+"1","baseline","179","2026-09-29T01:41:59.6611942Z","179.0145313","1.00609549999999","8.984375","0","","","","","","","","",""
+"1","baseline","180","2026-09-29T01:42:00.6590522Z","180.0124082","0.997876899999994","6.0546875","0","","","","","","","","",""
+"1","baseline","181","2026-09-29T01:42:01.6507173Z","181.0034925","0.991084300000011","6.15079365079365","0","","","","","","","","",""
+"1","baseline","182","2026-09-29T01:42:02.6551563Z","182.0084432","1.00495069999999","6.15384615384615","0","","","","","","","","",""
+"1","baseline","183","2026-09-29T01:42:03.6568879Z","183.0097856","1.0013424","6.25","0","","","","","","","","",""
+"1","baseline","184","2026-09-29T01:42:04.6610699Z","184.0145478","1.00476220000002","5.859375","0","","","","","","","","",""
+"1","baseline","185","2026-09-29T01:42:05.6599012Z","185.0129432","0.998395399999993","10.546875","0","","","","","","","","",""
+"1","baseline","186","2026-09-29T01:42:06.6568691Z","186.0101691","0.997225899999989","5.078125","0","","","","","","","","",""
+"1","baseline","187","2026-09-29T01:42:07.6571443Z","187.0105462","1.00037710000001","6.4453125","0","","","","","","","","",""
+"1","baseline","188","2026-09-29T01:42:08.6592045Z","188.0124809","1.00193469999999","4.6875","0","","","","","","","","",""
+"1","baseline","189","2026-09-29T01:42:09.6597015Z","189.0128648","1.0003839","5.078125","0","","","","","","","","",""
+"1","baseline","190","2026-09-29T01:42:10.6575922Z","190.0109627","0.998097900000005","7.03125","0","","","","","","","","",""
+"1","baseline","191","2026-09-29T01:42:11.6588979Z","191.0121577","1.001195","6.8359375","0","","","","","","","","",""
+"1","baseline","192","2026-09-29T01:42:12.6586037Z","192.0118596","0.999701899999991","6.640625","0","","","","","","","","",""
+"1","baseline","193","2026-09-29T01:42:13.6488488Z","193.0020093","0.990149700000018","3.76984126984127","0","","","","","","","","",""
+"1","baseline","194","2026-09-29T01:42:14.6508246Z","194.0040038","1.0019945","7.03125","0","","","","","","","","",""
+"1","baseline","195","2026-09-29T01:42:15.6543324Z","195.0075374","1.0035336","10.1923076923077","0","","","","","","","","",""
+"1","baseline","196","2026-09-29T01:42:16.6538837Z","196.0066577","0.999120300000016","5.859375","0","","","","","","","","",""
+"1","baseline","197","2026-09-29T01:42:17.6570779Z","197.0103691","1.00371139999999","6.25","0","","","","","","","","",""
+"1","baseline","198","2026-09-29T01:42:18.6564830Z","198.0096432","0.999274100000008","6.0546875","0","","","","","","","","",""
+"1","baseline","199","2026-09-29T01:42:19.6533798Z","199.0066083","0.996965099999983","21.6796875","0","","","","","","","","",""
+"1","baseline","200","2026-09-29T01:42:20.6512067Z","200.0044352","0.997826900000007","40.2777777777778","0","","","","","","","","",""
+"1","baseline","201","2026-09-29T01:42:21.6492266Z","201.002554","0.998118800000015","23.046875","0.195680614371753","","","","","","","","",""
+"1","baseline","202","2026-09-29T01:42:22.6472620Z","202.0004469","0.997892899999982","14.6484375","0","","","","","","","","",""
+"1","baseline","203","2026-09-29T01:42:23.6580020Z","203.0111328","1.0106859","10.3846153846154","0","","","","","","","","",""
+"1","baseline","204","2026-09-29T01:42:24.6583169Z","204.0116545","1.00052170000001","11.5234375","0","","","","","","","","",""
+"1","baseline","205","2026-09-29T01:42:25.6533091Z","205.0066678","0.995013300000011","9.5703125","0","","","","","","","","",""
+"1","baseline","206","2026-09-29T01:42:26.6515385Z","206.0047958","0.99812799999998","14.0594059405941","0","","","","","","","","",""
+"1","baseline","207","2026-09-29T01:42:27.6501672Z","207.0033457","0.9985499","15.6555772994129","0.195596133953846","","","","","","","","",""
+"1","baseline","208","2026-09-29T01:42:28.6530191Z","208.0062888","1.00294310000001","10.3846153846154","0","","","","","","","","",""
+"1","baseline","209","2026-09-29T01:42:29.6531913Z","209.0065441","1.00025529999999","5.859375","0","","","","","","","","",""
+"1","baseline","210","2026-09-29T01:42:30.6507633Z","210.0039848","0.997440699999999","9.72222222222222","0","","","","","","","","",""
+"1","baseline","211","2026-09-29T01:42:31.6469173Z","211.0001685","0.996183700000017","14.84375","0","","","","","","","","",""
+"1","baseline","212","2026-09-29T01:42:32.6589750Z","212.0123732","1.01220469999998","5.96153846153846","0","","","","","","","","",""
+"1","baseline","213","2026-09-29T01:42:33.6600271Z","213.0133051","1.00093190000001","7.6171875","0","","","","","","","","",""
+"1","baseline","214","2026-09-29T01:42:34.6583788Z","214.0117129","0.998407799999995","5.6640625","0","","","","","","","","",""
+"1","baseline","215","2026-09-29T01:42:35.6557029Z","215.0089072","0.99719429999999","14.0625","0","","","","","","","","",""
+"1","baseline","216","2026-09-29T01:42:36.6567421Z","216.0099344","1.00102720000001","7.6171875","0","","","","","","","","",""
+"1","baseline","217","2026-09-29T01:42:37.6584732Z","217.011694","1.00175959999999","6.640625","0","","","","","","","","",""
+"1","baseline","218","2026-09-29T01:42:38.6621860Z","218.0155454","1.0038514","5.46875","0","","","","","","","","",""
+"1","baseline","219","2026-09-29T01:42:39.6481956Z","219.001357","0.985811600000005","9.12698412698413","0","","","","","","","","",""
+"1","baseline","220","2026-09-29T01:42:40.6497707Z","220.0029416","1.0015846","6.8359375","0","","","","","","","","",""
+"1","baseline","221","2026-09-29T01:42:41.6513711Z","221.0045328","1.00159120000001","16.2109375","0","","","","","","","","",""
+"1","baseline","222","2026-09-29T01:42:42.6564056Z","222.0096115","1.00507869999998","10.1923076923077","0.194325578683543","","","","","","","","",""
+"1","baseline","223","2026-09-29T01:42:43.6541406Z","223.0074786","0.997867100000008","6.8359375","0","","","","","","","","",""
+"1","baseline","224","2026-09-29T01:42:44.6525597Z","224.0058399","0.998361299999999","5.859375","0","","","","","","","","",""
+"1","baseline","225","2026-09-29T01:42:45.6531308Z","225.006318","1.00047810000001","5.2734375","0","","","","","","","","",""
+"1","baseline","226","2026-09-29T01:42:46.6529922Z","226.0061434","0.999825399999992","24.21875","0","","","","","","","","",""
+"1","baseline","227","2026-09-29T01:42:47.6537184Z","227.0070961","1.0009527","5.859375","0","","","","","","","","",""
+"1","baseline","228","2026-09-29T01:42:48.6544630Z","228.0076628","1.00056670000001","6.25","0","","","","","","","","",""
+"1","baseline","229","2026-09-29T01:42:49.6521214Z","229.0053733","0.997710500000011","6.640625","0","","","","","","","","",""
+"1","baseline","230","2026-09-29T01:42:50.6529739Z","230.0061358","1.00076249999998","6.25","0","","","","","","","","",""
+"1","baseline","231","2026-09-29T01:42:51.6529573Z","231.0061825","1.00004670000001","11.3502935420744","0","","","","","","","","",""
+"1","baseline","232","2026-09-29T01:42:52.6609011Z","232.0141736","1.0079911","6.4327485380117","0","","","","","","","","",""
+"1","baseline","233","2026-09-29T01:42:53.6484080Z","233.0017584","0.987584800000008","5.35714285714286","0","","","","","","","","",""
+"1","baseline","234","2026-09-29T01:42:54.6488216Z","234.0021705","1.00041209999998","7.6171875","0","","","","","","","","",""
+"1","baseline","235","2026-09-29T01:42:55.6473031Z","235.0006635","0.998493000000025","9.1796875","0","","","","","","","","",""
+"1","baseline","236","2026-09-29T01:42:56.6585357Z","236.0118712","1.0112077","7.69230769230769","0","","","","","","","","",""
+"1","baseline","237","2026-09-29T01:42:57.6577439Z","237.0109665","0.999095299999993","5.46875","0","","","","","","","","",""
+"1","baseline","238","2026-09-29T01:42:58.6560933Z","238.0093305","0.998363999999981","7.8125","0","","","","","","","","",""
+"1","baseline","239","2026-09-29T01:42:59.6574436Z","239.010794","1.0014635","5.078125","0","","","","","","","","",""
+"1","baseline","240","2026-09-29T01:43:00.6580856Z","240.0114572","1.00066320000002","6.25","0","","","","","","","","",""
+"1","baseline","241","2026-09-29T01:43:01.6599943Z","241.0132993","1.0018421","5.859375","0","","","","","","","","",""
+"1","baseline","242","2026-09-29T01:43:02.6614693Z","242.014777","1.00147769999998","5.859375","0","","","","","","","","",""
+"1","baseline","243","2026-09-29T01:43:03.6477864Z","243.0009467","0.986169700000005","5.95238095238095","0","","","","","","","","",""
+"1","baseline","244","2026-09-29T01:43:04.6612859Z","244.0145052","1.01355850000002","6.53846153846154","0","","","","","","","","",""
+"1","baseline","245","2026-09-29T01:43:05.6582129Z","245.0115421","0.997036899999983","5.859375","0","","","","","","","","",""
+"1","baseline","246","2026-09-29T01:43:06.6572397Z","246.0104262","0.998884099999998","9.1796875","0","","","","","","","","",""
+"1","baseline","247","2026-09-29T01:43:07.6579559Z","247.011323","1.00089679999999","8.203125","0","","","","","","","","",""
+"1","baseline","248","2026-09-29T01:43:08.6470803Z","248.0003905","0.989067500000004","4.16666666666667","0","","","","","","","","",""
+"1","baseline","249","2026-09-29T01:43:09.6506472Z","249.0038612","1.00347070000001","4.4921875","0","","","","","","","","",""
+"1","baseline","250","2026-09-29T01:43:10.6493515Z","250.0025615","0.998700299999996","15.0390625","0","","","","","","","","",""
+"1","baseline","251","2026-09-29T01:43:11.6501820Z","251.0040047","1.00144320000001","10.546875","0","","","","","","","","",""
+"1","baseline","252","2026-09-29T01:43:12.6509056Z","252.0042511","1.00024639999998","8.7890625","0","","","","","","","","",""
+"1","baseline","253","2026-09-29T01:43:13.6536238Z","253.0068683","1.0026172","13.0769230769231","0","","","","","","","","",""
+"1","baseline","254","2026-09-29T01:43:14.6507991Z","254.0034878","0.996619500000008","7.34126984126984","0","","","","","","","","",""
+"1","baseline","255","2026-09-29T01:43:15.6498880Z","255.0032024","0.999714600000004","9.1796875","0","","","","","","","","",""
+"1","baseline","256","2026-09-29T01:43:16.6491345Z","256.002461","0.99925859999999","14.84375","0","","","","","","","","",""
+"1","baseline","257","2026-09-29T01:43:17.6526912Z","257.0059269","1.00346589999998","9.80769230769231","0","","","","","","","","",""
+"1","baseline","258","2026-09-29T01:43:18.6511192Z","258.0044342","0.998507300000028","11.5079365079365","0","","","","","","","","",""
+"1","baseline","259","2026-09-29T01:43:19.6551020Z","259.0082928","1.0038586","8.67052023121387","0.194561763977516","","","","","","","","",""
+"1","baseline","260","2026-09-29T01:43:20.6588185Z","260.0120773","1.00378449999999","5.84795321637427","0","","","","","","","","",""
+"1","baseline","261","2026-09-29T01:43:21.6616790Z","261.0149877","1.00291040000002","5.2734375","0","","","","","","","","",""
+"1","baseline","262","2026-09-29T01:43:22.6578869Z","262.0112213","0.996233599999982","7.6171875","0","","","","","","","","",""
+"1","baseline","263","2026-09-29T01:43:23.6503069Z","263.0037938","0.992572499999994","19.6428571428571","0","","","","","","","","",""
+"1","baseline","264","2026-09-29T01:43:24.6522640Z","264.0054513","1.00165750000002","10.9615384615385","0","","","","","","","","",""
+"1","baseline","265","2026-09-29T01:43:25.6611064Z","265.0144419","1.0089906","6.4453125","0","","","","","","","","",""
+"1","baseline","266","2026-09-29T01:43:26.6560102Z","266.0094194","0.994977500000005","8.203125","0","","","","","","","","",""
+"1","baseline","267","2026-09-29T01:43:27.6580949Z","267.0111977","1.00177829999996","9.375","0","","","","","","","","",""
+"1","baseline","268","2026-09-29T01:43:28.6562579Z","268.0094891","0.998291400000028","21.6796875","0","","","","","","","","",""
+"1","baseline","269","2026-09-29T01:43:29.6496472Z","269.0029178","0.993428699999981","19.8412698412698","0","","","","","","","","",""
+"1","baseline","270","2026-09-29T01:43:30.6609945Z","270.0145986","1.01168080000002","27.1153846153846","0","","","","","","","","",""
+"1","baseline","271","2026-09-29T01:43:31.6576531Z","271.0110863","0.996487699999989","14.84375","0","","","","","","","","",""
+"1","baseline","272","2026-09-29T01:43:32.6560872Z","272.0094594","0.998373099999981","8.984375","0","","","","","","","","",""
+"1","baseline","273","2026-09-29T01:43:33.6530322Z","273.0062971","0.996837700000015","6.4453125","0","","","","","","","","",""
+"1","baseline","274","2026-09-29T01:43:34.6519535Z","274.0047921","0.998494999999991","8.64440078585462","0.195606888366994","","","","","","","","",""
+"1","baseline","275","2026-09-29T01:43:35.6524244Z","275.0057256","1.00093350000003","13.9805825242718","0","","","","","","","","",""
+"1","baseline","276","2026-09-29T01:43:36.6564063Z","276.0095961","1.0038705","7.8125","0","","","","","","","","",""
+"1","baseline","277","2026-09-29T01:43:37.6552578Z","277.0081095","0.998513399999979","7.6171875","0","","","","","","","","",""
+"1","baseline","278","2026-09-29T01:43:38.6550481Z","278.0083103","1.00020080000002","8.59375","0","","","","","","","","",""
+"1","baseline","279","2026-09-29T01:43:39.6570527Z","279.0102521","1.0019418","7.03125","0","","","","","","","","",""
+"1","baseline","280","2026-09-29T01:43:40.6540958Z","280.0073568","0.997104699999966","4.70588235294118","0","","","","","","","","",""
+"1","baseline","281","2026-09-29T01:43:41.6523077Z","281.0056338","0.99827700000003","5.05836575875486","0","","","","","","","","",""
+"1","baseline","282","2026-09-29T01:43:42.6604118Z","282.0138322","1.00819839999997","12.3046875","0","","","","","","","","",""
+"1","baseline","283","2026-09-29T01:43:43.6574650Z","283.0107692","0.996937000000003","5.078125","0","","","","","","","","",""
+"1","baseline","284","2026-09-29T01:43:44.6613363Z","284.0145575","1.0037883","8.7890625","0","","","","","","","","",""
+"1","baseline","285","2026-09-29T01:43:45.6470725Z","285.0004646","0.98590710000002","7.14285714285714","0","","","","","","","","",""
+"1","baseline","286","2026-09-29T01:43:46.6603966Z","286.0136732","1.01320859999998","11.1538461538462","0","","","","","","","","",""
+"1","baseline","287","2026-09-29T01:43:47.6600254Z","287.0132986","0.999625400000014","5.2734375","0","","","","","","","","",""
+"1","baseline","288","2026-09-29T01:43:48.6586947Z","288.0119366","0.998638000000028","4.8828125","0","","","","","","","","",""
+"1","baseline","289","2026-09-29T01:43:49.6594029Z","289.0127197","1.00078309999998","6.4453125","0","","","","","","","","",""
+"1","baseline","290","2026-09-29T01:43:50.6551006Z","290.0084304","0.995710700000018","5.2734375","0","","","","","","","","",""
+"1","baseline","291","2026-09-29T01:43:51.6569702Z","291.0097256","1.00129519999996","7.2265625","0","","","","","","","","",""
+"1","baseline","292","2026-09-29T01:43:52.6545214Z","292.0077745","0.998048900000015","6.4453125","0","","","","","","","","",""
+"1","baseline","293","2026-09-29T01:43:53.6495536Z","293.0028377","0.995063200000004","14.484126984127","0","","","","","","","","",""
+"1","baseline","294","2026-09-29T01:43:54.6512564Z","294.004483","1.00164530000001","13.4765625","0","","","","","","","","",""
+"1","baseline","295","2026-09-29T01:43:55.6468251Z","295.0001408","0.995657800000004","8.3984375","0.1961642845564","","","","","","","","",""
+"1","baseline","296","2026-09-29T01:43:56.6516319Z","296.0048885","1.0047477","12.3552123552124","0","","","","","","","","",""
+"1","baseline","297","2026-09-29T01:43:57.6490216Z","297.0021833","0.99729480000002","9.28853754940712","0.195842292569856","","","","","","","","",""
+"1","baseline","298","2026-09-29T01:43:58.6468533Z","298.0000972","0.997913899999958","7.8125","0","","","","","","","","",""
+"1","baseline","299","2026-09-29T01:43:59.6503813Z","299.0034722","1.00337500000001","5.859375","0","","","","","","","","",""
+"1","baseline","300","2026-09-29T01:44:00.6585121Z","300.0117647","1.00829250000004","13.6538461538462","0","","","","","","","","",""
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block-end.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block-end.json
new file mode 100644
index 0000000..0b844dd
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block-end.json
@@ -0,0 +1,12 @@
+{
+ "state": "block",
+ "layers": {
+ "shutdown": true,
+ "local_shutdown": true,
+ "update": false,
+ "remote": true,
+ "sleep": true
+ },
+ "uptime_seconds": 333,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block-start.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block-start.json
new file mode 100644
index 0000000..5994d76
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block-start.json
@@ -0,0 +1,12 @@
+{
+ "state": "block",
+ "layers": {
+ "shutdown": true,
+ "local_shutdown": true,
+ "update": false,
+ "remote": true,
+ "sleep": true
+ },
+ "uptime_seconds": 33,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block.csv
new file mode 100644
index 0000000..6636f91
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-1-block.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"1","block","1","2026-09-29T01:50:08.0115577Z","1.0048423","1.0048388","8.65384615384615","0","26324","0","0","3.23828125","13.92578125","11","194","0","0"
+"1","block","2","2026-09-29T01:50:09.0128938Z","2.0061387","1.0012964","11.5234375","0","26324","0","0","3.296875","14.1171875","11","194","0","0"
+"1","block","3","2026-09-29T01:50:10.0168402Z","3.010124","1.0039853","7.421875","0","26324","0","0","3.234375","14.0390625","11","194","0","0"
+"1","block","4","2026-09-29T01:50:11.0180048Z","4.0112522","1.0011282","5.6640625","0","26324","0","0","3.234375","14.0390625","11","194","0","0"
+"1","block","5","2026-09-29T01:50:12.0195411Z","5.0128834","1.0016312","7.6171875","0","26324","0","0","3.234375","14.0390625","11","194","0","0"
+"1","block","6","2026-09-29T01:50:13.0211117Z","6.0143865","1.0015031","19.921875","0","26324","0","0","3.25390625","14.04296875","11","194","0","0"
+"1","block","7","2026-09-29T01:50:14.0072613Z","7.0004857","0.9860992","18.8492063492063","0","26324","0","0","3.25390625","14.046875","11","194","0","0"
+"1","block","8","2026-09-29T01:50:15.0087170Z","8.0019415","1.0014558","10.3515625","0","26324","0","0","3.25390625","14.046875","11","194","0","0"
+"1","block","9","2026-09-29T01:50:16.0084889Z","9.0018508","0.999909300000001","7.6171875","0.195330216450632","26324","0","0","3.25390625","14.046875","11","194","0","0"
+"1","block","10","2026-09-29T01:50:17.0095041Z","10.0026967","1.0008459","5.2734375","0.195147424793367","26324","0","0","3.25390625","14.05078125","11","194","0","0"
+"1","block","11","2026-09-29T01:50:18.0103799Z","11.0030783","1.0003816","13.0859375","0.195237997180276","26324","0","0","3.25390625","14.05078125","11","194","0","0"
+"1","block","12","2026-09-29T01:50:19.0185519Z","12.011297","1.0082187","9.80769230769231","0.193720370391861","26324","0","0","3.25390625","14.05078125","11","194","0","0"
+"1","block","13","2026-09-29T01:50:20.0353790Z","13.0285439","1.0172469","7.30769230769231","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","14","2026-09-29T01:50:21.0171509Z","14.0104799","0.981936000000001","5.35714285714286","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","15","2026-09-29T01:50:22.0125786Z","15.005971","0.995491099999999","9.5703125","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","16","2026-09-29T01:50:23.0221461Z","16.0155945","1.0096235","14.453125","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","17","2026-09-29T01:50:24.0089247Z","17.0021408","0.986546300000001","6.54761904761905","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","18","2026-09-29T01:50:25.0062578Z","17.9995949","0.997454099999999","5.46875","0.19581101526376","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","19","2026-09-29T01:50:26.0073724Z","19.0005878","1.0009929","7.2265625","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","20","2026-09-29T01:50:27.0156040Z","20.0088338","1.008246","7.88461538461539","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","21","2026-09-29T01:50:28.0163458Z","21.0096595","1.0008257","5.6640625","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","22","2026-09-29T01:50:29.0180428Z","22.0112706","1.0016111","7.6171875","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","23","2026-09-29T01:50:30.0146654Z","23.0079881","0.996717499999999","8.59375","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","24","2026-09-29T01:50:31.0155597Z","24.0088071","1.000819","5.6640625","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","25","2026-09-29T01:50:32.0135042Z","25.0067054","0.997898299999999","8.203125","0","26324","0","0","3.25390625","14.0546875","11","194","0","0"
+"1","block","26","2026-09-29T01:50:33.0105657Z","26.003742","0.997036600000001","10.3174603174603","0","26324","0","0","3.25390625","14.05859375","11","194","0","0"
+"1","block","27","2026-09-29T01:50:34.0096100Z","27.0028373","0.9990953","31.25","0.195489359223289","26324","0","0","3.22265625","14.02734375","10","194","0","0"
+"1","block","28","2026-09-29T01:50:35.0134666Z","28.0067079","1.0038706","13.8461538461538","0.194559438238355","26324","0","0","3.22265625","14.02734375","10","194","0","0"
+"1","block","29","2026-09-29T01:50:36.0107432Z","29.0039525","0.997244599999998","11.5079365079365","0","26324","0.015625","0.195852151016912","3.2265625","14.03125","10","194","0","0"
+"1","block","30","2026-09-29T01:50:37.0127555Z","30.0059897","1.0020372","45.7692307692308","0.194915418309819","26324","0","0","3.2265625","14.03125","10","194","0","0"
+"1","block","31","2026-09-29T01:50:38.0227202Z","31.0159925","1.0100028","16.2109375","0","26324","0","0","3.2265625","14.03125","10","194","0","0"
+"1","block","32","2026-09-29T01:50:39.0174015Z","32.0107081","0.994715599999996","15.4296875","0","26324","0","0","3.2265625","14.03515625","10","194","0","0"
+"1","block","33","2026-09-29T01:50:40.0142526Z","33.0075001","0.996792000000006","10.9375","0","26324","0","0","3.2265625","14.0390625","10","194","0","0"
+"1","block","34","2026-09-29T01:50:41.0168198Z","34.0101228","1.0026227","5.078125","0","26324","0","0","3.2265625","14.0390625","10","194","0","0"
+"1","block","35","2026-09-29T01:50:42.0165956Z","35.0099419","0.999819100000003","11.71875","0","26324","0","0","3.2265625","14.04296875","10","194","0","0"
+"1","block","36","2026-09-29T01:50:43.0168116Z","36.0100449","1.000103","4.6875","0","26324","0","0","3.2265625","14.04296875","10","194","0","0"
+"1","block","37","2026-09-29T01:50:44.0169265Z","37.0102033","1.0001584","5.2734375","0","26324","0","0","3.2265625","14.04296875","10","194","0","0"
+"1","block","38","2026-09-29T01:50:45.0156251Z","38.0089782","0.998774900000001","6.0546875","0","26324","0","0","3.2265625","14.04296875","10","194","0","0"
+"1","block","39","2026-09-29T01:50:46.0128627Z","39.0060343","0.997056099999995","6.640625","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","40","2026-09-29T01:50:47.0111236Z","40.0043592","0.9983249","20.5479452054795","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","41","2026-09-29T01:50:48.0221417Z","41.015604","1.0112448","7.40740740740741","0.193140671774035","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","42","2026-09-29T01:50:49.0095766Z","42.0028056","0.987201599999999","8.92857142857143","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","43","2026-09-29T01:50:50.0139376Z","43.0071618","1.0043562","10.7692307692308","0.1944653699554","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","44","2026-09-29T01:50:51.0170436Z","44.0103588","1.003197","4.4921875","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","45","2026-09-29T01:50:52.0146216Z","45.0078587","0.997499900000001","9.1796875","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","46","2026-09-29T01:50:53.0146115Z","46.0077827","0.999924","4.4921875","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","47","2026-09-29T01:50:54.0118561Z","47.0050852","0.997302499999996","5.46875","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","48","2026-09-29T01:50:55.0183852Z","48.0115629","1.0064777","5.859375","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","49","2026-09-29T01:50:56.0110635Z","49.0043618","0.992798899999997","5.859375","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","50","2026-09-29T01:50:57.0114885Z","50.0047303","1.0003685","8.203125","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","51","2026-09-29T01:50:58.0143990Z","51.0075418","1.0028115","15.234375","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","52","2026-09-29T01:50:59.0185088Z","52.0122784","1.0047366","6.25","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","53","2026-09-29T01:51:00.0192245Z","53.0124017","1.0001233","6.25","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","54","2026-09-29T01:51:01.0196788Z","54.0130302","1.0006285","7.2265625","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","55","2026-09-29T01:51:02.0191664Z","55.0123647","0.999334500000003","12.890625","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","56","2026-09-29T01:51:03.0221898Z","56.0149847","1.00262","5.2734375","0","26324","0","0","3.265625","14.05078125","10","194","0","0"
+"1","block","57","2026-09-29T01:51:04.0186703Z","57.0119975","0.9970128","6.25","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","58","2026-09-29T01:51:05.0215923Z","58.01474","1.0027425","5.46875","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","59","2026-09-29T01:51:06.0086680Z","59.0019679","0.987227900000001","10.1190476190476","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","60","2026-09-29T01:51:07.0140706Z","60.0073736","1.0054057","9.03846153846154","0.194262375874734","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","61","2026-09-29T01:51:08.0130791Z","61.0063581","0.998984500000006","5.078125","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","62","2026-09-29T01:51:09.0098838Z","62.0031654","0.9968073","8.53174603174603","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","63","2026-09-29T01:51:10.0090304Z","63.002317","0.999151599999998","9.1796875","0.195478343826903","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","64","2026-09-29T01:51:11.0082938Z","64.0014337","0.999116699999995","7.2265625","0.195485172052475","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","65","2026-09-29T01:51:12.0213139Z","65.0145638","1.0131301","8.46153846153846","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","66","2026-09-29T01:51:13.0102507Z","66.0033909","0.988827100000009","7.3558648111332","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","67","2026-09-29T01:51:14.0160942Z","67.0094936","1.0061027","10.1727447216891","0.194127796297535","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","68","2026-09-29T01:51:15.0161768Z","68.0093847","0.999891099999999","6.25","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","69","2026-09-29T01:51:16.0185143Z","69.0117874","1.0024027","4.8828125","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","70","2026-09-29T01:51:17.0211795Z","70.0145073","1.00271989999999","7.421875","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","71","2026-09-29T01:51:18.0143640Z","71.0076593","0.993152000000009","5.6640625","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","72","2026-09-29T01:51:19.0143994Z","72.0076692","1.00000989999999","4.4921875","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","73","2026-09-29T01:51:20.0193584Z","73.0124954","1.0048262","6.8359375","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","74","2026-09-29T01:51:21.0067364Z","73.9999285","0.987433100000004","5.75396825396825","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","75","2026-09-29T01:51:22.0220680Z","75.0154453","1.0155168","12.3076923076923","0.192328182064541","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","76","2026-09-29T01:51:23.0067113Z","76.0000139","0.984568600000003","8.33333333333333","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","77","2026-09-29T01:51:24.0070799Z","77.0004519","1.000438","8.984375","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","78","2026-09-29T01:51:25.0134468Z","78.0067575","1.00630559999999","21.5384615384615","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","79","2026-09-29T01:51:26.0165841Z","79.0098809","1.00312340000001","7.421875","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","80","2026-09-29T01:51:27.0147051Z","80.0079005","0.998019599999992","5.46875","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","81","2026-09-29T01:51:28.0141775Z","81.0074435","0.999543000000003","9.375","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","82","2026-09-29T01:51:29.0163380Z","82.0096629","1.0022194","7.421875","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","83","2026-09-29T01:51:30.0138260Z","83.0071088","0.997445900000002","7.6171875","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","84","2026-09-29T01:51:31.0158400Z","84.0091021","1.0019933","4.8828125","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","85","2026-09-29T01:51:32.0147147Z","85.0079933","0.998891200000003","6.0546875","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","86","2026-09-29T01:51:33.0151154Z","86.0082576","1.0002643","8.984375","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","87","2026-09-29T01:51:34.0216777Z","87.0150617","1.0068041","7.421875","0","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","88","2026-09-29T01:51:35.0077268Z","88.0008143","0.985752600000012","6.54761904761905","0","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","89","2026-09-29T01:51:36.0218075Z","89.01507","1.01425569999999","4.80769230769231","0","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","90","2026-09-29T01:51:37.0161660Z","90.0093656","0.994295600000001","10.3515625","0","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","91","2026-09-29T01:51:38.0171661Z","91.0104712","1.0011056","5.859375","0","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","92","2026-09-29T01:51:39.0197754Z","92.0131239","1.0026527","4.4921875","0","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","93","2026-09-29T01:51:40.0064858Z","92.99966","0.986536099999995","6.15079365079365","0","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","94","2026-09-29T01:51:41.0073765Z","94.0005969","1.0009369","6.0546875","0","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","95","2026-09-29T01:51:42.0105402Z","95.0033664","1.0027695","10.3515625","0.194773075966112","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","96","2026-09-29T01:51:43.0075468Z","96.0007713","0.997404900000006","12.6953125","0.195820674231697","26324","0","0","3.23046875","14.0390625","10","194","0","0"
+"1","block","97","2026-09-29T01:51:44.0078974Z","97.0010803","1.000309","4.6875","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","98","2026-09-29T01:51:45.0186490Z","98.0119705","1.01089019999999","6.53846153846154","0.193208421646586","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","99","2026-09-29T01:51:46.0212548Z","99.0145332","1.00256270000001","8.0078125","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","100","2026-09-29T01:51:47.0207300Z","100.013898","0.999364799999995","6.0546875","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","101","2026-09-29T01:51:48.0183321Z","101.0115815","0.997683499999994","5.6640625","0","26324","0","0","3.203125","14.02734375","9","192","0","0"
+"1","block","102","2026-09-29T01:51:49.0078243Z","102.0011565","0.989575000000002","5.55555555555556","0","26324","0","0","3.203125","14.03125","9","192","0","0"
+"1","block","103","2026-09-29T01:51:50.0201094Z","103.0132586","1.01210210000001","12.1153846153846","0.192977072174832","26324","0","0","3.203125","14.03515625","9","192","0","0"
+"1","block","104","2026-09-29T01:51:51.0223841Z","104.0157927","1.00253409999999","8.0078125","0","26324","0","0","3.203125","14.03515625","9","192","0","0"
+"1","block","105","2026-09-29T01:51:52.0165027Z","105.0097678","0.9939751","20.5078125","0","26324","0","0","3.203125","14.03515625","9","192","0","0"
+"1","block","106","2026-09-29T01:51:53.0123347Z","106.0056108","0.995843000000008","43.5546875","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","107","2026-09-29T01:51:54.0184688Z","107.0112383","1.0056275","13.4765625","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","108","2026-09-29T01:51:55.0143705Z","108.0076764","0.996438099999992","5.67514677103718","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","109","2026-09-29T01:51:56.0096980Z","109.0030353","0.995358899999999","11.2871287128713","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","110","2026-09-29T01:51:57.0102492Z","110.0034579","1.00042260000001","15.0390625","0.195229995803772","26324","0.015625","0.195229995803772","3.203125","14.0390625","9","192","0","0"
+"1","block","111","2026-09-29T01:51:58.0072891Z","111.0004526","0.996994699999988","9.1796875","0.195901242002593","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","112","2026-09-29T01:51:59.0191743Z","112.0123872","1.0119346","4.42307692307692","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","113","2026-09-29T01:52:00.0161203Z","113.0094219","0.9970347","5.859375","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","114","2026-09-29T01:52:01.0168881Z","114.010086","1.00066410000001","6.25","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","115","2026-09-29T01:52:02.0221588Z","115.0154712","1.00538519999999","9.765625","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","116","2026-09-29T01:52:03.0165540Z","116.0011979","0.985726700000001","8.92857142857143","0","26324","0","0","3.203125","14.0390625","9","192","0","0"
+"1","block","117","2026-09-29T01:52:04.0077755Z","117.0011795","0.999981599999998","8.203125","0","26324","0","0","3.2109375","14.03125","10","192","0","0"
+"1","block","118","2026-09-29T01:52:05.0210706Z","118.0143194","1.0131399","6.53846153846154","0","26324","0","0","3.2109375","14.03125","10","192","0","0"
+"1","block","119","2026-09-29T01:52:06.0191774Z","119.0123687","0.998049300000005","7.8125","0","26324","0","0","3.2109375","14.03125","10","192","0","0"
+"1","block","120","2026-09-29T01:52:07.0221843Z","120.0155161","1.0031474","6.0546875","0","26324","0","0","3.21484375","14.03515625","10","192","0","0"
+"1","block","121","2026-09-29T01:52:08.0222793Z","121.0154867","0.999970599999997","4.6875","0","26324","0","0","3.21484375","14.03515625","10","192","0","0"
+"1","block","122","2026-09-29T01:52:09.0221649Z","122.0149198","0.999433100000005","5.6640625","0","26324","0","0","3.21484375","14.03515625","10","192","0","0"
+"1","block","123","2026-09-29T01:52:10.0202980Z","123.0136296","0.998709799999986","7.2265625","0","26324","0","0","3.21484375","14.03515625","10","192","0","0"
+"1","block","124","2026-09-29T01:52:11.0167435Z","124.0099738","0.99634420000001","6.0546875","0","26324","0","0","3.21484375","14.03515625","10","192","0","0"
+"1","block","125","2026-09-29T01:52:12.0157942Z","125.0090265","0.999052699999993","4.4921875","0","26324","0","0","3.21484375","14.03515625","10","192","0","0"
+"1","block","126","2026-09-29T01:52:13.0183080Z","126.0115815","1.002555","8.59375","0","26324","0","0","3.21484375","14.03515625","10","192","0","0"
+"1","block","127","2026-09-29T01:52:14.0169999Z","127.0103269","0.998745400000004","7.8125","0","26324","0","0","3.234375","14.0390625","10","192","0","0"
+"1","block","128","2026-09-29T01:52:15.0101983Z","128.0033564","0.993029500000006","6.54761904761905","0","26324","0","0","3.234375","14.0390625","10","192","0","0"
+"1","block","129","2026-09-29T01:52:16.0069584Z","129.0002845","0.996928099999991","7.8125","0.195914329227957","26324","0","0","3.234375","14.04296875","10","192","0","0"
+"1","block","130","2026-09-29T01:52:17.0223461Z","130.0153479","1.0150634","5.19230769230769","0","26324","0","0","3.234375","14.04296875","10","192","0","0"
+"1","block","131","2026-09-29T01:52:18.0085720Z","131.0019575","0.986609600000008","6.15079365079365","0","26324","0","0","3.234375","14.04296875","10","192","0","0"
+"1","block","132","2026-09-29T01:52:19.0114319Z","132.0046803","1.00272279999999","12.3076923076923","0.194782147169689","26324","0","0","3.234375","14.046875","10","192","0","0"
+"1","block","133","2026-09-29T01:52:20.0183604Z","133.011531","1.0068507","6.4453125","0","26324","0","0","3.234375","14.046875","10","192","0","0"
+"1","block","134","2026-09-29T01:52:21.0365172Z","134.0298469","1.0183159","5.96153846153846","0","26324","0","0","3.234375","14.046875","10","192","0","0"
+"1","block","135","2026-09-29T01:52:22.0214000Z","135.0145656","0.984718700000002","8.33333333333333","0","26324","0","0","3.234375","14.046875","10","192","0","0"
+"1","block","136","2026-09-29T01:52:23.0176486Z","136.0108411","0.996275499999996","12.3046875","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","137","2026-09-29T01:52:24.0184451Z","137.0117621","1.00092100000001","9.765625","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","138","2026-09-29T01:52:25.0172460Z","138.0104177","0.998655600000006","5.859375","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","139","2026-09-29T01:52:26.0200122Z","139.0131952","1.00277749999998","8.0078125","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","140","2026-09-29T01:52:27.0198557Z","140.013121","0.9999258","5.2734375","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","141","2026-09-29T01:52:28.0183155Z","141.0115966","0.998475600000006","9.765625","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","142","2026-09-29T01:52:29.0167162Z","142.009854","0.9982574","4.8828125","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","143","2026-09-29T01:52:30.0157299Z","143.0089168","0.99906279999999","8.203125","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","144","2026-09-29T01:52:31.0137331Z","144.0069069","0.99799010000001","4.6875","0","26324","0","0","3.234375","14.05078125","10","192","0","0"
+"1","block","145","2026-09-29T01:52:32.0148305Z","145.0080088","1.00110190000001","6.4453125","0","26324","0","0","3.234375","14.0546875","10","192","0","0"
+"1","block","146","2026-09-29T01:52:33.0186493Z","146.0121066","1.00409779999998","9.5703125","0","26324","0","0","3.234375","14.0546875","10","192","0","0"
+"1","block","147","2026-09-29T01:52:34.0193729Z","147.0126547","1.0005481","8.984375","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","148","2026-09-29T01:52:35.0076173Z","148.0008195","0.988164800000021","5.15873015873016","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","149","2026-09-29T01:52:36.0159988Z","149.0092856","1.00846609999999","7.11538461538461","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","150","2026-09-29T01:52:37.0139517Z","150.0071393","0.997853700000007","9.1796875","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","151","2026-09-29T01:52:38.0178242Z","151.0111069","1.00396759999998","6.8359375","0","26324","0","0","3.21484375","14.03515625","10","194","0","0"
+"1","block","152","2026-09-29T01:52:39.0177658Z","152.0111479","1.00004100000001","5.859375","0","26324","0","0","3.21484375","14.03515625","10","194","0","0"
+"1","block","153","2026-09-29T01:52:40.0196589Z","153.012928","1.00178009999999","12.5","0","26324","0","0","3.21484375","14.03515625","10","194","0","0"
+"1","block","154","2026-09-29T01:52:41.0203457Z","154.0134718","1.0005438","6.640625","0","26324","0","0","3.21484375","14.03515625","10","194","0","0"
+"1","block","155","2026-09-29T01:52:42.0224305Z","155.0156167","1.00214489999999","7.421875","0","26324","0","0","3.21484375","14.03515625","10","194","0","0"
+"1","block","156","2026-09-29T01:52:43.0065437Z","155.9997498","0.984133100000008","7.34126984126984","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","157","2026-09-29T01:52:44.0196691Z","157.0128327","1.0130829","5.96153846153846","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","158","2026-09-29T01:52:45.0188506Z","158.0121029","0.999270200000012","5.6640625","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","159","2026-09-29T01:52:46.0222317Z","159.0155317","1.00342879999999","9.375","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","160","2026-09-29T01:52:47.0115904Z","160.004829","0.989297300000004","7.8125","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","161","2026-09-29T01:52:48.0130181Z","161.0061655","1.00133649999998","17.3828125","0.195051813251593","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","162","2026-09-29T01:52:49.0155380Z","162.0087489","1.00258340000002","7.6171875","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","163","2026-09-29T01:52:50.0126616Z","163.0058084","0.997059500000006","9.375","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","164","2026-09-29T01:52:51.0144415Z","164.0075527","1.00174429999998","5.078125","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","165","2026-09-29T01:52:52.0178378Z","165.0110288","1.0034761","4.4921875","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","166","2026-09-29T01:52:53.0149139Z","166.0080545","0.997025699999995","6.25","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","167","2026-09-29T01:52:54.0138304Z","167.0070051","0.998950600000001","11.5234375","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","168","2026-09-29T01:52:55.0158097Z","168.0089791","1.00197400000002","5.859375","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","169","2026-09-29T01:52:56.0188137Z","169.0121285","1.00314939999998","5.859375","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","170","2026-09-29T01:52:57.0065079Z","169.9998536","0.987725100000006","7.93650793650794","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","171","2026-09-29T01:52:58.0223481Z","171.0157335","1.01587989999999","6.92307692307692","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","172","2026-09-29T01:52:59.0203580Z","172.0134748","0.997741300000001","22.65625","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","173","2026-09-29T01:53:00.0194675Z","173.0126977","0.999222900000007","7.2265625","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","174","2026-09-29T01:53:01.0179189Z","174.0110677","0.998369999999994","7.6171875","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","175","2026-09-29T01:53:02.0148350Z","175.0080238","0.996956100000006","9.1796875","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","176","2026-09-29T01:53:03.0166090Z","176.0098868","1.00186300000001","5.859375","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","177","2026-09-29T01:53:04.0169301Z","177.0102027","1.00031589999998","9.1796875","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","178","2026-09-29T01:53:05.0191210Z","178.0123588","1.00215610000001","7.03125","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","179","2026-09-29T01:53:06.0212843Z","179.0145297","1.00217090000001","6.640625","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","180","2026-09-29T01:53:07.0105566Z","180.0036959","0.9891662","9.52380952380952","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","181","2026-09-29T01:53:08.0176036Z","181.0107941","1.0070982","5.19230769230769","0.193935904165055","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","182","2026-09-29T01:53:09.0182967Z","182.0115692","1.0007751","4.296875","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","183","2026-09-29T01:53:10.0343268Z","183.0274997","1.0159305","8.07692307692308","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","184","2026-09-29T01:53:11.0133774Z","184.0066175","0.979117800000012","8.73015873015873","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","185","2026-09-29T01:53:12.0127268Z","185.0060001","0.99938259999999","9.765625","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","186","2026-09-29T01:53:13.0138184Z","186.0069921","1.000992","5.2734375","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","187","2026-09-29T01:53:14.0130414Z","187.0063104","0.999318299999999","12.109375","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","188","2026-09-29T01:53:15.0157458Z","188.0088621","1.0025517","6.0546875","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","189","2026-09-29T01:53:16.0147116Z","189.0079258","0.999063699999994","6.25","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","190","2026-09-29T01:53:17.0140264Z","190.0071512","0.9992254","5.859375","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","191","2026-09-29T01:53:18.0196288Z","191.0129702","1.005819","7.03125","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","192","2026-09-29T01:53:19.0204907Z","192.0138244","1.00085420000002","9.9609375","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","193","2026-09-29T01:53:20.0082172Z","193.001536","0.987711599999983","6.34920634920635","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","194","2026-09-29T01:53:21.0150954Z","194.0083365","1.0068005","5.76923076923077","0.193993248910783","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","195","2026-09-29T01:53:22.0150327Z","195.0081919","0.999855400000001","7.6171875","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","196","2026-09-29T01:53:23.0148271Z","196.008068","0.999876099999994","5.078125","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","197","2026-09-29T01:53:24.0214002Z","197.0140972","1.0060292","18.5546875","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","198","2026-09-29T01:53:25.0106380Z","198.0039441","0.989846900000003","6.34920634920635","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","199","2026-09-29T01:53:26.0100896Z","199.0034864","0.999542300000002","10.15625","0.195401935465862","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","200","2026-09-29T01:53:27.0089672Z","200.0021454","0.998659000000004","6.640625","0.195574765760885","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","201","2026-09-29T01:53:28.0074065Z","201.0006451","0.998499699999996","16.6015625","0.195605967633241","26324","0.015625","0.195605967633241","3.234375","14.0546875","10","194","0","0"
+"1","block","202","2026-09-29T01:53:29.0078764Z","202.0013328","1.00068770000001","11.71875","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","203","2026-09-29T01:53:30.0111519Z","203.0045368","1.00320399999998","13.6538461538462","0.194688717349615","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","204","2026-09-29T01:53:31.0127810Z","204.0061973","1.00166050000001","9.9609375","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","205","2026-09-29T01:53:32.0140803Z","205.0072901","1.00109279999998","10.15625","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","206","2026-09-29T01:53:33.0123709Z","206.0056271","0.998337000000021","6.25","0","26324","0","0","3.234375","14.0546875","10","194","0","0"
+"1","block","207","2026-09-29T01:53:34.0126541Z","207.0057774","1.0001503","13.0859375","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","208","2026-09-29T01:53:35.0126680Z","208.0060081","1.0002307","5.6640625","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","209","2026-09-29T01:53:36.0166735Z","209.0099457","1.0039376","7.03125","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","210","2026-09-29T01:53:37.0211328Z","210.0144482","1.0045025","5.46875","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","211","2026-09-29T01:53:38.0177706Z","211.0113793","0.996931099999983","13.4765625","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","212","2026-09-29T01:53:39.0076790Z","212.0004865","0.989107200000007","4.76190476190476","0","26324","0","0","3.2109375","14.03125","10","194","0","0"
+"1","block","213","2026-09-29T01:53:40.0198005Z","213.0132015","1.01271499999999","5.57692307692308","0","26324","0","0","3.21484375","14.03515625","10","194","0","0"
+"1","block","214","2026-09-29T01:53:41.0157359Z","214.0089016","0.995700100000022","6.0546875","0","26324","0","0","3.21484375","14.03515625","10","194","0","0"
+"1","block","215","2026-09-29T01:53:42.0111035Z","215.004367","0.9954654","17.7734375","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","216","2026-09-29T01:53:43.0185596Z","216.01237","1.008003","7.03125","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","217","2026-09-29T01:53:44.0170858Z","217.0103516","0.997981599999974","8.41487279843444","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","218","2026-09-29T01:53:45.0140854Z","218.0072388","0.996887200000003","5.45808966861598","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","219","2026-09-29T01:53:46.0160617Z","219.0093675","1.00212870000001","6.640625","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","220","2026-09-29T01:53:47.0147102Z","220.0080856","0.998718099999991","6.8359375","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","221","2026-09-29T01:53:48.0166687Z","221.0098468","1.0017612","5.6640625","0","26324","0","0","3.234375","14.0390625","10","194","0","0"
+"1","block","222","2026-09-29T01:53:49.0186849Z","222.0118809","1.0020341","6.25","0","26324","0","0","3.234375","14.04296875","10","194","0","0"
+"1","block","223","2026-09-29T01:53:50.0216457Z","223.0150388","1.00315789999999","6.8359375","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","224","2026-09-29T01:53:51.0191788Z","224.0125017","0.997462900000016","3.90625","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","225","2026-09-29T01:53:52.0094397Z","225.0026111","0.990109399999994","6.34920634920635","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","226","2026-09-29T01:53:53.0141687Z","226.0074465","1.00483539999999","10.3846153846154","0.194372630582085","26324","0.015625","0.194372630582085","3.234375","14.046875","10","194","0","0"
+"1","block","227","2026-09-29T01:53:54.0210768Z","227.0142487","1.00680220000001","9.1796875","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","228","2026-09-29T01:53:55.0116772Z","228.0049133","0.990664600000002","11.3502935420744","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","229","2026-09-29T01:53:56.0125591Z","229.0059226","1.00100929999999","9.55165692007797","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","230","2026-09-29T01:53:57.0155944Z","230.0088738","1.00295120000001","5.2734375","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","231","2026-09-29T01:53:58.0146433Z","231.0078632","0.998989399999999","8.3984375","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","232","2026-09-29T01:53:59.0183927Z","232.011299","1.00343579999998","6.4453125","0","26324","0","0","3.234375","14.046875","10","194","0","0"
+"1","block","233","2026-09-29T01:54:00.0144728Z","233.0077027","0.996403700000002","38.0859375","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","234","2026-09-29T01:54:01.0116236Z","234.0043652","0.996662500000014","29.6875","0","26324","0","0","3.234375","14.05078125","10","194","0","0"
+"1","block","235","2026-09-29T01:54:02.0162788Z","235.0095751","1.00520989999998","10.546875","0","26324","0","0","3.203125","14.03515625","9","192","0","0"
+"1","block","236","2026-09-29T01:54:03.0178400Z","236.0112927","1.00171760000001","5.078125","0","26324","0","0","3.203125","14.03515625","9","192","0","0"
+"1","block","237","2026-09-29T01:54:04.0215305Z","237.0148292","1.0035365","8.203125","0","26324","0","0","3.23046875","14.04296875","10","192","0","0"
+"1","block","238","2026-09-29T01:54:05.0076272Z","238.0007646","0.985935400000017","5.95238095238095","0","26324","0","0","3.23046875","14.04296875","10","192","0","0"
+"1","block","239","2026-09-29T01:54:06.0167698Z","239.0100284","1.00926379999999","9.42307692307692","0.193519771540407","26324","0","0","3.23046875","14.04296875","10","192","0","0"
+"1","block","240","2026-09-29T01:54:07.0168159Z","240.0039071","0.99387870000001","30.1369863013699","0","26324","0","0","3.23046875","14.04296875","10","192","0","0"
+"1","block","241","2026-09-29T01:54:08.0230175Z","241.0166629","1.01275580000001","29.2397660818713","0","26324","0","0","3.23046875","14.04296875","10","192","0","0"
+"1","block","242","2026-09-29T01:54:09.0185213Z","242.0119019","0.995238999999998","11.328125","0.196246831163168","26324","0","0","3.23046875","14.04296875","10","192","0","0"
+"1","block","243","2026-09-29T01:54:10.0162586Z","243.0094773","0.997575399999988","9.5703125","0","26324","0","0","3.23046875","14.04296875","10","192","0","0"
+"1","block","244","2026-09-29T01:54:11.0153199Z","244.0086564","0.999179099999992","6.0546875","0","26324","0","0","3.23046875","14.04296875","10","192","0","0"
+"1","block","245","2026-09-29T01:54:12.0180273Z","245.011282","1.00262560000002","7.2265625","0","26324","0","0","3.23046875","14.046875","10","192","0","0"
+"1","block","246","2026-09-29T01:54:13.0160941Z","246.0092505","0.997968499999985","13.4765625","0","26324","0","0","3.23046875","14.046875","10","192","0","0"
+"1","block","247","2026-09-29T01:54:14.0121636Z","247.0053733","0.996122800000023","7.03125","0","26324","0","0","3.23046875","14.05078125","10","192","0","0"
+"1","block","248","2026-09-29T01:54:15.0125953Z","248.0058004","1.0004271","8.59375","0","26324","0","0","3.23046875","14.05078125","10","192","0","0"
+"1","block","249","2026-09-29T01:54:16.0184202Z","249.0116215","1.00582109999999","5.859375","0","26324","0","0","3.23046875","14.05078125","10","192","0","0"
+"1","block","250","2026-09-29T01:54:17.0176599Z","250.0107704","0.999148899999994","6.25","0","26324","0","0","3.23046875","14.05078125","10","192","0","0"
+"1","block","251","2026-09-29T01:54:18.0162908Z","251.0095444","0.998773999999997","6.4453125","0","26324","0","0","3.23046875","14.05078125","10","192","0","0"
+"1","block","252","2026-09-29T01:54:19.0175068Z","252.0107135","1.0011691","5.6640625","0","26324","0","0","3.23046875","14.05078125","10","192","0","0"
+"1","block","253","2026-09-29T01:54:20.0326456Z","253.0258839","1.01517040000002","5.96153846153846","0","26324","0","0","3.23046875","14.05078125","10","192","0","0"
+"1","block","254","2026-09-29T01:54:21.0180995Z","254.0112491","0.98536519999999","5.55555555555556","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","255","2026-09-29T01:54:22.0204024Z","255.0136977","1.00244860000001","5.2734375","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","256","2026-09-29T01:54:23.0206574Z","256.0139168","1.00021910000001","5.6640625","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","257","2026-09-29T01:54:24.0215091Z","257.0146489","1.00073209999999","5.6640625","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","258","2026-09-29T01:54:25.0197878Z","258.012945","0.998296100000005","8.984375","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","259","2026-09-29T01:54:26.0179784Z","259.0113306","0.998385600000006","5.078125","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","260","2026-09-29T01:54:27.0151015Z","260.0082653","0.996934699999997","5.46875","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","261","2026-09-29T01:54:28.0153833Z","261.008569","1.00030369999996","5.46875","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","262","2026-09-29T01:54:29.0157599Z","262.0091115","1.00054249999999","7.6171875","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","263","2026-09-29T01:54:30.0219607Z","263.0153151","1.00620360000005","7.2265625","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","264","2026-09-29T01:54:31.0078514Z","264.0011142","0.985799099999952","6.54761904761905","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","265","2026-09-29T01:54:32.0196656Z","265.0130011","1.01188690000004","5.38461538461539","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","266","2026-09-29T01:54:33.0191191Z","266.0123679","0.999366800000018","4.1015625","0","26324","0","0","3.23046875","14.0546875","10","192","0","0"
+"1","block","267","2026-09-29T01:54:34.0178138Z","267.0111006","0.998732699999948","6.25","0","26324","0","0","3.31640625","14.24609375","13","194","0","0"
+"1","block","268","2026-09-29T01:54:35.0101442Z","268.0035043","0.992403700000011","11.9047619047619","0","26324","0","0","3.31640625","14.24609375","13","194","0","0"
+"1","block","269","2026-09-29T01:54:36.0099848Z","269.0031678","0.999663499999997","14.0625","0.195378244779369","26324","0","0","3.31640625","14.24609375","13","194","0","0"
+"1","block","270","2026-09-29T01:54:37.0119785Z","270.00526","1.00209219999999","7.5","0.194904720344097","26324","0","0","3.31640625","14.24609375","13","194","0","0"
+"1","block","271","2026-09-29T01:54:38.0120387Z","271.0053304","1.00007040000003","9.9609375","0","26324","0","0","3.31640625","14.24609375","13","194","0","0"
+"1","block","272","2026-09-29T01:54:39.0073644Z","272.0006048","0.995274399999971","11.9047619047619","0","26324","0","0","3.3359375","14.25","13","194","0","0"
+"1","block","273","2026-09-29T01:54:40.0175873Z","273.0108277","1.01022290000003","9.61538461538461","0","26324","0","0","3.3359375","14.25","13","194","0","0"
+"1","block","274","2026-09-29T01:54:41.0195103Z","274.0128971","1.00206939999998","7.03125","0","26324","0","0","3.3359375","14.25","13","194","0","0"
+"1","block","275","2026-09-29T01:54:42.0136035Z","275.0069188","0.994021700000019","7.8125","0","26324","0","0","3.3359375","14.25","13","194","0","0"
+"1","block","276","2026-09-29T01:54:43.0201958Z","276.0134221","1.00650330000002","7.03125","0","26324","0","0","3.3359375","14.25","13","194","0","0"
+"1","block","277","2026-09-29T01:54:44.0197933Z","277.0132349","0.999812799999972","3.90625","0","26324","0","0","3.3359375","14.25390625","13","194","0","0"
+"1","block","278","2026-09-29T01:54:45.0184959Z","278.0117769","0.998541999999986","10.3515625","0","26324","0","0","3.3359375","14.2578125","13","194","0","0"
+"1","block","279","2026-09-29T01:54:46.0189668Z","279.0121767","1.00039980000003","6.8359375","0","26324","0","0","3.3359375","14.2578125","13","194","0","0"
+"1","block","280","2026-09-29T01:54:47.0179619Z","280.0118633","0.999686599999961","5.2734375","0","26324","0","0","3.3359375","14.26171875","13","194","0","0"
+"1","block","281","2026-09-29T01:54:48.0221755Z","281.015455","1.00359170000002","5.859375","0","26324","0","0","3.3359375","14.265625","13","194","0","0"
+"1","block","282","2026-09-29T01:54:49.0071782Z","282.0004493","0.984994300000039","6.34920634920635","0","26324","0","0","3.3359375","14.265625","13","194","0","0"
+"1","block","283","2026-09-29T01:54:50.0104204Z","283.0037191","1.0032698","9.375","0.194675948583323","26324","0.015625","0.194675948583323","3.3359375","14.265625","13","194","0","0"
+"1","block","284","2026-09-29T01:54:51.0127547Z","284.0061244","1.00240529999996","9.03846153846154","0.194843842106588","26324","0","0","3.3359375","14.265625","13","194","0","0"
+"1","block","285","2026-09-29T01:54:52.0162198Z","285.0088923","1.00276790000004","4.8828125","0","26324","0","0","3.3359375","14.265625","13","194","0","0"
+"1","block","286","2026-09-29T01:54:53.0132190Z","286.0065234","0.997631099999978","5.6640625","0","26324","0","0","3.3359375","14.265625","13","194","0","0"
+"1","block","287","2026-09-29T01:54:54.0118872Z","287.0050945","0.998571099999992","8.0078125","0","26324","0","0","3.3359375","14.265625","13","194","0","0"
+"1","block","288","2026-09-29T01:54:55.0091671Z","288.0025651","0.997470599999986","28.3730158730159","0","26324","0","0","3.3359375","14.265625","13","194","0","0"
+"1","block","289","2026-09-29T01:54:56.0080015Z","289.0014491","0.998884000000032","9.5703125","0.195530712274892","26324","0.015625","0.195530712274892","3.3359375","14.265625","13","194","0","0"
+"1","block","290","2026-09-29T01:54:57.0104125Z","290.0036108","1.00216169999999","15.0390625","0.194891203684997","26324","0","0","3.3359375","14.265625","13","194","0","0"
+"1","block","291","2026-09-29T01:54:58.0208331Z","291.0140577","1.01044689999998","7.69230769230769","0.193293185421227","26324","0","0","3.359375","14.26953125","13","194","0","0"
+"1","block","292","2026-09-29T01:54:59.0221212Z","292.0149807","1.000923","6.640625","0","26324","0","0","3.359375","14.26953125","13","194","0","0"
+"1","block","293","2026-09-29T01:55:00.0059016Z","292.9990447","0.984064000000046","6.54761904761905","0","26324","0","0","3.359375","14.26953125","13","194","0","0"
+"1","block","294","2026-09-29T01:55:01.0098050Z","294.0029573","1.00391259999998","7.03125","0","26324","0","0","3.359375","14.26953125","13","194","0","0"
+"1","block","295","2026-09-29T01:55:02.0102771Z","295.0036966","1.00073930000002","13.4765625","0.19516821214076","26324","0","0","3.359375","14.26953125","13","194","0","0"
+"1","block","296","2026-09-29T01:55:03.0089979Z","296.0021633","0.998466699999994","10.546875","0.195612432542819","26324","0","0","3.359375","14.26953125","13","194","0","0"
+"1","block","297","2026-09-29T01:55:04.0089192Z","297.0021314","0.99996809999999","9.1796875","0.19531873066751","26324","0","0","3.31640625","14.24609375","13","194","0","0"
+"1","block","298","2026-09-29T01:55:05.0107290Z","298.0038884","1.001757","17.1875","0.194969937819252","26324","0","0","3.31640625","14.24609375","13","194","0","0"
+"1","block","299","2026-09-29T01:55:06.0141624Z","299.0074673","1.00357889999998","8.26923076923077","0.194615988837553","26324","0","0","3.31640625","14.24609375","13","194","0","0"
+"1","block","300","2026-09-29T01:55:07.0167435Z","300.0099228","1.0024555","4.8828125","0","26324","0","0","3.31640625","14.24609375","13","194","0","0"
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow-end.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow-end.json
new file mode 100644
index 0000000..14f27af
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow-end.json
@@ -0,0 +1,12 @@
+{
+ "state": "allow",
+ "layers": {
+ "shutdown": false,
+ "local_shutdown": false,
+ "update": false,
+ "remote": false,
+ "sleep": false
+ },
+ "uptime_seconds": 333,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow-start.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow-start.json
new file mode 100644
index 0000000..d41852d
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow-start.json
@@ -0,0 +1,12 @@
+{
+ "state": "allow",
+ "layers": {
+ "shutdown": false,
+ "local_shutdown": false,
+ "update": false,
+ "remote": false,
+ "sleep": false
+ },
+ "uptime_seconds": 32,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow.csv
new file mode 100644
index 0000000..7503b19
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-allow.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"2","allow","1","2026-09-29T01:55:41.1597410Z","1.0138575","1.0138529","7.88461538461539","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","2","2026-09-29T01:55:42.1508300Z","2.0048799","0.9910224","12.1031746031746","0","18792","0.015625","0.19708182176306","2.04296875","12.6171875","8","176","0","0"
+"2","allow","3","2026-09-29T01:55:43.1554007Z","3.0094434","1.0045635","9.42307692307692","0.194425240415364","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","4","2026-09-29T01:55:44.1558182Z","4.0099261","1.0004827","5.2734375","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","5","2026-09-29T01:55:45.1526441Z","5.0065657","0.9966396","7.8125","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","6","2026-09-29T01:55:46.1526010Z","6.0067248","1.0001591","11.1328125","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","7","2026-09-29T01:55:47.1522362Z","7.0062575","0.9995327","6.25","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","8","2026-09-29T01:55:48.1534674Z","8.0074707","1.0012132","10.7421875","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","9","2026-09-29T01:55:49.1584820Z","9.0123148","1.0048441","6.8359375","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","10","2026-09-29T01:55:50.1580284Z","10.0121871","0.9998723","8.59375","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","11","2026-09-29T01:55:51.1608738Z","11.0148499","1.0026628","7.03125","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","12","2026-09-29T01:55:52.1592806Z","12.0133207","0.9984708","5.078125","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","13","2026-09-29T01:55:53.1488296Z","13.0031043","0.989783599999999","5.95238095238095","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","14","2026-09-29T01:55:54.1618868Z","14.0159025","1.0127982","10","0.192844438309626","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","15","2026-09-29T01:55:55.1616906Z","15.0158512","0.999948700000001","5.2734375","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","16","2026-09-29T01:55:56.1601516Z","16.014194","0.9983428","8.984375","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","17","2026-09-29T01:55:57.1597358Z","17.0138637","0.999669699999998","6.25","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","18","2026-09-29T01:55:58.1621085Z","18.0163541","1.0024904","7.8125","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","19","2026-09-29T01:55:59.1494402Z","19.00345","0.9870959","5.55555555555556","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","20","2026-09-29T01:56:00.1515057Z","20.0055328","1.0020828","7.6171875","0.194906548640492","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","21","2026-09-29T01:56:01.1482045Z","21.002346","0.996813200000002","7.8125","0.195936911750366","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","22","2026-09-29T01:56:02.1499629Z","22.0038952","1.0015492","8.59375","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","23","2026-09-29T01:56:03.1477330Z","23.0018673","0.997972100000002","9.1796875","0.195709379049775","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","24","2026-09-29T01:56:04.1485416Z","24.0025369","1.0006696","5.2734375","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","25","2026-09-29T01:56:05.1535730Z","25.0075326","1.0049957","9.80769230769231","0.194341627531342","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","26","2026-09-29T01:56:06.1528844Z","26.0069271","0.999394500000001","8.984375","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","27","2026-09-29T01:56:07.1503358Z","27.0044125","0.997485399999999","10.3174603174603","0","18792","0","0","2.04296875","12.6171875","8","176","0","0"
+"2","allow","28","2026-09-29T01:56:08.1491049Z","28.0031996","0.998787100000001","6.4453125","0.195549682209552","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","29","2026-09-29T01:56:09.1529527Z","29.0069391","1.0037395","8.84615384615385","0.194584849953598","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","30","2026-09-29T01:56:10.1560393Z","30.0103754","1.0034363","7.6171875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","31","2026-09-29T01:56:11.1550646Z","31.0091623","0.998786900000002","7.85854616895874","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","32","2026-09-29T01:56:12.1530649Z","32.0070872","0.997924900000001","7.57281553398058","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","33","2026-09-29T01:56:13.1578098Z","33.011947","1.0048598","7.2265625","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","34","2026-09-29T01:56:14.1585517Z","34.0125131","1.0005661","33.3984375","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","35","2026-09-29T01:56:15.1553451Z","35.0095376","0.997024500000002","20.7436399217221","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","36","2026-09-29T01:56:16.1516404Z","36.00563","0.996092399999995","20.0392927308448","0.196078697116855","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","37","2026-09-29T01:56:17.1477128Z","37.0018049","0.9961749","8.26771653543307","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","38","2026-09-29T01:56:18.1615796Z","38.0157228","1.0139179","9.80769230769231","0.192631474402414","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","39","2026-09-29T01:56:19.1469520Z","39.0009396","0.985216799999996","6.54761904761905","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","40","2026-09-29T01:56:20.1492744Z","40.0032668","1.0023272","8.203125","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","41","2026-09-29T01:56:21.1537357Z","41.0077667","1.0044999","7.69230769230769","0.194437550466655","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","42","2026-09-29T01:56:22.1513816Z","42.0053592","0.997592500000003","14.0873015873016","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","43","2026-09-29T01:56:23.1496352Z","43.0037161","0.998356899999997","9.9609375","0.195633946136898","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","44","2026-09-29T01:56:24.1512260Z","44.0054399","1.0017238","8.38206627680312","0.194976399682228","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","45","2026-09-29T01:56:25.1504676Z","45.0046411","0.999201200000002","15.6555772994129","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","46","2026-09-29T01:56:26.1488678Z","46.0030159","0.998374800000001","14.6484375","0.195630438588794","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","47","2026-09-29T01:56:27.1509809Z","47.0051177","1.0021018","7.03125","0.19490285318318","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","48","2026-09-29T01:56:28.1530223Z","48.0070701","1.0019524","4.23076923076923","0.194931914929292","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","49","2026-09-29T01:56:29.1525699Z","49.0066702","0.999600099999995","10.3515625","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","50","2026-09-29T01:56:30.1561996Z","50.0103636","1.0036934","8.0078125","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","51","2026-09-29T01:56:31.1516351Z","51.0055749","0.995211300000001","23.7254901960784","0.196252293357199","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","52","2026-09-29T01:56:32.1494882Z","52.0035252","0.997950299999999","20.5533596837945","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","53","2026-09-29T01:56:33.1529178Z","53.0069854","1.0034602","16.3461538461538","0.194639010097262","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","54","2026-09-29T01:56:34.1578159Z","54.0119671","1.0049817","10.7421875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","55","2026-09-29T01:56:35.1479782Z","55.002413","0.990445899999997","3.96825396825397","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","56","2026-09-29T01:56:36.1467319Z","56.0008954","0.9984824","10.3515625","0.195609356759819","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","57","2026-09-29T01:56:37.1596526Z","57.0137987","1.0129033","4.42307692307692","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","58","2026-09-29T01:56:38.1591387Z","58.0131661","0.999367400000004","7.6171875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","59","2026-09-29T01:56:39.1584502Z","59.0125607","0.999394599999995","5.46875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","60","2026-09-29T01:56:40.1580408Z","60.0122779","0.999717199999999","8.7890625","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","61","2026-09-29T01:56:41.1590668Z","61.0131955","1.0009176","6.0546875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","62","2026-09-29T01:56:42.1568288Z","62.0107948","0.997599300000005","8.203125","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","63","2026-09-29T01:56:43.1594430Z","63.013007","1.0022122","6.0546875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","64","2026-09-29T01:56:44.1533425Z","64.0075233","0.994516300000008","10.7421875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","65","2026-09-29T01:56:45.1547814Z","65.0087531","1.00122979999999","26.3671875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","66","2026-09-29T01:56:46.1543613Z","66.0084322","0.999679100000009","9.765625","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","67","2026-09-29T01:56:47.1526658Z","67.0066252","0.998193000000001","8.203125","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","68","2026-09-29T01:56:48.1508142Z","68.0048205","0.998195299999992","13.8888888888889","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","69","2026-09-29T01:56:49.1485968Z","69.0028436","0.998023099999997","10.3515625","0.195699378100568","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","70","2026-09-29T01:56:50.1488508Z","70.0028886","1.000045","6.8359375","0.19530371133299","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","71","2026-09-29T01:56:51.1536636Z","71.0078288","1.00494020000001","8.46153846153846","0.194352360468811","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","72","2026-09-29T01:56:52.1510979Z","72.0051655","0.997336699999991","8.94632206759443","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","73","2026-09-29T01:56:53.1562801Z","73.0102686","1.00510310000001","6.71785028790787","0.194320861213141","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","74","2026-09-29T01:56:54.1547316Z","74.0087887","0.998520099999993","7.2265625","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","75","2026-09-29T01:56:55.1572073Z","75.0112212","1.0024325","6.640625","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","76","2026-09-29T01:56:56.1595289Z","76.0137797","1.00255850000001","9.5703125","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","77","2026-09-29T01:56:57.1489456Z","77.003138","0.989358299999992","5.35714285714286","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","78","2026-09-29T01:56:58.1609680Z","78.0149924","1.0118544","5.96153846153846","0.193024312588846","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","79","2026-09-29T01:56:59.1481458Z","79.0023443","0.987351899999993","6.34920634920635","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","80","2026-09-29T01:57:00.1513353Z","80.0048368","1.0024925","15.4296875","0.194826893966787","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","81","2026-09-29T01:57:01.1500420Z","81.0042349","0.999398100000008","9.5703125","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","82","2026-09-29T01:57:02.1495848Z","82.0036799","0.999444999999994","8.203125","0.195420958632042","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","83","2026-09-29T01:57:03.1489525Z","83.0029974","0.999317500000004","7.6171875","0.195445891821167","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","84","2026-09-29T01:57:04.1580787Z","84.0122889","1.0092915","8.84615384615385","0.193514460391274","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","85","2026-09-29T01:57:05.1505954Z","85.0047017","0.992412799999997","7.93650793650794","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","86","2026-09-29T01:57:06.1495118Z","86.0035615","0.998859799999991","18.5546875","0.195535449519544","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","87","2026-09-29T01:57:07.1490279Z","87.0031812","0.999619700000011","8.984375","0.195386805602168","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","88","2026-09-29T01:57:08.1546147Z","88.0086968","1.0055156","10.5769230769231","0.194241143548644","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","89","2026-09-29T01:57:09.1531179Z","89.0072557","0.998558900000006","5.6640625","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","90","2026-09-29T01:57:10.1515855Z","90.0056838","0.998428099999998","10.6508875739645","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","91","2026-09-29T01:57:11.1530939Z","91.0071563","1.00147249999999","14.8936170212766","0.195025325208632","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","92","2026-09-29T01:57:12.1571982Z","92.0114334","1.00427710000001","5.46875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","93","2026-09-29T01:57:13.1568738Z","93.0109966","0.999563199999997","8.984375","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","94","2026-09-29T01:57:14.1533318Z","94.007345","0.996348400000002","7.6171875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","95","2026-09-29T01:57:15.1541590Z","95.0082882","1.00094319999999","6.25","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","96","2026-09-29T01:57:16.1577011Z","96.0116275","1.00333929999999","8.3984375","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","97","2026-09-29T01:57:17.1584558Z","97.012462","1.00083450000001","10.7421875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","98","2026-09-29T01:57:18.1463143Z","98.0003824","0.987920399999993","6.74603174603175","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","99","2026-09-29T01:57:19.1489378Z","99.002973","1.0025906","6.0546875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","100","2026-09-29T01:57:20.1534354Z","100.0074675","1.00449449999999","8.65384615384615","0.194438595731486","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","101","2026-09-29T01:57:21.1522007Z","101.0057995","0.998332000000005","10.546875","0","18792","0","0","2.015625","12.6015625","7","176","0","0"
+"2","allow","102","2026-09-29T01:57:22.1576829Z","102.0116326","1.0058331","10.3515625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","103","2026-09-29T01:57:23.1544071Z","103.0084574","0.996824799999999","6.0546875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","104","2026-09-29T01:57:24.1559208Z","104.0101353","1.0016779","4.296875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","105","2026-09-29T01:57:25.1529527Z","105.0071301","0.996994799999996","7.03125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","106","2026-09-29T01:57:26.1543309Z","106.0083381","1.00120799999999","8.59375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","107","2026-09-29T01:57:27.1549725Z","107.0089678","1.0006297","7.6171875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","108","2026-09-29T01:57:28.1552026Z","108.0092389","1.00027110000001","5.46875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","109","2026-09-29T01:57:29.1537650Z","109.0078126","0.998573699999994","7.8125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","110","2026-09-29T01:57:30.1488630Z","110.0027731","0.994960500000005","12.3015873015873","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","111","2026-09-29T01:57:31.1489540Z","111.0030241","1.00025099999999","8.3984375","0.195263488864297","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","112","2026-09-29T01:57:32.1567533Z","112.0109065","1.0078824","7.5","0.193785009044706","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","113","2026-09-29T01:57:33.1467093Z","113.0008414","0.989934900000009","5.35714285714286","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","114","2026-09-29T01:57:34.1480495Z","114.0021392","1.00129779999999","7.8125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","115","2026-09-29T01:57:35.1475649Z","115.0015642","0.999425000000002","7.05882352941176","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","116","2026-09-29T01:57:36.1615844Z","116.0156348","1.01407060000001","5.74712643678161","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","117","2026-09-29T01:57:37.1480830Z","117.0022121","0.986577299999993","10.1190476190476","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","118","2026-09-29T01:57:38.1501642Z","118.0042326","1.0020205","8.59375","0.194918666833662","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","119","2026-09-29T01:57:39.1466708Z","119.0006789","0.996446300000002","9.765625","0.196009057387237","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","120","2026-09-29T01:57:40.1589446Z","120.0130819","1.01240299999999","9.42307692307692","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","121","2026-09-29T01:57:41.1466286Z","121.0005954","0.987513500000006","6.34920634920635","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","122","2026-09-29T01:57:42.1479656Z","122.0019878","1.0013924","6.8359375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","123","2026-09-29T01:57:43.1502308Z","123.00433","1.0023422","5.46875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","124","2026-09-29T01:57:44.1517748Z","124.0058581","1.0015281","11.7307692307692","0.195014498345079","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","125","2026-09-29T01:57:45.1544804Z","125.0086458","1.0027877","9.375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","126","2026-09-29T01:57:46.1550859Z","126.0092923","1.0006465","6.640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","127","2026-09-29T01:57:47.1564696Z","127.0101391","1.00084679999999","10.546875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","128","2026-09-29T01:57:48.1508452Z","128.0050164","0.994877299999999","4.96031746031746","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","129","2026-09-29T01:57:49.1571746Z","129.0111839","1.0061675","7.5","0.194115293924719","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","130","2026-09-29T01:57:50.1584955Z","130.0125119","1.001328","8.3984375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","131","2026-09-29T01:57:51.1616335Z","131.0153105","1.00279860000001","4.4921875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","132","2026-09-29T01:57:52.1474139Z","132.0014972","0.98618669999999","7.73809523809524","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","133","2026-09-29T01:57:53.1502449Z","133.0042659","1.00276870000002","7.03125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","134","2026-09-29T01:57:54.1535935Z","134.008172","1.00390609999999","14.2307692307692","0.194552558252212","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","135","2026-09-29T01:57:55.1516068Z","135.0057875","0.997615499999995","8.03921568627451","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","136","2026-09-29T01:57:56.1476710Z","136.0016431","0.995855599999999","9.48616600790514","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","137","2026-09-29T01:57:57.1563370Z","137.0106135","1.00897040000001","10.1923076923077","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","138","2026-09-29T01:57:58.1621885Z","138.0162181","1.0056046","6.640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","139","2026-09-29T01:57:59.1601128Z","139.0141637","0.99794559999998","5.078125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","140","2026-09-29T01:58:00.1504229Z","140.0044985","0.990334799999999","8.33333333333333","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","141","2026-09-29T01:58:01.1531714Z","141.0071582","1.00265970000001","12.3076923076923","0.194794405320168","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","142","2026-09-29T01:58:02.1548270Z","142.0089445","1.00178629999999","6.25","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","143","2026-09-29T01:58:03.1555770Z","143.0097268","1.0007823","5.859375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","144","2026-09-29T01:58:04.1595892Z","144.0138015","1.00407470000002","5.2734375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","145","2026-09-29T01:58:05.1624861Z","145.0165976","1.00279609999998","5.6640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","146","2026-09-29T01:58:06.1485981Z","146.0027154","0.986117800000017","8.73015873015873","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","147","2026-09-29T01:58:07.1470709Z","147.0012908","0.998575399999993","8.7890625","0.195591139136816","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","148","2026-09-29T01:58:08.1476790Z","148.001862","1.0005712","5.46875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","149","2026-09-29T01:58:09.1501053Z","149.0041771","1.0023151","8.203125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","150","2026-09-29T01:58:10.1620126Z","150.0160641","1.011887","10.1923076923077","0.193018093917601","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","151","2026-09-29T01:58:11.1611342Z","151.0151679","0.9991038","5.46875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","152","2026-09-29T01:58:12.1516016Z","152.0056449","0.990476999999998","18.5770750988142","0.197190343642508","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","153","2026-09-29T01:58:13.1551338Z","153.0092177","1.0035728","16.2162162162162","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","154","2026-09-29T01:58:14.1558405Z","154.0100298","1.00081209999999","7.82778864970646","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","155","2026-09-29T01:58:15.1558226Z","155.009981","0.999951199999998","4.87329434697856","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","156","2026-09-29T01:58:16.1517968Z","156.0058327","0.995851700000003","10.15625","0.19612608985856","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","157","2026-09-29T01:58:17.1478903Z","157.0020006","0.996167900000017","30.7539682539683","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","158","2026-09-29T01:58:18.1580592Z","158.012125","1.0101244","20.3846153846154","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","159","2026-09-29T01:58:19.1535329Z","159.0076272","0.995502200000004","46.09375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","160","2026-09-29T01:58:20.1478960Z","160.0019202","0.994292999999999","16.468253968254","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","161","2026-09-29T01:58:21.1584305Z","161.0126287","1.01070849999999","8.26923076923077","0.193243155667536","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","162","2026-09-29T01:58:22.1606496Z","162.0148222","1.0021935","6.4453125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","163","2026-09-29T01:58:23.1592001Z","163.0132334","0.998411199999993","6.0546875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","164","2026-09-29T01:58:24.1489072Z","164.0029124","0.989678999999995","22.8174603174603","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","165","2026-09-29T01:58:25.1545445Z","165.0085265","1.0056141","22.6923076923077","0.194222117609528","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","166","2026-09-29T01:58:26.1475684Z","166.0017118","0.993185299999993","37.6984126984127","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","167","2026-09-29T01:58:27.1591312Z","167.0131577","1.01144590000001","15.1923076923077","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","168","2026-09-29T01:58:28.1481021Z","168.0022044","0.989046699999989","7.53968253968254","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","169","2026-09-29T01:58:29.1587448Z","169.012884","1.0106796","7.88461538461539","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","170","2026-09-29T01:58:30.1568116Z","170.0108201","0.997936100000004","4.8828125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","171","2026-09-29T01:58:31.1564115Z","171.0105043","0.99968419999999","4.4921875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","172","2026-09-29T01:58:32.1591158Z","172.0131361","1.00263180000002","6.4453125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","173","2026-09-29T01:58:33.1577778Z","173.0118104","0.998674300000005","8.59375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","174","2026-09-29T01:58:34.1540424Z","174.0081823","0.996371899999986","7.84313725490196","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","175","2026-09-29T01:58:35.1539666Z","175.0080992","0.999916900000017","4.28015564202335","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","176","2026-09-29T01:58:36.1572175Z","176.0113235","1.0032243","5.6640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","177","2026-09-29T01:58:37.1476033Z","177.0016818","0.990358299999997","7.34126984126984","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","178","2026-09-29T01:58:38.1613603Z","178.0154466","1.01376479999999","9.03846153846154","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","179","2026-09-29T01:58:39.1604617Z","179.0146968","0.999250200000006","6.0546875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","180","2026-09-29T01:58:40.1578112Z","180.0118031","0.997106299999984","5.6640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","181","2026-09-29T01:58:41.1560569Z","181.0101992","0.998396100000008","11.1328125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","182","2026-09-29T01:58:42.1554186Z","182.0094369","0.999237700000009","6.4453125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","183","2026-09-29T01:58:43.1492594Z","183.0036421","0.994205199999982","24.8015873015873","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","184","2026-09-29T01:58:44.1580145Z","184.0119732","1.00833110000002","17.5","0.193698776126211","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","185","2026-09-29T01:58:45.1575465Z","185.0115391","0.999565899999993","7.8125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","186","2026-09-29T01:58:46.1540256Z","186.0080816","0.996542500000004","6.8359375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","187","2026-09-29T01:58:47.1562684Z","187.0103923","1.00231069999998","6.640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","188","2026-09-29T01:58:48.1603465Z","188.0145517","1.00415940000002","10.15625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","189","2026-09-29T01:58:49.1504580Z","189.0045898","0.990038099999992","8.92857142857143","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","190","2026-09-29T01:58:50.1478038Z","190.0020249","0.99743509999999","11.328125","0.195814745240068","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","191","2026-09-29T01:58:51.1471695Z","191.0014363","0.999411400000014","4.1015625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","192","2026-09-29T01:58:52.1488060Z","192.0024062","1.0009699","6.640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","193","2026-09-29T01:58:53.1477332Z","193.0018223","0.999416099999991","10.3515625","0.195426609597346","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","194","2026-09-29T01:58:54.1475884Z","194.0016805","0.999858200000006","8.3984375","0.195340199240251","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","195","2026-09-29T01:58:55.1580052Z","195.012162","1.0104815","4.80769230769231","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","196","2026-09-29T01:58:56.1577717Z","196.0119047","0.999742700000013","8.59375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","197","2026-09-29T01:58:57.1592382Z","197.013394","1.0014893","10.9375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","198","2026-09-29T01:58:58.1545104Z","198.0086071","0.995213099999972","8.41487279843444","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","199","2026-09-29T01:58:59.1534366Z","199.007513","0.998905900000011","7.99220272904483","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","200","2026-09-29T01:59:00.1503494Z","200.0043516","0.99683859999999","12.1031746031746","0","18792","0.015625","0.195931919169264","1.95703125","12.578125","5","174","0","0"
+"2","allow","201","2026-09-29T01:59:01.1562291Z","201.0102653","1.00591370000001","7.5","0.194164270752052","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","202","2026-09-29T01:59:02.1617386Z","202.0157273","1.00546199999999","7.421875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","203","2026-09-29T01:59:03.1499594Z","203.0040452","0.988317899999998","7.14285714285714","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","204","2026-09-29T01:59:04.1535445Z","204.0070786","1.00303340000002","11.3461538461538","0.194721830798452","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","205","2026-09-29T01:59:05.1540378Z","205.0081762","1.00109759999998","7.03125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","206","2026-09-29T01:59:06.1591858Z","206.0133327","1.0051565","5.6640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","207","2026-09-29T01:59:07.1474451Z","207.0014862","0.98815350000001","5.55555555555556","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","208","2026-09-29T01:59:08.1505829Z","208.0046359","1.00314969999999","11.1328125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","209","2026-09-29T01:59:09.1511429Z","209.0053082","1.00067230000002","18.75","0.195181279625704","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","210","2026-09-29T01:59:10.1489323Z","210.0030055","0.997697299999999","8.7890625","0.19576328411433","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","211","2026-09-29T01:59:11.1591813Z","211.0132098","1.0102043","8.65384615384615","0.193339604672045","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","212","2026-09-29T01:59:12.1585893Z","212.012773","0.999563199999983","8.59375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","213","2026-09-29T01:59:13.1574556Z","213.0116879","0.998914900000017","7.2265625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","214","2026-09-29T01:59:14.1523618Z","214.0065587","0.994870800000001","17.3828125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","215","2026-09-29T01:59:15.1550756Z","215.0090851","1.00252639999999","11.9140625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","216","2026-09-29T01:59:16.1586804Z","216.0127701","1.00368499999999","4.8828125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","217","2026-09-29T01:59:17.1612082Z","217.0148067","1.0020366","8.59375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","218","2026-09-29T01:59:18.1465915Z","218.0006537","0.985847000000007","9.92063492063492","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","219","2026-09-29T01:59:19.1514244Z","219.0055104","1.0048567","9.49612403100775","0.194368510455271","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","220","2026-09-29T01:59:20.1485598Z","220.0025427","0.997032300000001","7.08661417322835","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","221","2026-09-29T01:59:21.1613986Z","221.0155136","1.0129709","9.03846153846154","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","222","2026-09-29T01:59:22.1469543Z","222.0009815","0.985467900000003","5.15873015873016","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","223","2026-09-29T01:59:23.1508769Z","223.0052656","1.00428410000001","6.0546875","0.194479331097643","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","224","2026-09-29T01:59:24.1606619Z","224.0148298","1.0095642","8.46153846153846","0.193462188932611","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","225","2026-09-29T01:59:25.1581427Z","225.0121668","0.997336999999987","9.375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","226","2026-09-29T01:59:26.1590418Z","226.0132149","1.00104809999999","5.6640625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","227","2026-09-29T01:59:27.1622738Z","227.0162373","1.00302240000002","5.2734375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","228","2026-09-29T01:59:28.1473430Z","228.0014727","0.985235399999993","9.52380952380952","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","229","2026-09-29T01:59:29.1506822Z","229.0047514","1.00327870000001","9.1796875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","230","2026-09-29T01:59:30.1522289Z","230.0065367","1.00178529999999","11.1538461538462","0.194964430003117","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","231","2026-09-29T01:59:31.1497925Z","231.0038788","0.997342099999997","11.1111111111111","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","232","2026-09-29T01:59:32.1471094Z","232.001157","0.997278199999982","6.25","0.195845552424593","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","233","2026-09-29T01:59:33.1493096Z","233.0033896","1.00223260000001","7.421875","0.194877416679519","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","234","2026-09-29T01:59:34.1601084Z","234.0141869","1.01079730000001","5.76923076923077","0.193226178977722","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","235","2026-09-29T01:59:35.1520925Z","235.0062513","0.992064400000004","7.421875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","236","2026-09-29T01:59:36.1543723Z","236.0083727","1.00212139999999","16.2109375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","237","2026-09-29T01:59:37.1570245Z","237.0111144","1.0027417","9.375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","238","2026-09-29T01:59:38.1557162Z","238.0098401","0.998725699999994","9.9609375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","239","2026-09-29T01:59:39.1552725Z","239.0093268","0.999486700000006","5.078125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","240","2026-09-29T01:59:40.1548707Z","240.0089331","0.999606299999982","15.0390625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","241","2026-09-29T01:59:41.1565590Z","241.0105921","1.00165900000002","12.3046875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","242","2026-09-29T01:59:42.1581329Z","242.012172","1.0015799","4.8828125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","243","2026-09-29T01:59:43.1468236Z","243.0009527","0.988780700000007","5.75396825396825","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","244","2026-09-29T01:59:44.1499666Z","244.0039236","1.00297089999998","5.87084148727984","0.19473396486379","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","245","2026-09-29T01:59:45.1498704Z","245.0039031","0.999979500000023","9.55165692007797","0.195316503988327","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","246","2026-09-29T01:59:46.1518026Z","246.005356","1.00145289999998","8.7890625","0.195029142159361","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","247","2026-09-29T01:59:47.1617900Z","247.0155652","1.01020920000002","9.42307692307692","0.193338666882064","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","248","2026-09-29T01:59:48.1611850Z","248.0152647","0.999699499999991","8.3984375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","249","2026-09-29T01:59:49.1600109Z","249.0141399","0.998875199999986","26.171875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","250","2026-09-29T01:59:50.1617810Z","250.0159225","1.00178260000001","4.8828125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","251","2026-09-29T01:59:51.1502839Z","251.0043226","0.988400100000007","5.35714285714286","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","252","2026-09-29T01:59:52.1478580Z","252.0014186","0.997095999999999","5.6640625","0.195881339409646","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","253","2026-09-29T01:59:53.1617186Z","253.0159289","1.01451029999998","8.84615384615385","0.1925189916751","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","254","2026-09-29T01:59:54.1512695Z","254.0052801","0.989351200000016","8.73015873015873","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","255","2026-09-29T01:59:55.1511715Z","255.0052637","0.999983600000007","12.890625","0.195315703177531","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","256","2026-09-29T01:59:56.1495369Z","256.0035646","0.998300900000004","6.640625","0.195644920284054","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","257","2026-09-29T01:59:57.1528453Z","257.0068387","1.0032741","16.3461538461538","0.19467511420857","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","258","2026-09-29T01:59:58.1581632Z","258.0123617","1.00552299999998","4.6875","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","259","2026-09-29T01:59:59.1491057Z","259.0032074","0.990845700000023","8.92857142857143","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","260","2026-09-29T02:00:00.1555694Z","260.0098907","1.00668329999996","9.80769230769231","0.19401583397679","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","261","2026-09-29T02:00:01.1532651Z","261.0073241","0.997433400000034","10.9375","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","262","2026-09-29T02:00:02.1618939Z","262.0161636","1.00883949999997","26.5625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","263","2026-09-29T02:00:03.1608751Z","263.0150076","0.99884400000002","7.2265625","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","264","2026-09-29T02:00:04.1483858Z","264.0023395","0.987331900000015","7.53968253968254","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","265","2026-09-29T02:00:05.1596240Z","265.0137268","1.01138729999997","7.88461538461539","0.193113459107116","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","266","2026-09-29T02:00:06.1566424Z","266.0106823","0.996955500000013","11.1328125","0","18792","0","0","1.95703125","12.578125","5","174","0","0"
+"2","allow","267","2026-09-29T02:00:07.1604689Z","267.0144256","1.0037433","8.3984375","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","268","2026-09-29T02:00:08.1573482Z","268.0113907","0.996965100000011","4.296875","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","269","2026-09-29T02:00:09.1584971Z","269.0124786","1.00108790000002","10.15625","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","270","2026-09-29T02:00:10.1475697Z","270.0011641","0.988685499999974","6.34920634920635","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","271","2026-09-29T02:00:11.1605953Z","271.0146034","1.01343930000002","8.84615384615385","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","272","2026-09-29T02:00:12.1571280Z","272.0113368","0.996733399999982","7.03125","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","273","2026-09-29T02:00:13.1537980Z","273.0079273","0.996590500000025","8.984375","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","274","2026-09-29T02:00:14.1614215Z","274.0154664","1.00753909999997","5.2734375","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","275","2026-09-29T02:00:15.1613096Z","275.0155655","1.0000991","5.6640625","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","276","2026-09-29T02:00:16.1517139Z","276.0056368","0.990071300000011","11.0453648915187","0.197271146027562","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","277","2026-09-29T02:00:17.1514595Z","277.0054052","0.999768399999994","10.4125736738703","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","278","2026-09-29T02:00:18.1500426Z","278.0041543","0.998749099999998","7.421875","0.195557122404416","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","279","2026-09-29T02:00:19.1593196Z","279.013396","1.00924170000002","18.4615384615385","0.193524009164501","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","280","2026-09-29T02:00:20.1499285Z","280.0040854","0.990689400000008","39.8809523809524","0","18792","0.015625","0.19714806679066","2.01953125","12.75390625","7","174","0","0"
+"2","allow","281","2026-09-29T02:00:21.1500154Z","281.0039997","0.9999143","18.75","0.195329239715844","18792","0.015625","0.195329239715844","2.01953125","12.75390625","7","174","0","0"
+"2","allow","282","2026-09-29T02:00:22.1500497Z","282.0041088","1.00010909999997","11.71875","0.195291193730769","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","283","2026-09-29T02:00:23.1610199Z","283.0151295","1.01102070000002","13.4615384615385","0.1931834827912","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","284","2026-09-29T02:00:24.1571718Z","284.0113466","0.996217099999967","11.1328125","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","285","2026-09-29T02:00:25.1575642Z","285.0117116","1.00036500000004","6.4453125","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","286","2026-09-29T02:00:26.1553877Z","286.0094574","0.997745799999961","6.0546875","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","287","2026-09-29T02:00:27.1562660Z","287.0102579","1.00080050000003","5.6640625","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","288","2026-09-29T02:00:28.1575803Z","288.0117568","1.0014989","5.46875","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","289","2026-09-29T02:00:29.1546076Z","289.0085441","0.996787299999994","11.71875","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","290","2026-09-29T02:00:30.1506444Z","290.0047097","0.996165599999983","9.52380952380952","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","291","2026-09-29T02:00:31.1523980Z","291.0065201","1.00181040000001","11.9230769230769","0.194959545239297","18792","0.015625","0.194959545239297","2.01953125","12.75390625","7","174","0","0"
+"2","allow","292","2026-09-29T02:00:32.1571280Z","292.0112396","1.00471950000002","9.375","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","293","2026-09-29T02:00:33.1533962Z","293.0070483","0.995808699999998","9.375","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","294","2026-09-29T02:00:34.1562065Z","294.0103124","1.00326409999997","5.2734375","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","295","2026-09-29T02:00:35.1598795Z","295.0139637","1.0036513","4.1015625","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","296","2026-09-29T02:00:36.1604439Z","296.0146476","1.00068390000001","6.25","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","297","2026-09-29T02:00:37.1590406Z","297.0131277","0.998480099999995","8.7890625","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","298","2026-09-29T02:00:38.1569606Z","298.01108","0.997952300000009","5.2734375","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","299","2026-09-29T02:00:39.1568502Z","299.0109047","0.999824699999976","8.59375","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
+"2","allow","300","2026-09-29T02:00:40.1504619Z","300.0045551","0.993650400000035","6.94444444444444","0","18792","0","0","2.01953125","12.75390625","7","174","0","0"
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-baseline.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-baseline.csv
new file mode 100644
index 0000000..991f8d9
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-baseline.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"2","baseline","1","2026-09-29T02:06:44.3847291Z","1.0066061","1.0066034","11.9373776908023","0","","","","","","","","",""
+"2","baseline","2","2026-09-29T02:06:45.3832162Z","2.0050419","0.9984358","9.16179337231969","0","","","","","","","","",""
+"2","baseline","3","2026-09-29T02:06:46.3842280Z","3.0060679","1.001026","10.7421875","0","","","","","","","","",""
+"2","baseline","4","2026-09-29T02:06:47.3961405Z","4.0179818","1.0119139","9.42307692307692","0","","","","","","","","",""
+"2","baseline","5","2026-09-29T02:06:48.3806658Z","5.0025749","0.984593100000001","5.55555555555556","0","","","","","","","","",""
+"2","baseline","6","2026-09-29T02:06:49.3787396Z","6.0005953","0.9980204","6.27450980392157","0","","","","","","","","",""
+"2","baseline","7","2026-09-29T02:06:50.3811691Z","7.0030368","1.0024415","7.00389105058366","0","","","","","","","","",""
+"2","baseline","8","2026-09-29T02:06:51.3917341Z","8.0136237","1.0105869","10.1923076923077","0","","","","","","","","",""
+"2","baseline","9","2026-09-29T02:06:52.3908220Z","9.0127049","0.999081199999999","6.640625","0","","","","","","","","",""
+"2","baseline","10","2026-09-29T02:06:53.3855744Z","10.0074693","0.994764400000001","8.73015873015873","0","","","","","","","","",""
+"2","baseline","11","2026-09-29T02:06:54.3856377Z","11.0075831","1.0001138","11.1328125","0.195290275966595","","","","","","","","",""
+"2","baseline","12","2026-09-29T02:06:55.3871123Z","12.0090646","1.0014815","10.1923076923077","0.195023572577227","","","","","","","","",""
+"2","baseline","13","2026-09-29T02:06:56.3878102Z","13.009695","1.0006304","10.7421875","0","","","","","","","","",""
+"2","baseline","14","2026-09-29T02:06:57.3866156Z","14.0085137","0.998818700000001","12.133072407045","0","","","","","","","","",""
+"2","baseline","15","2026-09-29T02:06:58.3858734Z","15.0077396","0.999225899999999","11.3725490196078","0.195463808534187","","","","","","","","",""
+"2","baseline","16","2026-09-29T02:06:59.3872637Z","16.0086146","1.000875","14.5631067961165","0","","","","","","","","",""
+"2","baseline","17","2026-09-29T02:07:00.3888166Z","17.0107604","1.0021458","6.4453125","0","","","","","","","","",""
+"2","baseline","18","2026-09-29T02:07:01.3923094Z","18.0142713","1.0035109","6.0546875","0","","","","","","","","",""
+"2","baseline","19","2026-09-29T02:07:02.3960746Z","19.0179662","1.0036949","5.2734375","0","","","","","","","","",""
+"2","baseline","20","2026-09-29T02:07:03.3811732Z","20.0029755","0.985009299999998","6.54761904761905","0","","","","","","","","",""
+"2","baseline","21","2026-09-29T02:07:04.3820439Z","21.0039887","1.0010132","11.328125","0","","","","","","","","",""
+"2","baseline","22","2026-09-29T02:07:05.3852001Z","22.0072394","1.0032507","6.4453125","0","","","","","","","","",""
+"2","baseline","23","2026-09-29T02:07:06.3898866Z","23.0118719","1.0046325","9.61538461538461","0","","","","","","","","",""
+"2","baseline","24","2026-09-29T02:07:07.3940192Z","24.0159644","1.0040925","7.421875","0","","","","","","","","",""
+"2","baseline","25","2026-09-29T02:07:08.3919512Z","25.0138521","0.9978877","5.46875","0","","","","","","","","",""
+"2","baseline","26","2026-09-29T02:07:09.3944501Z","26.0163398","1.0024877","6.0546875","0","","","","","","","","",""
+"2","baseline","27","2026-09-29T02:07:10.3786577Z","27.0006084","0.9842686","6.34920634920635","0","","","","","","","","",""
+"2","baseline","28","2026-09-29T02:07:11.3813479Z","28.0031205","1.0025121","7.6171875","0","","","","","","","","",""
+"2","baseline","29","2026-09-29T02:07:12.3818598Z","29.0037736","1.0006531","7.03125","0","","","","","","","","",""
+"2","baseline","30","2026-09-29T02:07:13.3944181Z","30.016387","1.0126134","6.73076923076923","0","","","","","","","","",""
+"2","baseline","31","2026-09-29T02:07:14.3924591Z","31.0145347","0.998147700000001","10.3515625","0","","","","","","","","",""
+"2","baseline","32","2026-09-29T02:07:15.3933555Z","32.0152135","1.0006788","5.859375","0","","","","","","","","",""
+"2","baseline","33","2026-09-29T02:07:16.3893954Z","33.0113871","0.996173599999999","4.296875","0","","","","","","","","",""
+"2","baseline","34","2026-09-29T02:07:17.3868765Z","34.009105","0.997717899999998","5.46875","0","","","","","","","","",""
+"2","baseline","35","2026-09-29T02:07:18.3958600Z","35.0177325","1.0086275","7.6171875","0","","","","","","","","",""
+"2","baseline","36","2026-09-29T02:07:19.3791157Z","36.0004594","0.982726899999996","6.16302186878728","0","","","","","","","","",""
+"2","baseline","37","2026-09-29T02:07:20.3781754Z","37.0000506","0.999591200000005","5.65302144249513","0","","","","","","","","",""
+"2","baseline","38","2026-09-29T02:07:21.3887631Z","38.0106598","1.0106092","5.57692307692308","0","","","","","","","","",""
+"2","baseline","39","2026-09-29T02:07:22.3864346Z","39.0083826","0.997722799999998","10.546875","0","","","","","","","","",""
+"2","baseline","40","2026-09-29T02:07:23.3865817Z","40.0084147","1.0000321","9.1796875","0","","","","","","","","",""
+"2","baseline","41","2026-09-29T02:07:24.3883905Z","41.0102019","1.0017872","12.5","0","","","","","","","","",""
+"2","baseline","42","2026-09-29T02:07:25.3900282Z","42.0119104","1.0017085","6.45792563600783","0","","","","","","","","",""
+"2","baseline","43","2026-09-29T02:07:26.3904609Z","43.0123005","1.0003901","4.87329434697856","0","","","","","","","","",""
+"2","baseline","44","2026-09-29T02:07:27.3938823Z","44.0156793","1.0033788","8.3984375","0","","","","","","","","",""
+"2","baseline","45","2026-09-29T02:07:28.3835468Z","45.0054674","0.989788100000005","5.95238095238095","0","","","","","","","","",""
+"2","baseline","46","2026-09-29T02:07:29.3859823Z","46.0078719","1.0024045","10.8108108108108","0.194843997607753","","","","","","","","",""
+"2","baseline","47","2026-09-29T02:07:30.3919641Z","47.0138479","1.005976","8.75486381322957","0","","","","","","","","",""
+"2","baseline","48","2026-09-29T02:07:31.3942765Z","48.0162432","1.0023953","6.0546875","0","","","","","","","","",""
+"2","baseline","49","2026-09-29T02:07:32.3789107Z","49.0009128","0.984669599999997","10.7142857142857","0","","","","","","","","",""
+"2","baseline","50","2026-09-29T02:07:33.3836349Z","50.00552","1.0046072","9.765625","0","","","","","","","","",""
+"2","baseline","51","2026-09-29T02:07:34.3854645Z","51.0074279","1.0019079","11.9140625","0","","","","","","","","",""
+"2","baseline","52","2026-09-29T02:07:35.3862428Z","52.0081079","1.00068","14.6153846153846","0.195179777751129","","","","","","","","",""
+"2","baseline","53","2026-09-29T02:07:36.3849849Z","53.0068448","0.998736899999997","18.8492063492063","0","","","","","","","","",""
+"2","baseline","54","2026-09-29T02:07:37.3912925Z","54.0131553","1.0063105","9.42307692307692","0","","","","","","","","",""
+"2","baseline","55","2026-09-29T02:07:38.4106150Z","55.0325571","1.0194018","5.38461538461539","0.191595208091648","","","","","","","","",""
+"2","baseline","56","2026-09-29T02:07:39.3917775Z","56.0138514","0.981294300000002","9.72222222222222","0","","","","","","","","",""
+"2","baseline","57","2026-09-29T02:07:40.3952371Z","57.0171498","1.0032984","8.0078125","0","","","","","","","","",""
+"2","baseline","58","2026-09-29T02:07:41.3931497Z","58.0151823","0.998032500000001","4.6875","0","","","","","","","","",""
+"2","baseline","59","2026-09-29T02:07:42.3953131Z","59.0168493","1.001667","7.2265625","0","","","","","","","","",""
+"2","baseline","60","2026-09-29T02:07:43.3832744Z","60.0052554","0.988406099999999","7.93650793650794","0","","","","","","","","",""
+"2","baseline","61","2026-09-29T02:07:44.3872830Z","61.0092561","1.0040007","15.1923076923077","0","","","","","","","","",""
+"2","baseline","62","2026-09-29T02:07:45.3901584Z","62.01191","1.00265390000001","7.8125","0","","","","","","","","",""
+"2","baseline","63","2026-09-29T02:07:46.3872144Z","63.0090392","0.997129199999996","5.078125","0","","","","","","","","",""
+"2","baseline","64","2026-09-29T02:07:47.3826308Z","64.0046276","0.995588399999995","15.0793650793651","0","","","","","","","","",""
+"2","baseline","65","2026-09-29T02:07:48.3872841Z","65.0092504","1.00462280000001","7.30769230769231","0","","","","","","","","",""
+"2","baseline","66","2026-09-29T02:07:49.3909426Z","66.0128191","1.0035687","5.46875","0","","","","","","","","",""
+"2","baseline","67","2026-09-29T02:07:50.3928738Z","67.014825","1.0020059","4.296875","0","","","","","","","","",""
+"2","baseline","68","2026-09-29T02:07:51.3944716Z","68.0164986","1.00167359999999","7.2265625","0","","","","","","","","",""
+"2","baseline","69","2026-09-29T02:07:52.3839693Z","69.0057798","0.989281200000008","7.14285714285714","0","","","","","","","","",""
+"2","baseline","70","2026-09-29T02:07:53.3951262Z","70.0170012","1.0112214","7.88461538461539","0","","","","","","","","",""
+"2","baseline","71","2026-09-29T02:07:54.3813794Z","71.0033725","0.986371300000002","10.3174603174603","0","","","","","","","","",""
+"2","baseline","72","2026-09-29T02:07:55.3873474Z","72.0093085","1.00593600000001","9.03846153846154","0","","","","","","","","",""
+"2","baseline","73","2026-09-29T02:07:56.3853062Z","73.0071565","0.997847999999991","12.8968253968254","0","","","","","","","","",""
+"2","baseline","74","2026-09-29T02:07:57.3822443Z","74.004095","0.996938499999999","9.375","0","","","","","","","","",""
+"2","baseline","75","2026-09-29T02:07:58.3830745Z","75.0050726","1.0009776","5.6640625","0","","","","","","","","",""
+"2","baseline","76","2026-09-29T02:07:59.3823693Z","76.0042934","0.999220800000003","5.46875","0","","","","","","","","",""
+"2","baseline","77","2026-09-29T02:08:00.3832149Z","77.0050193","1.00072590000001","6.640625","0","","","","","","","","",""
+"2","baseline","78","2026-09-29T02:08:01.3876583Z","78.0095087","1.0044894","7.69230769230769","0","","","","","","","","",""
+"2","baseline","79","2026-09-29T02:08:02.3934608Z","79.0152379","1.0057292","6.25","0","","","","","","","","",""
+"2","baseline","80","2026-09-29T02:08:03.3930003Z","80.0148399","0.999601999999996","8.0078125","0","","","","","","","","",""
+"2","baseline","81","2026-09-29T02:08:04.3891595Z","81.0110675","0.996227599999997","9.5703125","0","","","","","","","","",""
+"2","baseline","82","2026-09-29T02:08:05.3858122Z","82.007702","0.996634499999999","6.73267326732673","0","","","","","","","","",""
+"2","baseline","83","2026-09-29T02:08:06.3890951Z","83.0109875","1.0032855","9.2485549132948","0","","","","","","","","",""
+"2","baseline","84","2026-09-29T02:08:07.3901133Z","84.0118858","1.0008983","7.8125","0","","","","","","","","",""
+"2","baseline","85","2026-09-29T02:08:08.3883966Z","85.0102726","0.998386799999992","6.640625","0","","","","","","","","",""
+"2","baseline","86","2026-09-29T02:08:09.3840227Z","86.0060296","0.995756999999998","10.7142857142857","0","","","","","","","","",""
+"2","baseline","87","2026-09-29T02:08:10.3848110Z","87.0067313","1.00070170000001","6.4453125","0","","","","","","","","",""
+"2","baseline","88","2026-09-29T02:08:11.3849310Z","88.0069363","1.00020499999999","10.9375","0","","","","","","","","",""
+"2","baseline","89","2026-09-29T02:08:12.3872105Z","89.0091073","1.002171","7.88461538461539","0","","","","","","","","",""
+"2","baseline","90","2026-09-29T02:08:13.3903373Z","90.0123466","1.0032393","6.8359375","0","","","","","","","","",""
+"2","baseline","91","2026-09-29T02:08:14.3892597Z","91.0111305","0.998783899999992","12.3046875","0","","","","","","","","",""
+"2","baseline","92","2026-09-29T02:08:15.3939976Z","92.0158729","1.0047424","7.2265625","0","","","","","","","","",""
+"2","baseline","93","2026-09-29T02:08:16.3827536Z","93.0047805","0.988907600000005","7.53968253968254","0","","","","","","","","",""
+"2","baseline","94","2026-09-29T02:08:17.3860924Z","94.0075297","1.0027492","5.6640625","0","","","","","","","","",""
+"2","baseline","95","2026-09-29T02:08:18.3882314Z","95.010093","1.00256330000001","9.63391136801541","0.194813135489798","","","","","","","","",""
+"2","baseline","96","2026-09-29T02:08:19.3859945Z","96.0079914","0.997898399999997","14.3984220907298","0.19572383320787","","","","","","","","",""
+"2","baseline","97","2026-09-29T02:08:20.3861353Z","97.0079897","0.999998300000001","12.1621621621622","0","","","","","","","","",""
+"2","baseline","98","2026-09-29T02:08:21.3881641Z","98.0099805","1.0019908","8.203125","0","","","","","","","","",""
+"2","baseline","99","2026-09-29T02:08:22.3878921Z","99.0098709","0.999890399999998","5.6640625","0","","","","","","","","",""
+"2","baseline","100","2026-09-29T02:08:23.3820550Z","100.0039779","0.994107","10.515873015873","0","","","","","","","","",""
+"2","baseline","101","2026-09-29T02:08:24.3841731Z","101.0061691","1.0021912","8.203125","0","","","","","","","","",""
+"2","baseline","102","2026-09-29T02:08:25.3847351Z","102.0068271","1.000658","11.9140625","0","","","","","","","","",""
+"2","baseline","103","2026-09-29T02:08:26.3855195Z","103.0073223","1.0004952","7.421875","0","","","","","","","","",""
+"2","baseline","104","2026-09-29T02:08:27.3857015Z","104.0078529","1.00053059999999","14.2023346303502","0.390417844291822","","","","","","","","",""
+"2","baseline","105","2026-09-29T02:08:28.3896862Z","105.0117238","1.00387090000001","8.49420849420849","0","","","","","","","","",""
+"2","baseline","106","2026-09-29T02:08:29.3930343Z","106.0144749","1.0027511","5.2734375","0","","","","","","","","",""
+"2","baseline","107","2026-09-29T02:08:30.3886827Z","107.0100725","0.995597599999996","5.2734375","0","","","","","","","","",""
+"2","baseline","108","2026-09-29T02:08:31.3879227Z","108.0097323","0.999659800000003","39.0625","0","","","","","","","","",""
+"2","baseline","109","2026-09-29T02:08:32.3956028Z","109.0174711","1.0077388","24.0234375","0","","","","","","","","",""
+"2","baseline","110","2026-09-29T02:08:33.3793844Z","110.0013439","0.9838728","14.0873015873016","0","","","","","","","","",""
+"2","baseline","111","2026-09-29T02:08:34.3922014Z","111.0141649","1.012821","6.92307692307692","0","","","","","","","","",""
+"2","baseline","112","2026-09-29T02:08:35.3906837Z","112.012714","0.998549099999991","9.765625","0","","","","","","","","",""
+"2","baseline","113","2026-09-29T02:08:36.3907894Z","113.012714","1","10.3515625","0","","","","","","","","",""
+"2","baseline","114","2026-09-29T02:08:37.3880756Z","114.0098729","0.997158900000002","6.0546875","0","","","","","","","","",""
+"2","baseline","115","2026-09-29T02:08:38.3841465Z","115.0060014","0.996128499999998","8.73015873015873","0","","","","","","","","",""
+"2","baseline","116","2026-09-29T02:08:39.3893128Z","116.0111994","1.00519800000001","13.6538461538462","0","","","","","","","","",""
+"2","baseline","117","2026-09-29T02:08:40.3875952Z","117.0094702","0.9982708","17.96875","0","","","","","","","","",""
+"2","baseline","118","2026-09-29T02:08:41.3844799Z","118.0064116","0.996941399999997","10.9126984126984","0","","","","","","","","",""
+"2","baseline","119","2026-09-29T02:08:42.3939161Z","119.0157906","1.009379","9.80769230769231","0","","","","","","","","",""
+"2","baseline","120","2026-09-29T02:08:43.3785030Z","120.0004547","0.984664100000003","4.96031746031746","0","","","","","","","","",""
+"2","baseline","121","2026-09-29T02:08:44.3775842Z","120.999547","0.999092300000001","7.03125","0","","","","","","","","",""
+"2","baseline","122","2026-09-29T02:08:45.3796194Z","122.0015859","1.0020389","8.984375","0","","","","","","","","",""
+"2","baseline","123","2026-09-29T02:08:46.3884400Z","123.0103203","1.00873439999999","9.03846153846154","0","","","","","","","","",""
+"2","baseline","124","2026-09-29T02:08:47.3861268Z","124.0079469","0.997626600000004","14.453125","0.195777157505623","","","","","","","","",""
+"2","baseline","125","2026-09-29T02:08:48.3872214Z","125.0091441","1.00119720000001","16.015625","0","","","","","","","","",""
+"2","baseline","126","2026-09-29T02:08:49.3849606Z","126.0068468","0.997702699999991","9.92063492063492","0","","","","","","","","",""
+"2","baseline","127","2026-09-29T02:08:50.3840060Z","127.0059718","0.999125000000006","13.0859375","0","","","","","","","","",""
+"2","baseline","128","2026-09-29T02:08:51.3832602Z","128.0051008","0.999129000000011","6.4453125","0","","","","","","","","",""
+"2","baseline","129","2026-09-29T02:08:52.3825872Z","129.0044271","0.999326299999979","7.2265625","0","","","","","","","","",""
+"2","baseline","130","2026-09-29T02:08:53.3874503Z","130.0092539","1.00482680000002","9.03846153846154","0","","","","","","","","",""
+"2","baseline","131","2026-09-29T02:08:54.3891073Z","131.0109578","1.0017039","6.8359375","0","","","","","","","","",""
+"2","baseline","132","2026-09-29T02:08:55.3897220Z","132.0117664","1.0008086","8.984375","0","","","","","","","","",""
+"2","baseline","133","2026-09-29T02:08:56.3896912Z","133.011556","0.999789599999986","7.03125","0","","","","","","","","",""
+"2","baseline","134","2026-09-29T02:08:57.3920772Z","134.0138889","1.0023329","7.82778864970646","0","","","","","","","","",""
+"2","baseline","135","2026-09-29T02:08:58.3960167Z","135.0178703","1.00398140000001","4.48343079922027","0","","","","","","","","",""
+"2","baseline","136","2026-09-29T02:08:59.3801060Z","136.0019995","0.984129199999984","7.14285714285714","0","","","","","","","","",""
+"2","baseline","137","2026-09-29T02:09:00.3920020Z","137.0139827","1.0119832","6.92307692307692","0","","","","","","","","",""
+"2","baseline","138","2026-09-29T02:09:01.3929191Z","138.0147883","1.00080560000001","5.2734375","0","","","","","","","","",""
+"2","baseline","139","2026-09-29T02:09:02.3926666Z","139.0146128","0.999824499999988","7.03125","0","","","","","","","","",""
+"2","baseline","140","2026-09-29T02:09:03.3962852Z","140.0182948","1.00368200000003","6.8359375","0","","","","","","","","",""
+"2","baseline","141","2026-09-29T02:09:04.3830238Z","141.0049262","0.986631399999993","6.54761904761905","0","","","","","","","","",""
+"2","baseline","142","2026-09-29T02:09:05.3917867Z","142.0136564","1.0087302","9.61538461538461","0","","","","","","","","",""
+"2","baseline","143","2026-09-29T02:09:06.3873702Z","143.0094859","0.995829499999985","24.21875","0","","","","","","","","",""
+"2","baseline","144","2026-09-29T02:09:07.3875522Z","144.0095657","1.00007980000001","7.8125","0","","","","","","","","",""
+"2","baseline","145","2026-09-29T02:09:08.3859237Z","145.007927","0.998361299999999","11.3725490196078","0.195633083934644","","","","","","","","",""
+"2","baseline","146","2026-09-29T02:09:09.3877527Z","146.009759","1.00183200000001","10.1167315175097","0","","","","","","","","",""
+"2","baseline","147","2026-09-29T02:09:10.3900489Z","147.0119344","1.0021754","5.6640625","0","","","","","","","","",""
+"2","baseline","148","2026-09-29T02:09:11.3859589Z","148.007874","0.995939599999986","12.992125984252","0.196108780090683","","","","","","","","",""
+"2","baseline","149","2026-09-29T02:09:12.3854715Z","149.0072871","0.999413099999998","12.007874015748","0","","","","","","","","",""
+"2","baseline","150","2026-09-29T02:09:13.3818499Z","150.0037464","0.996459299999998","11.9140625","0","","","","","","","","",""
+"2","baseline","151","2026-09-29T02:09:14.3950222Z","151.0168833","1.01313690000001","5.19230769230769","0","","","","","","","","",""
+"2","baseline","152","2026-09-29T02:09:15.3900678Z","152.0119551","0.995071800000005","16.40625","0","","","","","","","","",""
+"2","baseline","153","2026-09-29T02:09:16.3893353Z","153.0112128","0.999257699999987","20.3125","0","","","","","","","","",""
+"2","baseline","154","2026-09-29T02:09:17.3911852Z","154.0130587","1.00184590000001","4.4921875","0","","","","","","","","",""
+"2","baseline","155","2026-09-29T02:09:18.3894118Z","155.0113896","0.998330900000013","4.296875","0","","","","","","","","",""
+"2","baseline","156","2026-09-29T02:09:19.3959050Z","156.0177431","1.00635349999999","6.640625","0","","","","","","","","",""
+"2","baseline","157","2026-09-29T02:09:20.3903262Z","157.0121667","0.994423600000005","10.3515625","0","","","","","","","","",""
+"2","baseline","158","2026-09-29T02:09:21.3886117Z","158.0104253","0.998258599999986","10.15625","0","","","","","","","","",""
+"2","baseline","159","2026-09-29T02:09:22.3885115Z","159.0103395","0.999914200000006","5.2734375","0","","","","","","","","",""
+"2","baseline","160","2026-09-29T02:09:23.3881766Z","160.0101252","0.999785700000018","7.6171875","0","","","","","","","","",""
+"2","baseline","161","2026-09-29T02:09:24.3862594Z","161.0080848","0.997959600000002","6.0546875","0","","","","","","","","",""
+"2","baseline","162","2026-09-29T02:09:25.3849877Z","162.0068347","0.998749899999979","11.9047619047619","0","","","","","","","","",""
+"2","baseline","163","2026-09-29T02:09:26.3833008Z","163.0054175","0.998582800000008","5.859375","0","","","","","","","","",""
+"2","baseline","164","2026-09-29T02:09:27.3859611Z","164.007861","1.0024435","8.57699805068226","0","","","","","","","","",""
+"2","baseline","165","2026-09-29T02:09:28.3832941Z","165.005186","0.997324999999989","7.43639921722114","0.195836362269072","","","","","","","","",""
+"2","baseline","166","2026-09-29T02:09:29.3857186Z","166.0076187","1.00243270000001","7.8125","0","","","","","","","","",""
+"2","baseline","167","2026-09-29T02:09:30.3848997Z","167.0068154","0.999196699999999","6.8359375","0.195469520665951","","","","","","","","",""
+"2","baseline","168","2026-09-29T02:09:31.3856032Z","168.0075571","1.00074169999999","12.109375","0","","","","","","","","",""
+"2","baseline","169","2026-09-29T02:09:32.3892300Z","169.0111281","1.00357099999999","9.03846153846154","0.194617520833106","","","","","","","","",""
+"2","baseline","170","2026-09-29T02:09:33.3938766Z","170.0154296","1.00430150000003","5.46875","0","","","","","","","","",""
+"2","baseline","171","2026-09-29T02:09:34.3936826Z","171.0155661","1.0001365","6.25","0","","","","","","","","",""
+"2","baseline","172","2026-09-29T02:09:35.3927978Z","172.0147864","0.99922029999999","12.6953125","0","","","","","","","","",""
+"2","baseline","173","2026-09-29T02:09:36.3931475Z","173.015038","1.00025160000001","5.6640625","0","","","","","","","","",""
+"2","baseline","174","2026-09-29T02:09:37.3946771Z","174.016421","1.00138299999998","6.25","0","","","","","","","","",""
+"2","baseline","175","2026-09-29T02:09:38.3789981Z","175.0008515","0.984430500000002","7.34126984126984","0","","","","","","","","",""
+"2","baseline","176","2026-09-29T02:09:39.3802510Z","176.0021491","1.00129760000002","8.203125","0","","","","","","","","",""
+"2","baseline","177","2026-09-29T02:09:40.3788709Z","177.0008207","0.998671599999994","5.2734375","0","","","","","","","","",""
+"2","baseline","178","2026-09-29T02:09:41.3788036Z","178.0006553","0.999834600000014","4.6875","0","","","","","","","","",""
+"2","baseline","179","2026-09-29T02:09:42.3910982Z","179.0132557","1.0126004","5.38461538461539","0","","","","","","","","",""
+"2","baseline","180","2026-09-29T02:09:43.3899646Z","180.0119487","0.998693000000003","7.6171875","0","","","","","","","","",""
+"2","baseline","181","2026-09-29T02:09:44.3881355Z","181.0100429","0.998094199999997","8.3984375","0","","","","","","","","",""
+"2","baseline","182","2026-09-29T02:09:45.3870015Z","182.0088924","0.998849499999977","9.765625","0","","","","","","","","",""
+"2","baseline","183","2026-09-29T02:09:46.3885912Z","183.0106613","1.0017689","8.7890625","0","","","","","","","","",""
+"2","baseline","184","2026-09-29T02:09:47.3890220Z","184.0104163","0.999755000000022","6.8359375","0","","","","","","","","",""
+"2","baseline","185","2026-09-29T02:09:48.3911588Z","185.0130552","1.00263889999999","9.5703125","0","","","","","","","","",""
+"2","baseline","186","2026-09-29T02:09:49.3814256Z","186.0034783","0.990423099999987","6.34920634920635","0","","","","","","","","",""
+"2","baseline","187","2026-09-29T02:09:50.3842460Z","187.0060759","1.0025976","8.203125","0","","","","","","","","",""
+"2","baseline","188","2026-09-29T02:09:51.3857805Z","188.0076819","1.00160600000001","11.8677042801556","0","","","","","","","","",""
+"2","baseline","189","2026-09-29T02:09:52.3967338Z","189.0185974","1.01091550000001","5.5984555984556","0","","","","","","","","",""
+"2","baseline","190","2026-09-29T02:09:53.3938277Z","190.0157371","0.997139699999991","5.859375","0","","","","","","","","",""
+"2","baseline","191","2026-09-29T02:09:54.3828313Z","191.0048394","0.989102299999985","7.53968253968254","0","","","","","","","","",""
+"2","baseline","192","2026-09-29T02:09:55.3871670Z","192.0093018","1.00446240000002","9.42307692307692","0","","","","","","","","",""
+"2","baseline","193","2026-09-29T02:09:56.3852502Z","193.0070949","0.997793099999996","14.8809523809524","0","","","","","","","","",""
+"2","baseline","194","2026-09-29T02:09:57.3847244Z","194.0066637","0.999568799999992","14.6484375","0","","","","","","","","",""
+"2","baseline","195","2026-09-29T02:09:58.3904032Z","195.0124815","1.00581779999999","11.5384615384615","0","","","","","","","","",""
+"2","baseline","196","2026-09-29T02:09:59.3876552Z","196.009616","0.997134500000016","6.0546875","0","","","","","","","","",""
+"2","baseline","197","2026-09-29T02:10:00.3903936Z","197.0122627","1.00264669999999","4.296875","0","","","","","","","","",""
+"2","baseline","198","2026-09-29T02:10:01.3952742Z","198.01715","1.00488730000001","5.859375","0","","","","","","","","",""
+"2","baseline","199","2026-09-29T02:10:02.3820128Z","199.0039881","0.9868381","4.36507936507936","0","","","","","","","","",""
+"2","baseline","200","2026-09-29T02:10:03.3843318Z","200.0063397","1.0023516","7.6171875","0","","","","","","","","",""
+"2","baseline","201","2026-09-29T02:10:04.3853506Z","201.0073792","1.00103950000002","9.1796875","0","","","","","","","","",""
+"2","baseline","202","2026-09-29T02:10:05.3888842Z","202.010808","1.00342879999999","7.11538461538461","0","","","","","","","","",""
+"2","baseline","203","2026-09-29T02:10:06.3897182Z","203.0116555","1.00084749999999","10.15625","0","","","","","","","","",""
+"2","baseline","204","2026-09-29T02:10:07.3889926Z","204.0110422","0.999386700000002","5.859375","0","","","","","","","","",""
+"2","baseline","205","2026-09-29T02:10:08.3866354Z","205.0084724","0.997430199999997","5.859375","0","","","","","","","","",""
+"2","baseline","206","2026-09-29T02:10:09.3846237Z","206.0064388","0.997966399999996","14.0873015873016","0","","","","","","","","",""
+"2","baseline","207","2026-09-29T02:10:10.3847485Z","207.0066808","1.00024200000001","6.0546875","0","","","","","","","","",""
+"2","baseline","208","2026-09-29T02:10:11.3961717Z","208.0179641","1.0112833","10","0","","","","","","","","",""
+"2","baseline","209","2026-09-29T02:10:12.3885153Z","209.0103371","0.992372999999986","5.46875","0","","","","","","","","",""
+"2","baseline","210","2026-09-29T02:10:13.3901843Z","210.0122288","1.00189170000002","5.859375","0","","","","","","","","",""
+"2","baseline","211","2026-09-29T02:10:14.3923831Z","211.0144218","1.00219299999998","6.8359375","0","","","","","","","","",""
+"2","baseline","212","2026-09-29T02:10:15.3939208Z","212.0158786","1.0014568","8.3984375","0","","","","","","","","",""
+"2","baseline","213","2026-09-29T02:10:16.3907991Z","213.0122747","0.996396099999998","12.5","0","","","","","","","","",""
+"2","baseline","214","2026-09-29T02:10:17.3810979Z","214.0030122","0.990737500000023","41.6666666666667","0","","","","","","","","",""
+"2","baseline","215","2026-09-29T02:10:18.3934502Z","215.0153311","1.0123189","19.2307692307692","0","","","","","","","","",""
+"2","baseline","216","2026-09-29T02:10:19.3867926Z","216.0092576","0.993926499999986","17.7734375","0","","","","","","","","",""
+"2","baseline","217","2026-09-29T02:10:20.3815276Z","217.003356","0.994098400000013","10.7142857142857","0","","","","","","","","",""
+"2","baseline","218","2026-09-29T02:10:21.3833447Z","218.0051998","1.00184379999999","5.46875","0","","","","","","","","",""
+"2","baseline","219","2026-09-29T02:10:22.3949168Z","219.0167856","1.01158580000001","5.76923076923077","0","","","","","","","","",""
+"2","baseline","220","2026-09-29T02:10:23.3785457Z","220.0003793","0.9835937","7.73809523809524","0","","","","","","","","",""
+"2","baseline","221","2026-09-29T02:10:24.3798581Z","221.0017785","1.00139920000001","6.4453125","0","","","","","","","","",""
+"2","baseline","222","2026-09-29T02:10:25.3830997Z","222.0050517","1.0032732","7.2265625","0","","","","","","","","",""
+"2","baseline","223","2026-09-29T02:10:26.3959439Z","223.0177883","1.01273659999998","17.1153846153846","0","","","","","","","","",""
+"2","baseline","224","2026-09-29T02:10:27.3787141Z","224.0005411","0.982752800000014","10.7142857142857","0","","","","","","","","",""
+"2","baseline","225","2026-09-29T02:10:28.3778685Z","224.9997457","0.999204599999985","8.984375","0","","","","","","","","",""
+"2","baseline","226","2026-09-29T02:10:29.3823141Z","226.0044681","1.00472240000002","8.203125","0","","","","","","","","",""
+"2","baseline","227","2026-09-29T02:10:30.3893843Z","227.0112642","1.0067961","9.03846153846154","0","","","","","","","","",""
+"2","baseline","228","2026-09-29T02:10:31.3911622Z","228.0131553","1.00189109999999","7.6171875","0","","","","","","","","",""
+"2","baseline","229","2026-09-29T02:10:32.3919352Z","229.0138263","1.00067099999998","5.46875","0","","","","","","","","",""
+"2","baseline","230","2026-09-29T02:10:33.3962707Z","230.0188927","1.0050664","4.6875","0","","","","","","","","",""
+"2","baseline","231","2026-09-29T02:10:34.3927155Z","231.0145029","0.995610200000016","6.640625","0","","","","","","","","",""
+"2","baseline","232","2026-09-29T02:10:35.3921182Z","232.0140043","0.999501399999986","6.8359375","0","","","","","","","","",""
+"2","baseline","233","2026-09-29T02:10:36.3809132Z","233.0027315","0.9887272","9.9601593625498","0","","","","","","","","",""
+"2","baseline","234","2026-09-29T02:10:37.3907268Z","234.0125893","1.00985780000002","10.727969348659","0","","","","","","","","",""
+"2","baseline","235","2026-09-29T02:10:38.3904245Z","235.0122325","0.99964319999998","6.0546875","0","","","","","","","","",""
+"2","baseline","236","2026-09-29T02:10:39.3819250Z","236.0039042","0.991671700000012","5.95238095238095","0","","","","","","","","",""
+"2","baseline","237","2026-09-29T02:10:40.3846192Z","237.0064199","1.0025157","9.765625","0","","","","","","","","",""
+"2","baseline","238","2026-09-29T02:10:41.3842221Z","238.006154","0.999734099999984","6.25","0","","","","","","","","",""
+"2","baseline","239","2026-09-29T02:10:42.3809029Z","239.0027642","0.996610200000021","7.6171875","0","","","","","","","","",""
+"2","baseline","240","2026-09-29T02:10:43.3832917Z","240.0051185","1.00235429999998","7.6171875","0","","","","","","","","",""
+"2","baseline","241","2026-09-29T02:10:44.3823009Z","241.004125","0.999006500000007","6.0546875","0","","","","","","","","",""
+"2","baseline","242","2026-09-29T02:10:45.3821688Z","242.0040068","0.999881799999997","5.2734375","0","","","","","","","","",""
+"2","baseline","243","2026-09-29T02:10:46.3860202Z","243.0080235","1.00401669999999","10.4651162790698","0.194531126822892","","","","","","","","",""
+"2","baseline","244","2026-09-29T02:10:47.3839364Z","244.0058403","0.99781680000001","36.2204724409449","0","","","","","","","","",""
+"2","baseline","245","2026-09-29T02:10:48.3835377Z","245.0053338","0.9994935","10.3515625","0","","","","","","","","",""
+"2","baseline","246","2026-09-29T02:10:49.3848457Z","246.0066459","1.00131210000001","10.546875","0","","","","","","","","",""
+"2","baseline","247","2026-09-29T02:10:50.3872725Z","247.0090561","1.00241019999999","13.8461538461538","0","","","","","","","","",""
+"2","baseline","248","2026-09-29T02:10:51.3860556Z","248.0078851","0.998829000000001","12.6953125","0.195541479071993","","","","","","","","",""
+"2","baseline","249","2026-09-29T02:10:52.3858831Z","249.0077702","0.9998851","8.87573964497041","0.195334943985064","","","","","","","","",""
+"2","baseline","250","2026-09-29T02:10:53.3817279Z","250.0035606","0.995790400000004","8.25147347740668","0","","","","","","","","",""
+"2","baseline","251","2026-09-29T02:10:54.3885906Z","251.009981","1.0064204","8.46153846153846","0","","","","","","","","",""
+"2","baseline","252","2026-09-29T02:10:55.3897636Z","252.0116303","1.0016493","7.8125","0","","","","","","","","",""
+"2","baseline","253","2026-09-29T02:10:56.3853337Z","253.0072347","0.995604400000019","14.0873015873016","0","","","","","","","","",""
+"2","baseline","254","2026-09-29T02:10:57.3842762Z","254.0061363","0.998901599999982","14.84375","0","","","","","","","","",""
+"2","baseline","255","2026-09-29T02:10:58.3843292Z","255.0062544","1.00011810000001","8.984375","0","","","","","","","","",""
+"2","baseline","256","2026-09-29T02:10:59.3864555Z","256.0079352","1.00168079999997","11.7307692307692","0.194984769599263","","","","","","","","",""
+"2","baseline","257","2026-09-29T02:11:00.3904613Z","257.0119373","1.00400210000004","9.9609375","0","","","","","","","","",""
+"2","baseline","258","2026-09-29T02:11:01.3872497Z","258.0091131","0.99717579999998","5.2734375","0","","","","","","","","",""
+"2","baseline","259","2026-09-29T02:11:02.3888545Z","259.0107373","1.00162420000004","8.203125","0.194995787841381","","","","","","","","",""
+"2","baseline","260","2026-09-29T02:11:03.3841352Z","260.006088","0.99535069999996","11.9047619047619","0","","","","","","","","",""
+"2","baseline","261","2026-09-29T02:11:04.3871873Z","261.0090987","1.0030107","12.5","0","","","","","","","","",""
+"2","baseline","262","2026-09-29T02:11:05.3867735Z","262.0085754","0.999476700000002","6.4453125","0","","","","","","","","",""
+"2","baseline","263","2026-09-29T02:11:06.3902217Z","263.0121194","1.00354399999998","14.6484375","0","","","","","","","","",""
+"2","baseline","264","2026-09-29T02:11:07.3916812Z","264.0135282","1.00140880000004","8.59375","0","","","","","","","","",""
+"2","baseline","265","2026-09-29T02:11:08.3938919Z","265.0157585","1.00223030000001","6.25","0","","","","","","","","",""
+"2","baseline","266","2026-09-29T02:11:09.3819642Z","266.0037666","0.988008100000002","5.15873015873016","0","","","","","","","","",""
+"2","baseline","267","2026-09-29T02:11:10.3810611Z","267.002927","0.999160399999994","5.078125","0","","","","","","","","",""
+"2","baseline","268","2026-09-29T02:11:11.3955915Z","268.0176193","1.01469229999998","9.61538461538461","0","","","","","","","","",""
+"2","baseline","269","2026-09-29T02:11:12.3792638Z","269.0012855","0.983666200000016","6.54761904761905","0","","","","","","","","",""
+"2","baseline","270","2026-09-29T02:11:13.3795992Z","270.0013979","1.00011239999998","6.0546875","0","","","","","","","","",""
+"2","baseline","271","2026-09-29T02:11:14.3810173Z","271.0024894","1.00109150000003","5.078125","0","","","","","","","","",""
+"2","baseline","272","2026-09-29T02:11:15.3813832Z","272.0033707","1.0008813","9.375","0","","","","","","","","",""
+"2","baseline","273","2026-09-29T02:11:16.3956917Z","273.0175134","1.01414269999998","7.30769230769231","0","","","","","","","","",""
+"2","baseline","274","2026-09-29T02:11:17.3780774Z","273.9999418","0.982428400000003","10.9126984126984","0","","","","","","","","",""
+"2","baseline","275","2026-09-29T02:11:18.3814321Z","275.0032602","1.00331840000001","5.46875","0","","","","","","","","",""
+"2","baseline","276","2026-09-29T02:11:19.3857126Z","276.0075767","1.00431650000002","12.890625","0","","","","","","","","",""
+"2","baseline","277","2026-09-29T02:11:20.3850132Z","277.006968","0.999391299999957","9.5703125","0.19543145912918","","","","","","","","",""
+"2","baseline","278","2026-09-29T02:11:21.3840627Z","278.0058384","0.998870399999987","12.6953125","0","","","","","","","","",""
+"2","baseline","279","2026-09-29T02:11:22.3849970Z","279.0069075","1.00106910000005","11.328125","0","","","","","","","","",""
+"2","baseline","280","2026-09-29T02:11:23.3847330Z","280.0067705","0.999862999999948","12.109375","0","","","","","","","","",""
+"2","baseline","281","2026-09-29T02:11:24.3820095Z","281.0039558","0.997185300000012","4.296875","0","","","","","","","","",""
+"2","baseline","282","2026-09-29T02:11:25.3850823Z","282.0070158","1.00306","7.421875","0","","","","","","","","",""
+"2","baseline","283","2026-09-29T02:11:26.3867926Z","283.0086696","1.00165379999999","11.5384615384615","0","","","","","","","","",""
+"2","baseline","284","2026-09-29T02:11:27.3856449Z","284.007441","0.99877140000001","21.4285714285714","0","","","","","","","","",""
+"2","baseline","285","2026-09-29T02:11:28.3843187Z","285.0063298","0.998888800000032","8.984375","0.1955297726834","","","","","","","","",""
+"2","baseline","286","2026-09-29T02:11:29.3909458Z","286.0127835","1.00645370000001","6.92307692307692","0.194060094368969","","","","","","","","",""
+"2","baseline","287","2026-09-29T02:11:30.3818405Z","287.0037346","0.990951099999961","7.93650793650794","0","","","","","","","","",""
+"2","baseline","288","2026-09-29T02:11:31.3835007Z","288.005451","1.00171640000002","6.25","0","","","","","","","","",""
+"2","baseline","289","2026-09-29T02:11:32.3847706Z","289.0067152","1.00126419999998","8.0078125","0","","","","","","","","",""
+"2","baseline","290","2026-09-29T02:11:33.3838295Z","290.005658","0.998942800000009","5.859375","0","","","","","","","","",""
+"2","baseline","291","2026-09-29T02:11:34.3871411Z","291.008983","1.00332500000002","8.46153846153846","0","","","","","","","","",""
+"2","baseline","292","2026-09-29T02:11:35.3862259Z","292.0080421","0.999059100000011","11.9842829076621","0","","","","","","","","",""
+"2","baseline","293","2026-09-29T02:11:36.3891270Z","293.0111123","1.00307019999997","8.54368932038835","0","","","","","","","","",""
+"2","baseline","294","2026-09-29T02:11:37.3890946Z","294.0111077","0.999995399999989","8.7890625","0","","","","","","","","",""
+"2","baseline","295","2026-09-29T02:11:38.3874955Z","295.0095797","0.998471999999992","5.6640625","0","","","","","","","","",""
+"2","baseline","296","2026-09-29T02:11:39.3948561Z","296.0167585","1.00717880000002","5.6640625","0","","","","","","","","",""
+"2","baseline","297","2026-09-29T02:11:40.3853795Z","297.0072148","0.990456300000005","6.34920634920635","0","","","","","","","","",""
+"2","baseline","298","2026-09-29T02:11:41.3870686Z","298.00908","1.0018652","6.53846153846154","0","","","","","","","","",""
+"2","baseline","299","2026-09-29T02:11:42.3875710Z","299.0094372","1.0003572","10.3515625","0","","","","","","","","",""
+"2","baseline","300","2026-09-29T02:11:43.3842708Z","300.0062893","0.996852100000012","12.6984126984127","0","","","","","","","","",""
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block-end.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block-end.json
new file mode 100644
index 0000000..0b844dd
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block-end.json
@@ -0,0 +1,12 @@
+{
+ "state": "block",
+ "layers": {
+ "shutdown": true,
+ "local_shutdown": true,
+ "update": false,
+ "remote": true,
+ "sleep": true
+ },
+ "uptime_seconds": 333,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block-start.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block-start.json
new file mode 100644
index 0000000..6e48522
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block-start.json
@@ -0,0 +1,12 @@
+{
+ "state": "block",
+ "layers": {
+ "shutdown": true,
+ "local_shutdown": true,
+ "update": false,
+ "remote": true,
+ "sleep": true
+ },
+ "uptime_seconds": 32,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block.csv
new file mode 100644
index 0000000..fa75c62
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-2-block.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"2","block","1","2026-09-29T02:01:14.3096352Z","1.0083337","1.0083304","15","0","27632","0.015625","0.193698910595178","3.21484375","13.90625","11","194","0","0"
+"2","block","2","2026-09-29T02:01:15.3049368Z","2.0035376","0.9952039","8.92857142857143","0","27632","0","0","3.20703125","14.015625","11","194","0","0"
+"2","block","3","2026-09-29T02:01:16.3093351Z","3.0079545","1.0044169","9.80769230769231","0","27632","0","0","3.2265625","14.01953125","11","194","0","0"
+"2","block","4","2026-09-29T02:01:17.3063188Z","4.0049759","0.9970214","10.3174603174603","0","27632","0","0","3.2265625","14.01953125","11","194","0","0"
+"2","block","5","2026-09-29T02:01:18.3031214Z","5.0018518","0.9968759","7.03125","0.195924588005388","27632","0","0","3.2265625","14.01953125","11","194","0","0"
+"2","block","6","2026-09-29T02:01:19.3029009Z","6.0015438","0.999692","9.765625","0","27632","0","0","3.2265625","14.01953125","11","194","0","0"
+"2","block","7","2026-09-29T02:01:20.3040074Z","7.0026159","1.0010721","7.2265625","0","27632","0","0","3.2265625","14.0234375","11","194","0","0"
+"2","block","8","2026-09-29T02:01:21.3057747Z","8.0042593","1.0016434","6.8359375","0","27632","0","0","3.2265625","14.0234375","11","194","0","0"
+"2","block","9","2026-09-29T02:01:22.3097257Z","9.0083219","1.0040626","9.03846153846154","0.194522233972264","27632","0","0","3.2265625","14.02734375","11","194","0","0"
+"2","block","10","2026-09-29T02:01:23.3148676Z","10.0135912","1.0052693","3.515625","0","27632","0","0","3.2265625","14.02734375","11","194","0","0"
+"2","block","11","2026-09-29T02:01:24.3160289Z","11.0146012","1.00101","7.03125","0","27632","0","0","3.2265625","14.02734375","11","194","0","0"
+"2","block","12","2026-09-29T02:01:25.3165364Z","12.0153461","1.0007449","6.640625","0","27632","0","0","3.2265625","14.02734375","11","194","0","0"
+"2","block","13","2026-09-29T02:01:26.3163739Z","13.0146382","0.999292100000002","6.0546875","0","27632","0","0","3.2265625","14.02734375","11","194","0","0"
+"2","block","14","2026-09-29T02:01:27.3051565Z","14.0039815","0.9893433","4.16666666666667","0","27632","0","0","3.2265625","14.02734375","11","194","0","0"
+"2","block","15","2026-09-29T02:01:28.3068774Z","15.0054821","1.0015006","14.0625","0.195019853208276","27632","0.015625","0.195019853208276","3.2265625","14.02734375","11","194","0","0"
+"2","block","16","2026-09-29T02:01:29.3065769Z","16.0051069","0.999624799999998","13.8671875","0.195385808755446","27632","0","0","3.2265625","14.02734375","11","194","0","0"
+"2","block","17","2026-09-29T02:01:30.3048502Z","17.0035658","0.998458900000003","9.765625","0.195613960674795","27632","0","0","3.2265625","14.02734375","11","194","0","0"
+"2","block","18","2026-09-29T02:01:31.3084978Z","18.0070947","1.0035289","9.03846153846154","0","27632","0","0","3.2265625","14.03125","11","194","0","0"
+"2","block","19","2026-09-29T02:01:32.3071315Z","19.0057088","0.998614100000001","9.32539682539683","0","27632","0","0","3.2265625","14.03515625","11","194","0","0"
+"2","block","20","2026-09-29T02:01:33.3037984Z","20.0025311","0.996822299999998","7.8125","0.195935123040486","27632","0","0","3.2265625","14.03515625","11","194","0","0"
+"2","block","21","2026-09-29T02:01:34.3036342Z","21.0023279","0.999796799999999","5.859375","0","27632","0","0","3.2265625","14.03515625","11","194","0","0"
+"2","block","22","2026-09-29T02:01:35.3034623Z","22.0021165","0.999788600000002","6.25","0","27632","0","0","3.2265625","14.03515625","11","194","0","0"
+"2","block","23","2026-09-29T02:01:36.3182093Z","23.017089","1.0149725","6.34615384615385","0","27632","0","0","3.2265625","14.03515625","11","194","0","0"
+"2","block","24","2026-09-29T02:01:37.3079706Z","24.0065615","0.989472500000002","11.1545988258317","0.197390528791856","27632","0","0","3.2265625","14.03515625","11","194","0","0"
+"2","block","25","2026-09-29T02:01:38.3072420Z","25.0057604","0.9991989","19.4059405940594","0","27632","0","0","3.2265625","14.03515625","11","194","0","0"
+"2","block","26","2026-09-29T02:01:39.3062036Z","26.0048608","0.9991004","8.203125","0.195488361329852","27632","0","0","3.2265625","14.03515625","11","194","0","0"
+"2","block","27","2026-09-29T02:01:40.3095706Z","27.0081496","1.0032888","9.80769230769231","0.194672261865178","27632","0","0","3.19921875","14.0078125","10","194","0","0"
+"2","block","28","2026-09-29T02:01:41.3063641Z","28.0045184","0.996368799999999","8.33333333333333","0","27632","0","0","3.19921875","14.0078125","10","194","0","0"
+"2","block","29","2026-09-29T02:01:42.3055467Z","29.0041991","0.999680699999999","6.640625","0.195374883200206","27632","0","0","3.19921875","14.0078125","10","194","0","0"
+"2","block","30","2026-09-29T02:01:43.3038329Z","30.0025307","0.9983316","11.1328125","0.195638903947346","27632","0","0","3.19921875","14.0078125","10","194","0","0"
+"2","block","31","2026-09-29T02:01:44.3076780Z","31.0065905","1.0040598","8.84615384615385","0.19452277643224","27632","0","0","3.19921875","14.01171875","10","194","0","0"
+"2","block","32","2026-09-29T02:01:45.3069415Z","32.0056219","0.999031400000003","10.9126984126984","0","27632","0","0","3.19921875","14.01171875","10","194","0","0"
+"2","block","33","2026-09-29T02:01:46.3099301Z","33.0084235","1.0028016","8.84615384615385","0.194766841217645","27632","0","0","3.19921875","14.01171875","10","194","0","0"
+"2","block","34","2026-09-29T02:01:47.3093268Z","34.0079278","0.999504299999998","24.609375","0","27632","0","0","3.19921875","14.01171875","10","194","0","0"
+"2","block","35","2026-09-29T02:01:48.3110025Z","35.0096225","1.0016947","5.6640625","0","27632","0","0","3.19921875","14.01171875","10","194","0","0"
+"2","block","36","2026-09-29T02:01:49.3151306Z","36.0132151","1.0035926","6.4453125","0","27632","0","0","3.19921875","14.01171875","10","194","0","0"
+"2","block","37","2026-09-29T02:01:50.3143565Z","37.0129603","0.9997452","6.640625","0","27632","0","0","3.19921875","14.015625","10","194","0","0"
+"2","block","38","2026-09-29T02:01:51.3014592Z","38.0001277","0.987167400000004","4.36507936507936","0","27632","0","0","3.19921875","14.015625","10","194","0","0"
+"2","block","39","2026-09-29T02:01:52.3044431Z","39.0030206","1.0028929","7.2265625","0","27632","0","0","3.19921875","14.0234375","10","194","0","0"
+"2","block","40","2026-09-29T02:01:53.3172810Z","40.0160417","1.0130211","10","0","27632","0","0","3.19921875","14.0234375","10","194","0","0"
+"2","block","41","2026-09-29T02:01:54.3159621Z","41.0146851","0.998643400000006","6.4453125","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","42","2026-09-29T02:01:55.3054469Z","42.0036401","0.988954999999997","5.55555555555556","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","43","2026-09-29T02:01:56.3051141Z","43.0036997","1.0000596","8.984375","0.19530086006874","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","44","2026-09-29T02:01:57.3075516Z","44.0062756","1.0025759","8.7890625","0.194810687150968","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","45","2026-09-29T02:01:58.3099467Z","45.0086485","1.0023729","7.11538461538461","0.19485014010255","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","46","2026-09-29T02:01:59.3101345Z","46.0086884","1.0000399","4.6875","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","47","2026-09-29T02:02:00.3176613Z","47.0158303","1.0071419","10.3515625","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","48","2026-09-29T02:02:01.3168946Z","48.0154985","0.999668200000002","7.421875","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","49","2026-09-29T02:02:02.3060438Z","49.004557","0.989058499999999","5.75396825396825","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","50","2026-09-29T02:02:03.3110882Z","50.0098001","1.0052431","5","0.194293798186727","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","51","2026-09-29T02:02:04.3073001Z","51.0056039","0.995803799999997","6.34920634920635","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","52","2026-09-29T02:02:05.3084382Z","52.0070863","1.0014824","16.3461538461538","0.195023397315819","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","53","2026-09-29T02:02:06.3096230Z","53.0083107","1.0012244","8.7890625","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","54","2026-09-29T02:02:07.3168261Z","54.0157027","1.007392","5.078125","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","55","2026-09-29T02:02:08.3037071Z","55.002348","0.986645299999999","5.55555555555556","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","56","2026-09-29T02:02:09.3067643Z","56.0039084","1.0015604","8.3984375","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","57","2026-09-29T02:02:10.3059855Z","57.0047057","1.0007973","8.984375","0.195156901402513","27632","0","0","3.19140625","14.015625","10","194","0","0"
+"2","block","58","2026-09-29T02:02:11.3093129Z","58.0076966","1.0029909","14.0384615384615","0.194730081798349","27632","0.015625","0.194730081798349","3.19140625","14.015625","10","194","0","0"
+"2","block","59","2026-09-29T02:02:12.3097195Z","59.0083527","1.0006561","8.3984375","0","27632","0","0","3.19140625","14.015625","10","194","0","0"
+"2","block","60","2026-09-29T02:02:13.3078417Z","60.0064082","0.9980555","17.6817288801572","0.195693025087282","27632","0.015625","0.195693025087282","3.19140625","14.015625","10","194","0","0"
+"2","block","61","2026-09-29T02:02:14.3114487Z","61.0099587","1.0035505","10.4854368932039","0","27632","0","0","3.19140625","14.015625","10","194","0","0"
+"2","block","62","2026-09-29T02:02:15.3139088Z","62.0125675","1.0026088","4.296875","0","27632","0","0","3.19140625","14.015625","10","194","0","0"
+"2","block","63","2026-09-29T02:02:16.3124605Z","63.0110221","0.998454600000002","5.6640625","0","27632","0","0","3.19140625","14.015625","10","194","0","0"
+"2","block","64","2026-09-29T02:02:17.3116750Z","64.010151","0.999128899999995","9.1796875","0","27632","0","0","3.19921875","14.01953125","10","194","0","0"
+"2","block","65","2026-09-29T02:02:18.3116108Z","65.010181","1.00003000000001","5.859375","0","27632","0","0","3.19921875","14.01953125","10","194","0","0"
+"2","block","66","2026-09-29T02:02:19.3100076Z","66.0086758","0.998494799999989","3.90625","0","27632","0","0","3.19921875","14.01953125","10","194","0","0"
+"2","block","67","2026-09-29T02:02:20.3089810Z","67.0076547","0.998978900000012","10.1960784313725","0","27632","0","0","3.19921875","14.0234375","10","194","0","0"
+"2","block","68","2026-09-29T02:02:21.3181047Z","68.0168297","1.009175","9.53307392996109","0","27632","0","0","3.19921875","14.0234375","10","194","0","0"
+"2","block","69","2026-09-29T02:02:22.3172893Z","69.0155629","0.99873319999999","6.0546875","0","27632","0","0","3.19921875","14.0234375","10","194","0","0"
+"2","block","70","2026-09-29T02:02:23.3163438Z","70.0145336","0.998970700000001","6.640625","0","27632","0","0","3.19921875","14.0234375","10","194","0","0"
+"2","block","71","2026-09-29T02:02:24.3147781Z","71.0135304","0.9989968","4.4921875","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","72","2026-09-29T02:02:25.3136912Z","72.0117559","0.998225500000004","7.6171875","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","73","2026-09-29T02:02:26.3137393Z","73.0123324","1.00057649999999","5.2734375","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","74","2026-09-29T02:02:27.3179684Z","74.0165122","1.0041798","4.8828125","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","75","2026-09-29T02:02:28.3089120Z","75.0075483","0.991036100000002","13.28125","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","76","2026-09-29T02:02:29.3084467Z","76.0069525","0.999404200000001","13.671875","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","77","2026-09-29T02:02:30.3301301Z","77.01716","1.01020749999999","34.5631067961165","0","27632","0.015625","0.193338992236745","3.2421875","14.03125","10","194","0","0"
+"2","block","78","2026-09-29T02:02:31.3109924Z","78.0097054","0.992545400000012","26.3261296660118","0","27632","0","0","3.2421875","14.03515625","10","194","0","0"
+"2","block","79","2026-09-29T02:02:32.3068910Z","79.0055802","0.995874799999996","18.0555555555556","0","27632","0","0","3.2421875","14.03515625","10","194","0","0"
+"2","block","80","2026-09-29T02:02:33.3076528Z","80.0062531","1.0006729","15.0390625","0.19518116259569","27632","0","0","3.2421875","14.03515625","10","194","0","0"
+"2","block","81","2026-09-29T02:02:34.3174311Z","81.0160837","1.0098306","5.76923076923077","0.193411152325944","27632","0","0","3.2421875","14.03515625","10","194","0","0"
+"2","block","82","2026-09-29T02:02:35.3039232Z","82.0024675","0.986383799999999","5.35714285714286","0","27632","0","0","3.2421875","14.0390625","10","194","0","0"
+"2","block","83","2026-09-29T02:02:36.3033469Z","83.0020628","0.999595299999996","6.0546875","0","27632","0","0","3.2421875","14.0390625","10","194","0","0"
+"2","block","84","2026-09-29T02:02:37.3038580Z","84.0025932","1.0005304","8.59375","0","27632","0","0","3.2421875","14.04296875","10","194","0","0"
+"2","block","85","2026-09-29T02:02:38.3153361Z","85.0139877","1.01139450000001","7.5","0","27632","0","0","3.2421875","14.04296875","10","194","0","0"
+"2","block","86","2026-09-29T02:02:39.3161584Z","86.0153879","1.00140019999999","4.6875","0","27632","0","0","3.2421875","14.04296875","10","194","0","0"
+"2","block","87","2026-09-29T02:02:40.3172056Z","87.0157332","1.00034530000001","9.375","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","88","2026-09-29T02:02:41.3142808Z","88.0129958","0.997262599999999","6.8359375","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","89","2026-09-29T02:02:42.3028008Z","89.0015292","0.988533399999994","3.96825396825397","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","90","2026-09-29T02:02:43.3053638Z","90.0039452","1.002416","7.2265625","0","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","91","2026-09-29T02:02:44.3061944Z","91.0043921","1.0004469","17.578125","0.195225253834062","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","92","2026-09-29T02:02:45.3074220Z","92.0056124","1.0012203","14.453125","0.195074450647874","27632","0.015625","0.195074450647874","3.2421875","14.02734375","10","194","0","0"
+"2","block","93","2026-09-29T02:02:46.3123639Z","93.0110175","1.0054051","7.88461538461539","0.194262491805541","27632","0","0","3.2421875","14.02734375","10","194","0","0"
+"2","block","94","2026-09-29T02:02:47.3083377Z","94.0069861","0.995968599999998","7.03125","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","95","2026-09-29T02:02:48.3103003Z","95.0090486","1.00206250000001","7.03125","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","96","2026-09-29T02:02:49.3087706Z","96.0074284","0.998379799999995","4.8828125","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","97","2026-09-29T02:02:50.3068440Z","97.0054743","0.998045899999994","12.1031746031746","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","98","2026-09-29T02:02:51.3073166Z","98.0059861","1.00051180000001","12.3046875","0.195212590196335","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","99","2026-09-29T02:02:52.3091111Z","99.0077275","1.0017414","17.3076923076923","0.194972974062967","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","100","2026-09-29T02:02:53.3086224Z","100.0072655","0.999537999999987","16.6015625","0","27632","0.015625","0.195402776082553","3.2421875","14.03125","10","194","0","0"
+"2","block","101","2026-09-29T02:02:54.3086263Z","101.0073089","1.00004340000001","7.6171875","0","27632","0","0","3.2421875","14.03125","10","194","0","0"
+"2","block","102","2026-09-29T02:02:55.3118547Z","102.0105286","1.0032197","4.8828125","0","27632","0","0","3.21875","14.01953125","9","192","0","0"
+"2","block","103","2026-09-29T02:02:56.3172891Z","103.0159152","1.00538659999999","6.8359375","0","27632","0","0","3.21875","14.01953125","9","192","0","0"
+"2","block","104","2026-09-29T02:02:57.3164067Z","104.0150482","0.999133","6.8359375","0","27632","0","0","3.21875","14.01953125","9","192","0","0"
+"2","block","105","2026-09-29T02:02:58.3038840Z","105.0026625","0.987614300000004","5.75396825396825","0","27632","0","0","3.21875","14.01953125","9","192","0","0"
+"2","block","106","2026-09-29T02:02:59.3055023Z","106.004149","1.0014865","7.03125","0","27632","0","0","3.21875","14.01953125","9","192","0","0"
+"2","block","107","2026-09-29T02:03:00.3108199Z","107.0090209","1.0048719","7.11538461538461","0.194365570377677","27632","0","0","3.21875","14.01953125","9","192","0","0"
+"2","block","108","2026-09-29T02:03:01.3108759Z","108.0095034","1.0004825","9.5703125","0","27632","0","0","3.21875","14.01953125","9","192","0","0"
+"2","block","109","2026-09-29T02:03:02.3067840Z","109.0054786","0.99597519999999","8.33333333333333","0","27632","0","0","3.21875","14.01953125","9","192","0","0"
+"2","block","110","2026-09-29T02:03:03.3057421Z","110.004424","0.998945400000011","7.2265625","0.195518694014706","27632","0","0","3.21875","14.0234375","9","192","0","0"
+"2","block","111","2026-09-29T02:03:04.3060740Z","111.0046779","1.00025389999999","9.5703125","0.195262922743917","27632","0","0","3.21875","14.02734375","9","192","0","0"
+"2","block","112","2026-09-29T02:03:05.3027680Z","112.001454","0.996776100000005","8.203125","0.195944204520954","27632","0","0","3.21875","14.02734375","9","192","0","0"
+"2","block","113","2026-09-29T02:03:06.3043700Z","113.0030283","1.0015743","5.2734375","0","27632","0","0","3.21875","14.02734375","9","192","0","0"
+"2","block","114","2026-09-29T02:03:07.3067751Z","114.0050796","1.00205129999999","6.25","0","27632","0","0","3.21875","14.02734375","9","192","0","0"
+"2","block","115","2026-09-29T02:03:08.3039522Z","115.0025676","0.997488000000004","8.3984375","0.19580436055371","27632","0","0","3.21875","14.02734375","9","192","0","0"
+"2","block","116","2026-09-29T02:03:09.3152247Z","116.0138115","1.0112439","6.73076923076923","0","27632","0","0","3.21875","14.02734375","9","192","0","0"
+"2","block","117","2026-09-29T02:03:10.3152955Z","117.0139414","1.0001299","5.46875","0","27632","0","0","3.203125","14.0234375","10","192","0","0"
+"2","block","118","2026-09-29T02:03:11.3141661Z","118.0127453","0.998803899999999","10.15625","0","27632","0","0","3.203125","14.0234375","10","192","0","0"
+"2","block","119","2026-09-29T02:03:12.3053151Z","119.0039233","0.991178000000005","6.54761904761905","0","27632","0","0","3.203125","14.0234375","10","192","0","0"
+"2","block","120","2026-09-29T02:03:13.3041475Z","120.0027849","0.998861599999998","13.4765625","0.195535097154601","27632","0","0","3.203125","14.0234375","10","192","0","0"
+"2","block","121","2026-09-29T02:03:14.3034372Z","121.0021201","0.999335200000004","6.8359375","0","27632","0","0","3.203125","14.0234375","10","192","0","0"
+"2","block","122","2026-09-29T02:03:15.3070929Z","122.0056963","1.0035762","7.2265625","0","27632","0","0","3.203125","14.02734375","10","192","0","0"
+"2","block","123","2026-09-29T02:03:16.3066038Z","123.0052069","0.999510599999994","16.2109375","0.195408132740164","27632","0.015625","0.195408132740164","3.203125","14.02734375","10","192","0","0"
+"2","block","124","2026-09-29T02:03:17.3047159Z","124.0032717","0.998064800000009","8.0078125","0.19569120161336","27632","0","0","3.203125","14.02734375","10","192","0","0"
+"2","block","125","2026-09-29T02:03:18.3070952Z","125.0057378","1.00246609999999","6.25","0.194832024743781","27632","0","0","3.203125","14.02734375","10","192","0","0"
+"2","block","126","2026-09-29T02:03:19.3104963Z","126.0091606","1.00342280000001","6.92307692307692","0.194646264764961","27632","0","0","3.203125","14.02734375","10","192","0","0"
+"2","block","127","2026-09-29T02:03:20.3116120Z","127.0101649","1.00100429999999","6.640625","0","27632","0","0","3.24609375","14.03125","10","192","0","0"
+"2","block","128","2026-09-29T02:03:21.3062020Z","128.0048873","0.994722400000015","15.6746031746032","0","27632","0","0","3.24609375","14.03125","10","192","0","0"
+"2","block","129","2026-09-29T02:03:22.3037241Z","129.0022362","0.997348899999992","12.109375","0.195831669338585","27632","0","0","3.24609375","14.03515625","10","192","0","0"
+"2","block","130","2026-09-29T02:03:23.3052849Z","130.0038497","1.00161349999999","6.25","0","27632","0","0","3.24609375","14.03515625","10","192","0","0"
+"2","block","131","2026-09-29T02:03:24.3043431Z","131.0029371","0.999087400000008","6.4453125","0.195490904999901","27632","0","0","3.24609375","14.03515625","10","192","0","0"
+"2","block","132","2026-09-29T02:03:25.3044445Z","132.0030027","1.0000656","9.375","0","27632","0","0","3.24609375","14.03515625","10","192","0","0"
+"2","block","133","2026-09-29T02:03:26.3044495Z","133.0030085","1.0000058","6.25","0","27632","0","0","3.24609375","14.03515625","10","192","0","0"
+"2","block","134","2026-09-29T02:03:27.3034435Z","134.0020481","0.999039600000003","4.6875","0","27632","0","0","3.24609375","14.03515625","10","192","0","0"
+"2","block","135","2026-09-29T02:03:28.3067482Z","135.0052734","1.0032253","8.0078125","0","27632","0","0","3.24609375","14.03515625","10","192","0","0"
+"2","block","136","2026-09-29T02:03:29.3081426Z","136.0062797","1.0010063","10.7421875","0.195116154613612","27632","0.015625","0.195116154613612","3.24609375","14.0390625","10","192","0","0"
+"2","block","137","2026-09-29T02:03:30.3088495Z","137.0076195","1.00133980000001","13.0769230769231","0.19505117044184","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","138","2026-09-29T02:03:31.3112246Z","138.0099929","1.00237339999998","10.15625","0","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","139","2026-09-29T02:03:32.3121742Z","139.010718","1.00072510000001","6.25","0","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","140","2026-09-29T02:03:33.3123899Z","140.0110021","1.00028409999999","6.640625","0","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","141","2026-09-29T02:03:34.3147300Z","141.0132921","1.00229000000002","4.4921875","0","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","142","2026-09-29T02:03:35.3019111Z","142.0005387","0.987246599999992","6.74603174603175","0","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","143","2026-09-29T02:03:36.3035231Z","143.0022992","1.00176049999999","13.28125","0","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","144","2026-09-29T02:03:37.3063296Z","144.0049645","1.00266530000002","9.9609375","0","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","145","2026-09-29T02:03:38.3071041Z","145.005328","1.00036349999999","9.765625","0.195241529703954","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","146","2026-09-29T02:03:39.3080911Z","146.0066332","1.00130519999999","15.3846153846154","0.195057910415328","27632","0","0","3.24609375","14.0390625","10","192","0","0"
+"2","block","147","2026-09-29T02:03:40.3067040Z","147.0055821","0.998948900000016","15.2777777777778","0","27632","0","0","3.203125","14.0234375","10","194","0","0"
+"2","block","148","2026-09-29T02:03:41.3060573Z","148.0046725","0.9990904","16.015625","0.195490317993247","27632","0","0","3.203125","14.0234375","10","194","0","0"
+"2","block","149","2026-09-29T02:03:42.3045198Z","149.0031876","0.998515099999992","6.25","0.195602950821677","27632","0","0","3.203125","14.0234375","10","194","0","0"
+"2","block","150","2026-09-29T02:03:43.3087878Z","150.007383","1.00419540000001","11.5384615384615","0.194496509344692","27632","0","0","3.203125","14.0234375","10","194","0","0"
+"2","block","151","2026-09-29T02:03:44.3083589Z","151.0069902","0.999607199999986","9.1796875","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","152","2026-09-29T02:03:45.3050014Z","152.003543","0.996552799999989","12.8968253968254","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","153","2026-09-29T02:03:46.3182299Z","153.0169113","1.01336830000002","4.23076923076923","0.192735948025999","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","154","2026-09-29T02:03:47.3029563Z","154.0015244","0.98461309999999","6.15079365079365","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","155","2026-09-29T02:03:48.3174898Z","155.0162556","1.0147312","7.11538461538461","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","156","2026-09-29T02:03:49.3084245Z","156.0070337","0.9907781","6.4453125","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","157","2026-09-29T02:03:50.3112027Z","157.009302","1.0022683","11.328125","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","158","2026-09-29T02:03:51.3084724Z","158.007047","0.997745000000009","7.8125","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","159","2026-09-29T02:03:52.3101696Z","159.0088374","1.0017904","8.7890625","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","160","2026-09-29T02:03:53.3066842Z","160.0052926","0.996455199999986","15.0793650793651","0","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","161","2026-09-29T02:03:54.3032464Z","161.001902","0.996609400000011","6.640625","0.195976979546849","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","162","2026-09-29T02:03:55.3073014Z","162.0058749","1.00397289999998","6.26223091976517","0","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","163","2026-09-29T02:03:56.3068548Z","163.0054454","0.999570500000004","11.8908382066277","0.195396422763576","27632","0.015625","0.195396422763576","3.24609375","14.03125","10","194","0","0"
+"2","block","164","2026-09-29T02:03:57.3060473Z","164.0048779","0.999432500000012","10.15625","0.195423402781076","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","165","2026-09-29T02:03:58.3040090Z","165.0026724","0.997794499999998","5.46875","0.195744213863677","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","166","2026-09-29T02:03:59.3038171Z","166.0026788","1.00000639999999","4.6875","0","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","167","2026-09-29T02:04:00.3037199Z","167.0022951","0.999616300000014","7.2265625","0.195387470172302","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","168","2026-09-29T02:04:01.3057669Z","168.0044688","1.00217369999999","13.671875","0","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","169","2026-09-29T02:04:02.3046467Z","169.0033721","0.998903299999995","4.4921875","0.195526934388945","27632","0","0","3.24609375","14.03125","10","194","0","0"
+"2","block","170","2026-09-29T02:04:03.3069362Z","170.0055313","1.00215920000002","5.6640625","0","27632","0","0","3.24609375","14.03515625","10","194","0","0"
+"2","block","171","2026-09-29T02:04:04.3115563Z","171.0102233","1.00469199999998","10.1923076923077","0.194400373447787","27632","0","0","3.24609375","14.03515625","10","194","0","0"
+"2","block","172","2026-09-29T02:04:05.3157949Z","172.0144414","1.0042181","8.3984375","0","27632","0","0","3.24609375","14.03515625","10","194","0","0"
+"2","block","173","2026-09-29T02:04:06.3149733Z","173.0136625","0.9992211","5.078125","0","27632","0","0","3.24609375","14.03515625","10","194","0","0"
+"2","block","174","2026-09-29T02:04:07.3155539Z","174.0141306","1.00046810000001","7.8125","0","27632","0","0","3.24609375","14.03515625","10","194","0","0"
+"2","block","175","2026-09-29T02:04:08.3113207Z","175.0104363","0.996305699999994","18.1640625","0","27632","0","0","3.24609375","14.03515625","10","194","0","0"
+"2","block","176","2026-09-29T02:04:09.3108889Z","176.0094566","0.999020300000012","19.53125","0","27632","0","0","3.24609375","14.03515625","10","194","0","0"
+"2","block","177","2026-09-29T02:04:10.3119707Z","177.0105696","1.001113","8.203125","0","27632","0","0","3.1953125","14.01953125","10","194","0","0"
+"2","block","178","2026-09-29T02:04:11.3111577Z","178.0097902","0.999220600000001","33.3984375","0","27632","0","0","3.1953125","14.01953125","10","194","0","0"
+"2","block","179","2026-09-29T02:04:12.3104442Z","179.0090165","0.999226300000004","8.203125","0","27632","0","0","3.1953125","14.01953125","10","194","0","0"
+"2","block","180","2026-09-29T02:04:13.3127303Z","180.0113849","1.00236839999999","7.421875","0","27632","0","0","3.1953125","14.01953125","10","194","0","0"
+"2","block","181","2026-09-29T02:04:14.3090464Z","181.0076916","0.996306699999991","8.3984375","0","27632","0","0","3.1953125","14.01953125","10","194","0","0"
+"2","block","182","2026-09-29T02:04:15.3108172Z","182.0093681","1.0016765","12.5","0","27632","0","0","3.1953125","14.01953125","10","194","0","0"
+"2","block","183","2026-09-29T02:04:16.3091487Z","183.0078115","0.998443400000014","19.7265625","0","27632","0","0","3.1953125","14.01953125","10","194","0","0"
+"2","block","184","2026-09-29T02:04:17.3058087Z","184.0044189","0.996607399999988","41.468253968254","0","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","185","2026-09-29T02:04:18.3180862Z","185.0166881","1.01226919999999","29.4230769230769","0.192945216549117","27632","0","0","3.203125","14.02734375","10","194","0","0"
+"2","block","186","2026-09-29T02:04:19.3163669Z","186.0145369","0.997848800000014","8.3984375","0","27632","0","0","3.203125","13.0234375","10","194","0","0"
+"2","block","187","2026-09-29T02:04:20.3118810Z","187.0103997","0.995862799999998","6.8359375","0","27632","0","0","3.24609375","13.02734375","10","194","0","0"
+"2","block","188","2026-09-29T02:04:21.3085846Z","188.0070958","0.996696100000008","24.0234375","0","27632","0","0","3.24609375","13.02734375","10","194","0","0"
+"2","block","189","2026-09-29T02:04:22.3111546Z","189.0103902","1.00329439999999","27.734375","0","27632","0","0","3.24609375","13.02734375","10","194","0","0"
+"2","block","190","2026-09-29T02:04:23.3029384Z","190.0015818","0.991191600000008","32.9365079365079","0","27632","0.015625","0.197048179181501","3.24609375","13.02734375","10","194","0","0"
+"2","block","191","2026-09-29T02:04:24.3053090Z","191.0039867","1.00240489999999","10.7421875","0.194843919857138","27632","0","0","3.24609375","13.03125","10","194","0","0"
+"2","block","192","2026-09-29T02:04:25.3075927Z","192.0061089","1.0021222","16.9921875","0.194898885585011","27632","0","0","3.24609375","13.03125","10","194","0","0"
+"2","block","193","2026-09-29T02:04:26.3053421Z","193.0040344","0.997925500000008","16.9921875","0.195718518065726","27632","0","0","3.24609375","13.03515625","10","194","0","0"
+"2","block","194","2026-09-29T02:04:27.3041365Z","194.0027823","0.998747899999984","21.484375","0.195557357367163","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","195","2026-09-29T02:04:28.3144800Z","195.0129837","1.0102014","39.6153846153846","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","196","2026-09-29T02:04:29.3091520Z","196.0077838","0.99480010000002","27.734375","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","197","2026-09-29T02:04:30.3047679Z","197.0033938","0.995609999999999","19.2460317460317","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","198","2026-09-29T02:04:31.3151685Z","198.0138183","1.0104245","6.34615384615385","0.193297470518579","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","199","2026-09-29T02:04:32.3147967Z","199.0134069","0.999588599999981","13.0859375","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","200","2026-09-29T02:04:33.3149908Z","200.013654","1.00024710000002","5.859375","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","201","2026-09-29T02:04:34.3026618Z","201.0019314","0.988277399999987","6.54761904761905","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","202","2026-09-29T02:04:35.3163493Z","202.0149696","1.01303820000001","6.15384615384615","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","203","2026-09-29T02:04:36.3053791Z","203.0041615","0.98919189999998","8.92857142857143","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","204","2026-09-29T02:04:37.3165825Z","204.0153452","1.0111837","8.65384615384615","0.193152342151084","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","205","2026-09-29T02:04:38.3172370Z","205.0160357","1.00069050000002","10.15625","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","206","2026-09-29T02:04:39.3165872Z","206.015099","0.999063299999989","6.4453125","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","207","2026-09-29T02:04:40.3168617Z","207.0154292","1.00033020000001","5.859375","0","27632","0","0","3.24609375","13.03515625","10","194","0","0"
+"2","block","208","2026-09-29T02:04:41.3164546Z","208.0151546","0.999725399999988","5.2734375","0","27632","0","0","3.24609375","13.03515625","10","194","0","0"
+"2","block","209","2026-09-29T02:04:42.3029060Z","209.0015446","0.98639","9.52380952380952","0","27632","0","0","3.24609375","13.03515625","10","194","0","0"
+"2","block","210","2026-09-29T02:04:43.3159348Z","210.0144643","1.0129197","5.96153846153846","0","27632","0","0","3.24609375","13.03515625","10","194","0","0"
+"2","block","211","2026-09-29T02:04:44.3013220Z","210.9999558","0.985491499999995","9.12698412698413","0","27632","0","0","3.24609375","13.03515625","10","194","0","0"
+"2","block","212","2026-09-29T02:04:45.3120900Z","212.0108842","1.01092840000001","9.42307692307692","0","27632","0","0","3.24609375","13.03515625","10","194","0","0"
+"2","block","213","2026-09-29T02:04:46.3105234Z","213.0090986","0.998214399999995","5.6640625","0","27632","0","0","3.24609375","13.03515625","10","194","0","0"
+"2","block","214","2026-09-29T02:04:47.3074907Z","214.0060669","0.996968299999992","13.8888888888889","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","215","2026-09-29T02:04:48.3100971Z","215.0086896","1.00262270000002","12.5","0.194801593859781","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","216","2026-09-29T02:04:49.3093857Z","216.0081461","0.99945649999998","10.546875","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","217","2026-09-29T02:04:50.3125990Z","217.0118865","1.00374040000003","7.421875","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","218","2026-09-29T02:04:51.3142404Z","218.0128857","1.0009992","4.6875","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","219","2026-09-29T02:04:52.3161476Z","219.014798","1.00191229999999","10.9375","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","220","2026-09-29T02:04:53.3150220Z","220.013805","0.999007000000006","5.859375","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","221","2026-09-29T02:04:54.3152220Z","221.0137687","0.999963699999995","4.1015625","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","222","2026-09-29T02:04:55.3134387Z","222.0120419","0.9982732","4.4921875","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","223","2026-09-29T02:04:56.3160986Z","223.0149563","1.00291440000001","8.3984375","0","27632","0","0","3.24609375","13.0390625","10","194","0","0"
+"2","block","224","2026-09-29T02:04:57.3180995Z","224.017128","1.00217169999999","5.2734375","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","225","2026-09-29T02:04:58.3178488Z","225.0166566","0.999528599999991","7.2265625","0","27632","0","0","3.24609375","13.04296875","10","194","0","0"
+"2","block","226","2026-09-29T02:04:59.3059710Z","226.004644","0.987987400000009","6.54761904761905","0","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","227","2026-09-29T02:05:00.3080551Z","227.0063133","1.0016693","9.45945945945946","0.389974016374465","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","228","2026-09-29T02:05:01.3066306Z","228.005293","0.998979700000007","14.6245059288538","0","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","229","2026-09-29T02:05:02.3047371Z","229.0034025","0.998109499999998","27.1484375","0.195682437648375","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","230","2026-09-29T02:05:03.3080832Z","230.0066582","1.00325569999998","17.1153846153846","0","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","231","2026-09-29T02:05:04.3177904Z","231.0163828","1.00972460000003","9.375","0","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","232","2026-09-29T02:05:05.3045664Z","232.0032573","0.986874499999999","6.74603174603175","0","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","233","2026-09-29T02:05:06.3044291Z","233.0031124","0.999855099999991","5.2734375","0.195340804882629","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","234","2026-09-29T02:05:07.3073084Z","234.0060545","1.00294209999998","19.921875","0.194739556750089","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","235","2026-09-29T02:05:08.3122407Z","235.0109438","1.0048893","8.65384615384615","0.19436220487172","27632","0","0","3.24609375","13.046875","10","194","0","0"
+"2","block","236","2026-09-29T02:05:09.3139672Z","236.012548","1.0016042","7.03125","0","27632","0","0","3.21484375","13.03125","9","192","0","0"
+"2","block","237","2026-09-29T02:05:10.3158309Z","237.0143827","1.00183470000002","4.8828125","0","27632","0","0","3.24609375","13.03125","10","192","0","0"
+"2","block","238","2026-09-29T02:05:11.3151329Z","238.013646","0.999263299999996","7.421875","0","27632","0","0","3.24609375","13.03125","10","192","0","0"
+"2","block","239","2026-09-29T02:05:12.3046554Z","239.0032091","0.989563099999998","9.74155069582505","0","27632","0","0","3.24609375","13.03125","10","192","0","0"
+"2","block","240","2026-09-29T02:05:13.3168519Z","240.0154578","1.01224869999999","8.82917466410749","0.192949124064079","27632","0","0","3.24609375","13.03125","10","192","0","0"
+"2","block","241","2026-09-29T02:05:14.3174941Z","241.0162383","1.00078050000002","5.6640625","0","27632","0","0","3.24609375","13.03125","10","192","0","0"
+"2","block","242","2026-09-29T02:05:15.3081130Z","242.0067936","0.990555299999983","7.2265625","0","27632","0","0","3.24609375","13.03515625","10","192","0","0"
+"2","block","243","2026-09-29T02:05:16.3111798Z","243.0098973","1.0031037","8.7890625","0","27632","0","0","3.24609375","13.03515625","10","192","0","0"
+"2","block","244","2026-09-29T02:05:17.3081774Z","244.006739","0.996841700000004","10.9375","0","27632","0","0","3.24609375","13.03515625","10","192","0","0"
+"2","block","245","2026-09-29T02:05:18.3172654Z","245.0157816","1.00904260000001","11.328125","0","27632","0","0","3.24609375","13.03515625","10","192","0","0"
+"2","block","246","2026-09-29T02:05:19.3181354Z","246.0169163","1.00113469999999","6.25","0","27632","0","0","3.24609375","13.03515625","10","192","0","0"
+"2","block","247","2026-09-29T02:05:20.3114999Z","247.0100781","0.993161799999996","11.328125","0","27632","0","0","3.24609375","13.03515625","10","192","0","0"
+"2","block","248","2026-09-29T02:05:21.3123628Z","248.0110251","1.000947","7.03125","0","27632","0","0","3.24609375","13.03515625","10","192","0","0"
+"2","block","249","2026-09-29T02:05:22.3104508Z","249.0090291","0.998004000000009","8.984375","0","27632","0","0","3.24609375","13.03515625","10","192","0","0"
+"2","block","250","2026-09-29T02:05:23.3163848Z","250.0150439","1.0060148","6.0546875","0","27632","0","0","3.24609375","13.0390625","10","192","0","0"
+"2","block","251","2026-09-29T02:05:24.3036154Z","251.0023251","0.987281199999984","5.75396825396825","0","27632","0","0","3.24609375","13.0390625","10","192","0","0"
+"2","block","252","2026-09-29T02:05:25.3064567Z","252.0050958","1.00277070000001","7.8125","0","27632","0","0","3.24609375","13.04296875","10","192","0","0"
+"2","block","253","2026-09-29T02:05:26.3058041Z","253.0045717","0.999475899999993","12.6953125","0.195414916957979","27632","0","0","3.24609375","13.04296875","10","192","0","0"
+"2","block","254","2026-09-29T02:05:27.3048036Z","254.0033846","0.99881289999999","5.078125","0.195544631031499","27632","0","0","3.24609375","13.04296875","10","192","0","0"
+"2","block","255","2026-09-29T02:05:28.3039807Z","255.0025441","0.999159500000019","4.4921875","0.195476798248925","27632","0","0","3.24609375","13.04296875","10","192","0","0"
+"2","block","256","2026-09-29T02:05:29.3179822Z","256.0165714","1.01402729999998","7.30769230769231","0","27632","0","0","3.24609375","13.04296875","10","192","0","0"
+"2","block","257","2026-09-29T02:05:30.3155660Z","257.0142961","0.997724699999992","7.2265625","0","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","258","2026-09-29T02:05:31.3127507Z","258.0112167","0.99692060000001","6.8359375","0","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","259","2026-09-29T02:05:32.3108250Z","259.0094029","0.998186200000021","13.4765625","0","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","260","2026-09-29T02:05:33.3075065Z","260.0061075","0.996704599999987","12.1031746031746","0","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","261","2026-09-29T02:05:34.3037607Z","261.0022931","0.99618559999999","11.71875","0.196060352608994","27632","0.015625","0.196060352608994","3.24609375","13.046875","10","192","0","0"
+"2","block","262","2026-09-29T02:05:35.3049897Z","262.0036294","1.00133629999999","6.640625","0","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","263","2026-09-29T02:05:36.3064406Z","263.0053349","1.00170550000001","9.5703125","0.19497996167536","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","264","2026-09-29T02:05:37.3103739Z","264.0089553","1.00362039999999","10.1923076923077","0.194607941408925","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","265","2026-09-29T02:05:38.3097726Z","265.008401","0.999445700000024","10.546875","0","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","266","2026-09-29T02:05:39.3110061Z","266.009521","1.00112000000001","5.46875","0","27632","0","0","3.24609375","13.046875","10","192","0","0"
+"2","block","267","2026-09-29T02:05:40.3155493Z","267.0143292","1.00480819999996","4.8828125","0","27632","0","0","3.26953125","13.21875","12","194","0","0"
+"2","block","268","2026-09-29T02:05:41.3037863Z","268.0026359","0.98830670000001","8.33333333333333","0","27632","0","0","3.26953125","13.21875","12","194","0","0"
+"2","block","269","2026-09-29T02:05:42.3037430Z","269.0023067","0.99967079999999","7.2265625","0","27632","0","0","3.26953125","13.21875","12","194","0","0"
+"2","block","270","2026-09-29T02:05:43.3052348Z","270.003794","1.00148730000001","9.1796875","0","27632","0","0","3.26953125","13.21875","12","194","0","0"
+"2","block","271","2026-09-29T02:05:44.3055143Z","271.0040511","1.0002571","10.15625","0.195262298063168","27632","0","0","3.27734375","13.22265625","12","194","0","0"
+"2","block","272","2026-09-29T02:05:45.3169981Z","272.0155069","1.01145580000002","7.69230769230769","0","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","273","2026-09-29T02:05:46.3065814Z","273.0052673","0.989760400000023","17.0634920634921","0","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","274","2026-09-29T02:05:47.3051737Z","274.0038107","0.99854339999996","7.421875","0.195597407183311","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","275","2026-09-29T02:05:48.3149577Z","275.0137581","1.00994739999999","6.15384615384615","0.193388784406002","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","276","2026-09-29T02:05:49.3150009Z","276.0135618","0.999803700000029","7.6171875","0","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","277","2026-09-29T02:05:50.3025033Z","277.0010722","0.987510400000019","8.73015873015873","0","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","278","2026-09-29T02:05:51.3151309Z","278.0136775","1.01260529999996","6.53846153846154","0","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","279","2026-09-29T02:05:52.3161999Z","279.0148565","1.00117900000004","5.859375","0","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","280","2026-09-29T02:05:53.3155366Z","280.0137744","0.998917899999981","10.15625","0","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","281","2026-09-29T02:05:54.3145693Z","281.0131824","0.999408000000017","5.078125","0","27632","0","0","3.27734375","13.2265625","12","194","0","0"
+"2","block","282","2026-09-29T02:05:55.3155544Z","282.0141413","1.0009589","4.8828125","0","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","283","2026-09-29T02:05:56.3179038Z","283.0164894","1.00234810000001","6.8359375","0","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","284","2026-09-29T02:05:57.3037426Z","284.0022728","0.985783400000003","8.15109343936382","0","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","285","2026-09-29T02:05:58.3187905Z","285.0174268","1.015154","7.10172744721689","0","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","286","2026-09-29T02:05:59.3053524Z","286.0040359","0.986609099999953","5.75396825396825","0","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","287","2026-09-29T02:06:00.3066100Z","287.0051783","1.00114240000005","9.1796875","0.195089629607127","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","288","2026-09-29T02:06:01.3081637Z","288.0067134","1.00153509999996","15","0.195013135335954","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","289","2026-09-29T02:06:02.3108145Z","289.0093366","1.00262320000002","6.25","0","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","290","2026-09-29T02:06:03.3128610Z","290.0116333","1.00229669999999","7.03125","0","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","291","2026-09-29T02:06:04.3133905Z","291.0120514","1.00041809999999","5.078125","0","27632","0","0","3.2890625","13.23046875","12","194","0","0"
+"2","block","292","2026-09-29T02:06:05.3177955Z","292.0160527","1.00400130000003","7.2265625","0","27632","0","0","3.2890625","13.234375","12","194","0","0"
+"2","block","293","2026-09-29T02:06:06.3158559Z","293.0144622","0.99840949999998","7.421875","0","27632","0","0","3.2890625","13.23828125","12","194","0","0"
+"2","block","294","2026-09-29T02:06:07.3024085Z","294.0009236","0.986461399999996","3.96825396825397","0","27632","0","0","3.2890625","13.23828125","12","194","0","0"
+"2","block","295","2026-09-29T02:06:08.3079170Z","295.0064778","1.00555420000001","6.56370656370656","0.194233687254251","27632","0.015625","0.194233687254251","3.2890625","13.23828125","12","194","0","0"
+"2","block","296","2026-09-29T02:06:09.3058275Z","296.0044289","0.997951100000023","13.2411067193676","0","27632","0","0","3.2890625","13.23828125","12","194","0","0"
+"2","block","297","2026-09-29T02:06:10.3038113Z","297.0023705","0.99794159999999","8.203125","0.195715360498051","27632","0","0","3.2890625","13.23828125","12","194","0","0"
+"2","block","298","2026-09-29T02:06:11.3075218Z","298.0061142","1.00374370000003","10.3515625","0","27632","0","0","3.2890625","13.23828125","12","194","0","0"
+"2","block","299","2026-09-29T02:06:12.3061429Z","299.0047868","0.998672599999963","13.0859375","0","27632","0","0","3.2890625","13.23828125","12","194","0","0"
+"2","block","300","2026-09-29T02:06:13.3032919Z","300.001951","0.997164199999986","12.6953125","0.195867942310808","27632","0","0","3.2890625","13.23828125","12","194","0","0"
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow-end.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow-end.json
new file mode 100644
index 0000000..14f27af
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow-end.json
@@ -0,0 +1,12 @@
+{
+ "state": "allow",
+ "layers": {
+ "shutdown": false,
+ "local_shutdown": false,
+ "update": false,
+ "remote": false,
+ "sleep": false
+ },
+ "uptime_seconds": 333,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow-start.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow-start.json
new file mode 100644
index 0000000..d41852d
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow-start.json
@@ -0,0 +1,12 @@
+{
+ "state": "allow",
+ "layers": {
+ "shutdown": false,
+ "local_shutdown": false,
+ "update": false,
+ "remote": false,
+ "sleep": false
+ },
+ "uptime_seconds": 32,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow.csv
new file mode 100644
index 0000000..eb5ddd0
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-allow.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"3","allow","1","2026-09-29T02:23:20.9401040Z","1.0063695","1.0063666","6.42023346303502","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","2","2026-09-29T02:23:21.9593436Z","2.0255063","1.0191368","6.55105973025048","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","3","2026-09-29T02:23:22.9477151Z","3.013864","0.9883577","9.30693069306931","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","4","2026-09-29T02:23:23.9342896Z","4.0005035","0.9866395","10.7421875","0.197957308621842","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","5","2026-09-29T02:23:24.9372776Z","5.003565","1.0030615","5.859375","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","6","2026-09-29T02:23:25.9388729Z","6.0050737","1.0015087","9.9609375","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","7","2026-09-29T02:23:26.9457535Z","7.0120368","1.0069631","7.03125","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","8","2026-09-29T02:23:27.9463599Z","8.012482","1.0004452","6.0546875","0.195225585569304","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","9","2026-09-29T02:23:28.9460369Z","9.0121983","0.999716299999999","6.0546875","0.195367925880572","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","10","2026-09-29T02:23:29.9430703Z","10.0093173","0.997119","5.46875","0.195876821121652","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","11","2026-09-29T02:23:30.9444204Z","11.0106469","1.0013296","4.1015625","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","12","2026-09-29T02:23:31.9477864Z","12.0139218","1.0032749","7.421875","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","13","2026-09-29T02:23:32.9439252Z","13.0103044","0.996382599999999","6.4453125","0.196021588494219","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","14","2026-09-29T02:23:33.9481101Z","14.0143341","1.0040297","7.03125","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","15","2026-09-29T02:23:34.9445196Z","15.0108","0.9964659","12.3046875","0.196005201984333","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","16","2026-09-29T02:23:35.9572477Z","16.0233726","1.0125726","8.46153846153846","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","17","2026-09-29T02:23:36.9541196Z","17.020633","0.997260400000002","5.2734375","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","18","2026-09-29T02:23:37.9434117Z","18.0095804","0.988947400000001","7.34126984126984","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","19","2026-09-29T02:23:38.9446169Z","19.0108865","1.0013061","5.859375","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","20","2026-09-29T02:23:39.9460784Z","20.0121523","1.0012658","6.640625","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","21","2026-09-29T02:23:40.9462259Z","21.0124788","1.0003265","7.6171875","0.195248751282706","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","22","2026-09-29T02:23:41.9450893Z","22.0113567","0.9988779","13.28125","0.195531906352118","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","23","2026-09-29T02:23:42.9455986Z","23.0120194","1.0006627","5.6640625","0.195183152125087","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","24","2026-09-29T02:23:43.9440744Z","24.0104759","0.9984565","5.46875","0.195614430874054","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","25","2026-09-29T02:23:44.9503367Z","25.0172367","1.0067608","10.1923076923077","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","26","2026-09-29T02:23:45.9348913Z","26.0005933","0.9833566","9.32539682539683","0","25272","0","0","1.99609375","12.578125","8","176","0","0"
+"3","allow","27","2026-09-29T02:23:46.9494873Z","27.0157492","1.0151559","7.5","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","28","2026-09-29T02:23:47.9485906Z","28.0147357","0.998986500000001","9.375","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","29","2026-09-29T02:23:48.9392060Z","29.0053443","0.990608599999998","10.9126984126984","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","30","2026-09-29T02:23:49.9376777Z","30.0038739","0.998529600000001","7.24070450097847","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","31","2026-09-29T02:23:50.9433342Z","31.0095884","1.0057145","6.23781676413255","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","32","2026-09-29T02:23:51.9575575Z","32.0237292","1.0141408","6.15384615384615","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","33","2026-09-29T02:23:52.9564168Z","33.0225577","0.998828500000002","9.39334637964775","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","34","2026-09-29T02:23:53.9393250Z","34.0056609","0.983103199999995","5.94059405940594","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","35","2026-09-29T02:23:54.9573115Z","35.0235158","1.0178549","5.96153846153846","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","36","2026-09-29T02:23:55.9552646Z","36.0213604","0.997844600000001","9.19765166340509","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","37","2026-09-29T02:23:56.9372896Z","37.0037999","0.982439499999998","10.2970297029703","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","38","2026-09-29T02:23:57.9380361Z","38.0041962","1.0003963","7.421875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","39","2026-09-29T02:23:58.9384479Z","39.004561","1.0003648","6.640625","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","40","2026-09-29T02:23:59.9352158Z","40.0013964","0.996835400000002","7.2265625","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","41","2026-09-29T02:24:00.9355973Z","41.0016372","1.0002408","7.03125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","42","2026-09-29T02:24:01.9491582Z","42.0154495","1.0138123","8.26923076923077","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","43","2026-09-29T02:24:02.9455269Z","43.0118145","0.996365000000004","11.1111111111111","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","44","2026-09-29T02:24:03.9488797Z","44.0151923","1.0033778","7.11538461538461","0.194654994360051","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","45","2026-09-29T02:24:04.9355966Z","45.0017396","0.986547300000005","9.72222222222222","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","46","2026-09-29T02:24:05.9494750Z","46.0157346","1.01399499999999","7.88461538461539","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","47","2026-09-29T02:24:06.9343426Z","47.0004954","0.984760800000004","5.75396825396825","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","48","2026-09-29T02:24:07.9336243Z","47.9997633","0.9992679","13.8671875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","49","2026-09-29T02:24:08.9340854Z","49.0002519","1.0004886","7.421875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","50","2026-09-29T02:24:09.9476845Z","50.013863","1.01361110000001","16.40625","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","51","2026-09-29T02:24:10.9469075Z","51.0130922","0.999229199999995","33.7890625","0.195463163006046","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","52","2026-09-29T02:24:11.9335928Z","51.9997454","0.986653199999999","8.3984375","0.197954559920345","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","53","2026-09-29T02:24:12.9466937Z","53.0128554","1.01311","14.453125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","54","2026-09-29T02:24:13.9476012Z","54.0139521","1.0010967","10.15625","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","55","2026-09-29T02:24:14.9340484Z","55.0003066","0.986354499999997","6.0546875","0.19801450695465","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","56","2026-09-29T02:24:15.9475728Z","56.0138027","1.0134961","13.28125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","57","2026-09-29T02:24:16.9486457Z","57.0149793","1.0011766","13.4615384615385","0.390165930765861","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","58","2026-09-29T02:24:17.9454221Z","58.0116135","0.996634199999995","11.7063492063492","0.39194420580791","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","59","2026-09-29T02:24:18.9444642Z","59.0106448","0.999031299999999","5.6640625","0.195501882673746","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","60","2026-09-29T02:24:19.9444567Z","60.0106016","0.9999568","6.4453125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","61","2026-09-29T02:24:20.9530649Z","61.0186187","1.0080171","10.1923076923077","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","62","2026-09-29T02:24:21.9376574Z","62.0034105","0.984791799999996","6.74603174603175","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","63","2026-09-29T02:24:22.9373338Z","63.0030207","0.999610200000006","4.6875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","64","2026-09-29T02:24:23.9357944Z","64.0019349","0.998914199999994","5.859375","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","65","2026-09-29T02:24:24.9482885Z","65.0145512","1.0126163","6.25","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","66","2026-09-29T02:24:25.9362392Z","66.001852","0.9873008","6.25","0.197824715628712","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","67","2026-09-29T02:24:26.9383405Z","67.0044956","1.0026436","8.0078125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","68","2026-09-29T02:24:27.9385689Z","68.0043395","0.999843900000002","6.0546875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","69","2026-09-29T02:24:28.9380259Z","69.0042561","0.999916599999992","7.6171875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","70","2026-09-29T02:24:29.9348577Z","70.0011081","0.996852000000004","9.1796875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","71","2026-09-29T02:24:30.9349823Z","71.0011346","1.0000265","5.859375","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","72","2026-09-29T02:24:31.9375722Z","72.003933","1.0027984","8.3984375","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","73","2026-09-29T02:24:32.9423710Z","73.0081137","1.00418069999999","5.2734375","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","74","2026-09-29T02:24:33.9557832Z","74.0218494","1.0137357","7.5","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","75","2026-09-29T02:24:34.9370368Z","75.0032243","0.981374900000006","3.96825396825397","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","76","2026-09-29T02:24:35.9381463Z","76.0043379","1.0011136","7.03125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","77","2026-09-29T02:24:36.9404592Z","77.0060903","1.0017524","8.203125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","78","2026-09-29T02:24:37.9582799Z","78.0244345","1.0183442","5.57692307692308","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","79","2026-09-29T02:24:38.9569893Z","79.0233053","0.998870799999992","7.03125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","80","2026-09-29T02:24:39.9463939Z","80.0126135","0.989308200000011","4.56349206349206","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","81","2026-09-29T02:24:40.9456121Z","81.011961","0.999347499999999","8.0078125","0.195440024616062","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","82","2026-09-29T02:24:41.9458119Z","82.0120007","1.0000397","7.8125","0.195304746401567","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","83","2026-09-29T02:24:42.9462649Z","83.0125197","1.000519","4.8828125","0.195211185394781","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","84","2026-09-29T02:24:43.9489102Z","84.0151445","1.00262479999999","13.8461538461538","0.194801185847389","25272","0.015625","0.194801185847389","1.96484375","12.5625","7","176","0","0"
+"3","allow","85","2026-09-29T02:24:44.9476162Z","85.013747","0.998602500000004","16.2698412698413","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","86","2026-09-29T02:24:45.9463436Z","86.012559","0.998812000000001","12.890625","0.19554480723099","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","87","2026-09-29T02:24:46.9492080Z","87.0153699","1.0028109","15.5769230769231","0.194765034963222","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","88","2026-09-29T02:24:47.9374523Z","88.0035859","0.988215999999994","9.72222222222222","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","89","2026-09-29T02:24:48.9390799Z","89.0051849","1.001599","5.078125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","90","2026-09-29T02:24:49.9388764Z","90.0050046","0.999819700000003","6.4453125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","91","2026-09-29T02:24:50.9446345Z","91.0107648","1.0057602","5.6640625","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","92","2026-09-29T02:24:51.9461930Z","92.0124034","1.00163860000001","7.03125","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","93","2026-09-29T02:24:52.9353372Z","93.0014192","0.989015800000004","9.9609375","0.197481678250235","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","94","2026-09-29T02:24:53.9381590Z","94.0042795","1.00286029999999","5.46875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","95","2026-09-29T02:24:54.9405005Z","95.0067718","1.0024923","5.46875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","96","2026-09-29T02:24:55.9575683Z","96.0236787","1.0169069","5.38461538461539","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","97","2026-09-29T02:24:56.9526602Z","97.0189802","0.995301500000011","17.96875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","98","2026-09-29T02:24:57.9482230Z","98.0067255","0.9877453","7.93650793650794","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","99","2026-09-29T02:24:58.9427680Z","99.0088938","1.00216829999999","6.640625","0.194889920186062","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","100","2026-09-29T02:24:59.9464517Z","100.0133322","1.0044384","6.0546875","0","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","101","2026-09-29T02:25:00.9441449Z","101.010252","0.996919800000001","9.765625","0.195915960341042","25272","0","0","1.96484375","12.5625","7","176","0","0"
+"3","allow","102","2026-09-29T02:25:01.9452356Z","102.011462","1.00121","7.2265625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","103","2026-09-29T02:25:02.9465418Z","103.0128492","1.0013872","5.46875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","104","2026-09-29T02:25:03.9462834Z","104.0124438","0.999594600000009","5.078125","0.195391711799962","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","105","2026-09-29T02:25:04.9453896Z","105.0115882","0.999144399999992","6.640625","0.19547975247622","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","106","2026-09-29T02:25:05.9459912Z","106.0123607","1.00077250000001","5.6640625","0.195161737557735","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","107","2026-09-29T02:25:06.9483171Z","107.0146306","1.00226989999999","16.1849710982659","0.389740328428505","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","108","2026-09-29T02:25:07.9373637Z","108.0034788","0.988848200000007","5.94059405940594","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","109","2026-09-29T02:25:08.9365829Z","109.0028176","0.999338800000004","5.2734375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","110","2026-09-29T02:25:09.9475616Z","110.0137935","1.01097589999999","12.5","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","111","2026-09-29T02:25:10.9452368Z","111.0115062","0.997712700000008","9.1796875","0.195760262448296","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","112","2026-09-29T02:25:11.9581947Z","112.0243738","1.01286759999999","6.34615384615385","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","113","2026-09-29T02:25:12.9580951Z","113.0241818","0.999808000000002","6.4453125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","114","2026-09-29T02:25:13.9573400Z","114.0233229","0.999141100000003","6.640625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","115","2026-09-29T02:25:14.9564449Z","115.0225312","0.999208299999992","26.7578125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","116","2026-09-29T02:25:15.9524794Z","116.0188382","0.996307000000002","22.0703125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","117","2026-09-29T02:25:16.9453886Z","117.0115598","0.99272160000001","23.2142857142857","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","118","2026-09-29T02:25:17.9431316Z","118.0093146","0.997754799999996","7.8125","0.19575200239578","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","119","2026-09-29T02:25:18.9577731Z","119.0239372","1.0146226","8.26923076923077","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","120","2026-09-29T02:25:19.9584317Z","120.0246999","1.00076270000001","5.46875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","121","2026-09-29T02:25:20.9554407Z","121.0215587","0.996858799999998","7.6320939334638","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","122","2026-09-29T02:25:21.9386866Z","122.004833","0.983274299999991","8.51485148514852","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","123","2026-09-29T02:25:22.9360190Z","123.0021438","0.997310800000008","5.2734375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","124","2026-09-29T02:25:23.9388665Z","124.0049921","1.0028483","5.6640625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","125","2026-09-29T02:25:24.9408726Z","125.0070751","1.002083","6.25","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","126","2026-09-29T02:25:25.9438970Z","126.0101255","1.00305040000001","8.3984375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","127","2026-09-29T02:25:26.9581660Z","127.0244327","1.01430719999999","10.9615384615385","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","128","2026-09-29T02:25:27.9572828Z","128.022862","0.998429300000012","5.078125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","129","2026-09-29T02:25:28.9580516Z","129.024317","1.00145499999999","6.8359375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","130","2026-09-29T02:25:29.9539154Z","130.0201122","0.995795200000003","6.25","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","131","2026-09-29T02:25:30.9388991Z","131.0045322","0.98442","8.53174603174603","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","132","2026-09-29T02:25:31.9383825Z","132.0045058","0.999973600000004","5.46875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","133","2026-09-29T02:25:32.9422068Z","133.0083839","1.00387809999998","6.640625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","134","2026-09-29T02:25:33.9584375Z","134.0245859","1.01620200000002","7.11538461538461","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","135","2026-09-29T02:25:34.9496690Z","135.0159395","0.991353599999997","8.203125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","136","2026-09-29T02:25:35.9390132Z","136.0051192","0.989179699999994","5.95238095238095","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","137","2026-09-29T02:25:36.9474915Z","137.01334","1.0082208","16.015625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","138","2026-09-29T02:25:37.9464677Z","138.0126155","0.999275499999982","14.453125","0.195454106500163","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","139","2026-09-29T02:25:38.9461416Z","139.0122938","0.999678299999999","6.8359375","0.195375352250819","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","140","2026-09-29T02:25:39.9352022Z","140.0015019","0.989208100000013","8.0078125","0.197443288222162","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","141","2026-09-29T02:25:40.9368662Z","141.003013","1.00151109999999","4.8828125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","142","2026-09-29T02:25:41.9353979Z","142.0018235","0.998810500000019","6.4453125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","143","2026-09-29T02:25:42.9367922Z","143.0030318","1.0012083","4.6875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","144","2026-09-29T02:25:43.9423516Z","144.0080848","1.005053","5.46875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","145","2026-09-29T02:25:44.9450017Z","145.0108138","1.00272899999999","7.421875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","146","2026-09-29T02:25:45.9464475Z","146.012651","1.00183720000001","12.3046875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","147","2026-09-29T02:25:46.9472855Z","147.0136369","1.00098589999999","7.2265625","0.195120131062787","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","148","2026-09-29T02:25:47.9443190Z","148.010455","0.996818100000013","26.3671875","0.195935948594831","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","149","2026-09-29T02:25:48.9469924Z","149.0132401","1.00278509999998","7.6171875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","150","2026-09-29T02:25:49.9448623Z","150.0110711","0.997830999999991","8.203125","0.195737053669411","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","151","2026-09-29T02:25:50.9455196Z","151.0116918","1.00062070000001","5.46875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","152","2026-09-29T02:25:51.9441987Z","152.0103125","0.998620700000004","6.25","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","153","2026-09-29T02:25:52.9586758Z","153.0247695","1.01445699999999","6.92307692307692","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","154","2026-09-29T02:25:53.9581464Z","154.0243515","0.999582000000004","8.7890625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","155","2026-09-29T02:25:54.9575278Z","155.0236718","0.999320299999994","3.90625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","156","2026-09-29T02:25:55.9585187Z","156.0249318","1.00126","5.078125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","157","2026-09-29T02:25:56.9573292Z","157.0234552","0.99852340000001","5.46875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","158","2026-09-29T02:25:57.9564693Z","158.0225325","0.999077299999982","14.6484375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","159","2026-09-29T02:25:58.9420322Z","159.0077475","0.985215000000011","5.35714285714286","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","160","2026-09-29T02:25:59.9556580Z","160.0219125","1.01416499999999","5.76923076923077","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","161","2026-09-29T02:26:00.9421311Z","161.0082365","0.986323999999996","6.94444444444444","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","162","2026-09-29T02:26:01.9384776Z","162.00464","0.996403500000014","7.6171875","0.196017476855508","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","163","2026-09-29T02:26:02.9373062Z","163.0034521","0.998812100000009","6.4453125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","164","2026-09-29T02:26:03.9400925Z","164.0063654","1.00291329999999","4.6875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","165","2026-09-29T02:26:04.9410617Z","165.007148","1.00078260000001","8.7890625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","166","2026-09-29T02:26:05.9442589Z","166.0104976","1.00334959999998","6.0546875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","167","2026-09-29T02:26:06.9473831Z","167.0135767","1.00307910000001","7.03125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","168","2026-09-29T02:26:07.9459778Z","168.0121242","0.998547500000001","12.6953125","0.195596604067408","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","169","2026-09-29T02:26:08.9399526Z","169.0061022","0.993977999999998","8.984375","0.196495797693712","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","170","2026-09-29T02:26:09.9403367Z","170.0066677","1.00056549999999","8.0078125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","171","2026-09-29T02:26:10.9451562Z","171.0112953","1.00462760000002","11.1328125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","172","2026-09-29T02:26:11.9435489Z","172.009659","0.998363699999999","5.2734375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","173","2026-09-29T02:26:12.9455894Z","173.0118685","1.00220949999999","5.2734375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","174","2026-09-29T02:26:13.9484978Z","174.0146744","1.0028059","17.0873786407767","0.194766006063586","25272","0.015625","0.194766006063586","1.90625","12.5390625","5","174","0","0"
+"3","allow","175","2026-09-29T02:26:14.9482325Z","175.0143448","0.999670400000014","10.4125736738703","0.195376896224993","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","176","2026-09-29T02:26:15.9468489Z","176.0130281","0.998683299999982","13.8671875","0.195570007028258","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","177","2026-09-29T02:26:16.9478539Z","177.014069","1.00104089999999","9.765625","0.195109410614493","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","178","2026-09-29T02:26:17.9444029Z","178.0105256","0.996456600000016","13.28125","0.196007031314758","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","179","2026-09-29T02:26:18.9342944Z","179.0004246","0.989899000000008","9.375","0.197305482680555","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","180","2026-09-29T02:26:19.9340583Z","180.0002045","0.999779899999993","6.8359375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","181","2026-09-29T02:26:20.9389466Z","181.0050802","1.00487569999999","6.8359375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","182","2026-09-29T02:26:21.9424373Z","182.0086046","1.0035244","8.984375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","183","2026-09-29T02:26:22.9441304Z","183.0103104","1.0017058","6.8359375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","184","2026-09-29T02:26:23.9575102Z","184.0236569","1.01334650000001","5.19230769230769","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","185","2026-09-29T02:26:24.9555737Z","185.0216943","0.998037399999987","7.8125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","186","2026-09-29T02:26:25.9420336Z","186.0081213","0.98642700000002","6.15079365079365","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","187","2026-09-29T02:26:26.9472929Z","187.013621","1.0054997","5.078125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","188","2026-09-29T02:26:27.9473296Z","188.0135669","0.9999459","9.9609375","0.195323066977923","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","189","2026-09-29T02:26:28.9350892Z","189.0012275","0.987660599999998","8.203125","0.197752649037534","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","190","2026-09-29T02:26:29.9392939Z","190.005436","1.0042085","7.2265625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","191","2026-09-29T02:26:30.9356899Z","191.0017525","0.996316499999978","8.0078125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","192","2026-09-29T02:26:31.9382976Z","192.0044919","1.00273940000002","5.859375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","193","2026-09-29T02:26:32.9422072Z","193.0083142","1.0038223","6.25","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","194","2026-09-29T02:26:33.9567898Z","194.02306","1.01474579999999","6.92307692307692","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","195","2026-09-29T02:26:34.9557527Z","195.0220703","0.999010300000009","10.15625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","196","2026-09-29T02:26:35.9591169Z","196.0252448","1.0031745","5.2734375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","197","2026-09-29T02:26:36.9459417Z","197.0123765","0.987131699999992","5.75396825396825","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","198","2026-09-29T02:26:37.9427447Z","198.0089692","0.996592700000008","9.765625","0.195980263551999","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","199","2026-09-29T02:26:38.9566534Z","199.0229008","1.01393160000001","5","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","200","2026-09-29T02:26:39.9397049Z","200.0058376","0.982936799999976","5.15873015873016","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","201","2026-09-29T02:26:40.9402454Z","201.0064597","1.00062210000002","5.46875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","202","2026-09-29T02:26:41.9548201Z","202.0209248","1.0144651","5.96153846153846","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","203","2026-09-29T02:26:42.9428026Z","203.0090824","0.988157599999994","4.76190476190476","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","204","2026-09-29T02:26:43.9483560Z","204.0146391","1.0055567","9.92217898832685","0.19423320435337","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","205","2026-09-29T02:26:44.9407385Z","205.0070343","0.992395200000004","10.7843137254902","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","206","2026-09-29T02:26:45.9564621Z","206.022626","1.01559170000002","7.5","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","207","2026-09-29T02:26:46.9417539Z","207.007957","0.985331000000002","5.55555555555556","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","208","2026-09-29T02:26:47.9533440Z","208.0194695","1.01151249999998","9.42307692307692","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","209","2026-09-29T02:26:48.9411617Z","209.0074219","0.987952400000012","8.13492063492063","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","210","2026-09-29T02:26:49.9447934Z","210.0110193","1.00359739999999","6.8359375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","211","2026-09-29T02:26:50.9460137Z","211.0122","1.00118069999999","11.5234375","0.195082166486032","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","212","2026-09-29T02:26:51.9392196Z","212.0053571","0.993157100000019","6.0546875","0.196658212482191","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","213","2026-09-29T02:26:52.9401917Z","213.0064344","1.00107729999999","5.859375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","214","2026-09-29T02:26:53.9562353Z","214.0220115","1.0155771","7.5","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","215","2026-09-29T02:26:54.9523046Z","215.0184898","0.996478300000007","4.6875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","216","2026-09-29T02:26:55.9483874Z","216.0145999","0.996110099999981","14.0316205533597","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","217","2026-09-29T02:26:56.9470213Z","217.0131283","0.998528399999998","13.3333333333333","0.195600345468392","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","218","2026-09-29T02:26:57.9349388Z","218.001006","0.987877700000013","13.8671875","0.197709190115333","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","219","2026-09-29T02:26:58.9343620Z","219.0005194","0.999513400000012","15.625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","220","2026-09-29T02:26:59.9472000Z","220.0133857","1.01286629999998","11.71875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","221","2026-09-29T02:27:00.9495047Z","221.0156612","1.0022755","7.30769230769231","0.194869075418885","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","222","2026-09-29T02:27:01.9480155Z","222.0141511","0.99848990000001","9.92063492063492","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","223","2026-09-29T02:27:02.9352606Z","223.0013479","0.987196799999992","11.328125","0.197845556225467","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","224","2026-09-29T02:27:03.9433778Z","224.0095165","1.0081686","6.640625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","225","2026-09-29T02:27:04.9488739Z","225.01516","1.00564349999999","8.46153846153846","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","226","2026-09-29T02:27:05.9460439Z","226.0122917","0.997131700000011","12.5","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","227","2026-09-29T02:27:06.9428029Z","227.0089017","0.996610000000004","5.859375","0.19597686156069","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","228","2026-09-29T02:27:07.9451878Z","228.0113007","1.002399","9.5703125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","229","2026-09-29T02:27:08.9467977Z","229.0129775","1.00167679999998","8.7890625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","230","2026-09-29T02:27:09.9333127Z","229.9996613","0.986683800000009","12.5","0.19794842076053","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","231","2026-09-29T02:27:10.9350673Z","231.0011145","1.00145320000001","5.6640625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","232","2026-09-29T02:27:11.9499689Z","232.0160627","1.01494819999999","6.34615384615385","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","233","2026-09-29T02:27:12.9471248Z","233.0133114","0.9972487","16.468253968254","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","234","2026-09-29T02:27:13.9368116Z","234.0028611","0.989549699999998","37.109375","0.197375129313869","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","235","2026-09-29T02:27:14.9428418Z","235.009029","1.00616790000001","19.140625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","236","2026-09-29T02:27:15.9554395Z","236.0216291","1.01260009999999","8.46153846153846","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","237","2026-09-29T02:27:16.9372955Z","237.0033947","0.981765600000017","7.93650793650794","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","238","2026-09-29T02:27:17.9391722Z","238.005393","1.0019983","6.8359375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","239","2026-09-29T02:27:18.9391659Z","239.0053686","0.999975599999999","8.59375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","240","2026-09-29T02:27:19.9400276Z","240.0061204","1.00075179999999","4.30528375733855","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","241","2026-09-29T02:27:20.9390300Z","241.0052424","0.999122","8.38206627680312","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","242","2026-09-29T02:27:21.9370013Z","242.003169","0.9979266","6.8359375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","243","2026-09-29T02:27:22.9366150Z","243.0028212","0.999652200000014","4.1015625","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","244","2026-09-29T02:27:23.9370728Z","244.0034329","1.00061169999998","5.859375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","245","2026-09-29T02:27:24.9481842Z","245.0139278","1.0104949","8.0078125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","246","2026-09-29T02:27:25.9384179Z","246.0046635","0.990735700000016","8.7890625","0.197138853480294","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","247","2026-09-29T02:27:26.9385219Z","247.0048357","1.00017220000001","4.8828125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","248","2026-09-29T02:27:27.9359199Z","248.0020278","0.997192099999978","5.859375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","249","2026-09-29T02:27:28.9392224Z","249.0054229","1.00339510000001","8.0078125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","250","2026-09-29T02:27:29.9432031Z","250.0094062","1.00398330000002","4.296875","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","251","2026-09-29T02:27:30.9475815Z","251.0138156","1.00440939999999","9.375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","252","2026-09-29T02:27:31.9464389Z","252.012558","0.998742399999998","5.46875","0.19555843428696","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","253","2026-09-29T02:27:32.9353161Z","253.0014515","0.988893500000017","7.6171875","0.197506101516489","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","254","2026-09-29T02:27:33.9485060Z","254.0148208","1.01336929999999","10.2119460500963","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","255","2026-09-29T02:27:34.9402881Z","255.0064352","0.991614400000003","12.8712871287129","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","256","2026-09-29T02:27:35.9547701Z","256.0208114","1.01437620000002","7.30769230769231","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","257","2026-09-29T02:27:36.9445368Z","257.0107151","0.989903699999957","9.12698412698413","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","258","2026-09-29T02:27:37.9442682Z","258.010603","0.999887900000033","9.9609375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","259","2026-09-29T02:27:38.9570746Z","259.0232252","1.01262220000001","8.65384615384615","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","260","2026-09-29T02:27:39.9581291Z","260.0243026","1.00107739999999","7.03125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","261","2026-09-29T02:27:40.9502026Z","261.0163564","0.992053800000008","7.03125","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","262","2026-09-29T02:27:41.9491985Z","262.0153622","0.999005799999964","13.0859375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","263","2026-09-29T02:27:42.9365315Z","263.002754","0.987391800000012","4.36507936507936","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","264","2026-09-29T02:27:43.9373071Z","264.0030938","1.00033980000001","5.2734375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","265","2026-09-29T02:27:44.9465732Z","265.0127972","1.00970339999998","5.2734375","0","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","266","2026-09-29T02:27:45.9474025Z","266.013571","1.00077380000005","11.9140625","0.195161484043638","25272","0","0","1.90625","12.5390625","5","174","0","0"
+"3","allow","267","2026-09-29T02:27:46.9464061Z","267.0126966","0.999125599999957","9.1796875","0.195483430711823","25272","0","0","1.96875","12.7109375","7","174","0","0"
+"3","allow","268","2026-09-29T02:27:47.9470146Z","268.0132313","1.0005347","9.5703125","0.19520812221705","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","269","2026-09-29T02:27:48.9338298Z","268.99989","0.986658700000021","9.5703125","0.197953456448512","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","270","2026-09-29T02:27:49.9435466Z","270.009661","1.009771","5.2734375","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","271","2026-09-29T02:27:50.9440556Z","271.0103293","1.00066829999997","6.0546875","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","272","2026-09-29T02:27:51.9452094Z","272.0108805","1.00055120000002","5.078125","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","273","2026-09-29T02:27:52.9495002Z","273.0158162","1.00493569999998","5.38461538461539","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","274","2026-09-29T02:27:53.9464534Z","274.0120588","0.996242600000016","10.9126984126984","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","275","2026-09-29T02:27:54.9351324Z","275.0012997","0.989240900000027","8.7890625","0.197436741647049","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","276","2026-09-29T02:27:55.9380132Z","276.0046407","1.00334099999998","4.296875","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","277","2026-09-29T02:27:56.9390456Z","277.0052669","1.0006262","6.25","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","278","2026-09-29T02:27:57.9389034Z","278.0051019","0.999835000000019","7.6171875","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","279","2026-09-29T02:27:58.9361128Z","279.0022068","0.997104900000011","12.890625","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","280","2026-09-29T02:27:59.9469847Z","280.0131118","1.01090499999998","5.6640625","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","281","2026-09-29T02:28:00.9338864Z","281.0001484","0.98703660000001","10.3515625","0.197877667352961","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","282","2026-09-29T02:28:01.9473320Z","282.0135857","1.01343729999996","15.625","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","283","2026-09-29T02:28:02.9477471Z","283.0140175","1.0004318","10.15625","0.19522820046304","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","284","2026-09-29T02:28:03.9462409Z","284.012503","0.998485500000015","10.3515625","0.195608749451041","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","285","2026-09-29T02:28:04.9467315Z","285.0130639","1.00056089999998","6.0546875","0.19520301063134","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","286","2026-09-29T02:28:05.9418212Z","286.0079983","0.994934400000034","7.421875","0.196306912294914","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","287","2026-09-29T02:28:06.9574547Z","287.0235915","1.01559320000001","7.69230769230769","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","288","2026-09-29T02:28:07.9566658Z","288.0228539","0.999262399999964","5.859375","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","289","2026-09-29T02:28:08.9354505Z","289.0015591","0.978705200000036","9.32539682539683","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","290","2026-09-29T02:28:09.9402430Z","290.0065337","1.00497459999997","5.6640625","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","291","2026-09-29T02:28:10.9516141Z","291.0114015","1.0048678","16.1793372319688","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","292","2026-09-29T02:28:11.9411159Z","292.0073524","0.995950900000025","12.720156555773","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","293","2026-09-29T02:28:12.9447966Z","293.0109466","1.00359420000001","8.3984375","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","294","2026-09-29T02:28:13.9447302Z","294.0106116","0.999664999999993","9.5703125","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","295","2026-09-29T02:28:14.9461556Z","295.0125066","1.00189499999999","6.4453125","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","296","2026-09-29T02:28:15.9450298Z","296.0113646","0.998857999999984","9.375","0.195535801885757","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","297","2026-09-29T02:28:16.9459212Z","297.0122074","1.00084279999999","7.2265625","0.195148029240958","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","298","2026-09-29T02:28:17.9490198Z","298.0151957","1.00298830000003","11.1538461538462","0.194730586588094","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","299","2026-09-29T02:28:18.9470072Z","299.013206","0.998010299999976","15.2777777777778","0","25272","0","0","1.96875","12.71484375","7","174","0","0"
+"3","allow","300","2026-09-29T02:28:19.9374726Z","300.0035865","0.990380500000015","11.71875","0.197209557336798","25272","0","0","1.96875","12.71484375","7","174","0","0"
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-baseline.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-baseline.csv
new file mode 100644
index 0000000..bb57a1e
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-baseline.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"3","baseline","1","2026-09-29T02:17:47.8680735Z","1.0102562","1.0102538","7.6171875","0","","","","","","","","",""
+"3","baseline","2","2026-09-29T02:17:48.8710333Z","2.0131844","1.0029282","10.7692307692308","0","","","","","","","","",""
+"3","baseline","3","2026-09-29T02:17:49.8730063Z","3.0150606","1.0018762","5.859375","0","","","","","","","","",""
+"3","baseline","4","2026-09-29T02:17:50.8603783Z","4.0025087","0.9874481","6.54761904761905","0","","","","","","","","",""
+"3","baseline","5","2026-09-29T02:17:51.8629434Z","5.005046","1.0025373","7.8125","0","","","","","","","","",""
+"3","baseline","6","2026-09-29T02:17:52.8615484Z","6.0039621","0.9989161","20.1171875","0","","","","","","","","",""
+"3","baseline","7","2026-09-29T02:17:53.8709673Z","7.0130116","1.0090495","7.88461538461539","0","","","","","","","","",""
+"3","baseline","8","2026-09-29T02:17:54.8755365Z","8.017168","1.0041564","6.0546875","0","","","","","","","","",""
+"3","baseline","9","2026-09-29T02:17:55.8612336Z","9.0033543","0.9861863","4.56349206349206","0","","","","","","","","",""
+"3","baseline","10","2026-09-29T02:17:56.8596838Z","10.0017852","0.998430899999999","5.0880626223092","0","","","","","","","","",""
+"3","baseline","11","2026-09-29T02:17:57.8589698Z","11.0010615","0.9992763","5.87084148727984","0","","","","","","","","",""
+"3","baseline","12","2026-09-29T02:17:58.8583135Z","12.0003539","0.9992924","6.42023346303502","0","","","","","","","","",""
+"3","baseline","13","2026-09-29T02:17:59.8635378Z","13.0050549","1.004701","5.859375","0","","","","","","","","",""
+"3","baseline","14","2026-09-29T02:18:00.8614873Z","14.0035564","0.9985015","8.203125","0","","","","","","","","",""
+"3","baseline","15","2026-09-29T02:18:01.8655951Z","15.0077155","1.0041591","16.40625","0","","","","","","","","",""
+"3","baseline","16","2026-09-29T02:18:02.8680694Z","16.0101636","1.0024481","6.25","0","","","","","","","","",""
+"3","baseline","17","2026-09-29T02:18:03.8669186Z","17.0090162","0.998852599999999","5.859375","0","","","","","","","","",""
+"3","baseline","18","2026-09-29T02:18:04.8661922Z","18.0083503","0.999334100000002","4.8828125","0","","","","","","","","",""
+"3","baseline","19","2026-09-29T02:18:05.8667773Z","19.008971","1.0006207","8.0078125","0","","","","","","","","",""
+"3","baseline","20","2026-09-29T02:18:06.8780509Z","20.0201119","1.0111409","5.76923076923077","0","","","","","","","","",""
+"3","baseline","21","2026-09-29T02:18:07.8661747Z","21.0086299","0.988517999999999","5.75396825396825","0","","","","","","","","",""
+"3","baseline","22","2026-09-29T02:18:08.8682875Z","22.0105659","1.001936","6.0546875","0","","","","","","","","",""
+"3","baseline","23","2026-09-29T02:18:09.8726793Z","23.01488","1.0043141","15.1923076923077","0","","","","","","","","",""
+"3","baseline","24","2026-09-29T02:18:10.8702793Z","24.0124783","0.9975983","11.9140625","0.19578271133782","","","","","","","","",""
+"3","baseline","25","2026-09-29T02:18:11.8684864Z","25.0105345","0.998056200000001","15.2777777777778","0","","","","","","","","",""
+"3","baseline","26","2026-09-29T02:18:12.8667643Z","26.0088852","0.9983507","8.0078125","0","","","","","","","","",""
+"3","baseline","27","2026-09-29T02:18:13.8662323Z","27.0083483","0.9994631","10.546875","0","","","","","","","","",""
+"3","baseline","28","2026-09-29T02:18:14.8674769Z","28.0095751","1.0012268","6.640625","0","","","","","","","","",""
+"3","baseline","29","2026-09-29T02:18:15.8721613Z","29.01446","1.0048849","6.73076923076923","0","","","","","","","","",""
+"3","baseline","30","2026-09-29T02:18:16.8709160Z","30.0129684","0.998508399999999","5.859375","0","","","","","","","","",""
+"3","baseline","31","2026-09-29T02:18:17.8722786Z","31.0145901","1.0016217","5.6640625","0","","","","","","","","",""
+"3","baseline","32","2026-09-29T02:18:18.8713203Z","32.0133835","0.998793399999997","5.078125","0","","","","","","","","",""
+"3","baseline","33","2026-09-29T02:18:19.8675801Z","33.0097772","0.996393700000006","9.92063492063492","0","","","","","","","","",""
+"3","baseline","34","2026-09-29T02:18:20.8678711Z","34.0101238","1.00034659999999","5.46875","0","","","","","","","","",""
+"3","baseline","35","2026-09-29T02:18:21.8700821Z","35.0121049","1.0019811","15.8203125","0","","","","","","","","",""
+"3","baseline","36","2026-09-29T02:18:22.8692002Z","36.0112227","0.9991178","7.8125","0.195484956828914","","","","","","","","",""
+"3","baseline","37","2026-09-29T02:18:23.8708421Z","37.013013","1.0017903","12.8846153846154","0","","","","","","","","",""
+"3","baseline","38","2026-09-29T02:18:24.8767378Z","38.0188454","1.0058324","4.1015625","0","","","","","","","","",""
+"3","baseline","39","2026-09-29T02:18:25.8638485Z","39.0059578","0.987112400000001","7.73809523809524","0","","","","","","","","",""
+"3","baseline","40","2026-09-29T02:18:26.8638097Z","40.0065452","1.0005874","4.8828125","0","","","","","","","","",""
+"3","baseline","41","2026-09-29T02:18:27.8629272Z","41.0051378","0.998592600000002","6.25","0","","","","","","","","",""
+"3","baseline","42","2026-09-29T02:18:28.8659728Z","42.0082911","1.0031533","5.859375","0","","","","","","","","",""
+"3","baseline","43","2026-09-29T02:18:29.8660544Z","43.0080787","0.999787599999998","5.46875","0","","","","","","","","",""
+"3","baseline","44","2026-09-29T02:18:30.8676901Z","44.0098934","1.0018147","9.375","0","","","","","","","","",""
+"3","baseline","45","2026-09-29T02:18:31.8662301Z","45.0083321","0.998438700000001","8.203125","0","","","","","","","","",""
+"3","baseline","46","2026-09-29T02:18:32.8783310Z","46.0204955","1.0121634","11.9230769230769","0","","","","","","","","",""
+"3","baseline","47","2026-09-29T02:18:33.8731981Z","47.0125218","0.992026299999999","13.8671875","0.196882381041712","","","","","","","","",""
+"3","baseline","48","2026-09-29T02:18:34.8728723Z","48.0149896","1.00246780000001","20.5078125","0","","","","","","","","",""
+"3","baseline","49","2026-09-29T02:18:35.8612610Z","49.0034623","0.988472699999996","5.36779324055666","0","","","","","","","","",""
+"3","baseline","50","2026-09-29T02:18:36.8668836Z","50.0090408","1.00557850000001","5.26315789473684","0","","","","","","","","",""
+"3","baseline","51","2026-09-29T02:18:37.8804104Z","51.0225232","1.01348239999999","6.92307692307692","0","","","","","","","","",""
+"3","baseline","52","2026-09-29T02:18:38.8694860Z","52.0115461","0.989022900000002","6.34920634920635","0","","","","","","","","",""
+"3","baseline","53","2026-09-29T02:18:39.8740889Z","53.0162553","1.0047092","6.73076923076923","0","","","","","","","","",""
+"3","baseline","54","2026-09-29T02:18:40.8614703Z","54.0035301","0.987274800000002","7.14285714285714","0","","","","","","","","",""
+"3","baseline","55","2026-09-29T02:18:41.8643691Z","55.0064234","1.0028933","9.375","0","","","","","","","","",""
+"3","baseline","56","2026-09-29T02:18:42.8624113Z","56.0047373","0.998313899999999","10.7421875","0","","","","","","","","",""
+"3","baseline","57","2026-09-29T02:18:43.8724211Z","57.0147115","1.0099742","7.5","0","","","","","","","","",""
+"3","baseline","58","2026-09-29T02:18:44.8694637Z","58.0116176","0.996906099999997","15.2777777777778","0","","","","","","","","",""
+"3","baseline","59","2026-09-29T02:18:45.8687676Z","59.0109753","0.999357700000004","16.015625","0","","","","","","","","",""
+"3","baseline","60","2026-09-29T02:18:46.8714713Z","60.0136108","1.0026355","14.6153846153846","0","","","","","","","","",""
+"3","baseline","61","2026-09-29T02:18:47.8763655Z","61.0184298","1.004819","5.859375","0","","","","","","","","",""
+"3","baseline","62","2026-09-29T02:18:48.8725637Z","62.0146968","0.996266999999996","5.46875","0","","","","","","","","",""
+"3","baseline","63","2026-09-29T02:18:49.8718934Z","63.0140784","0.9993816","10.3515625","0","","","","","","","","",""
+"3","baseline","64","2026-09-29T02:18:50.8697496Z","64.0118818","0.997803400000002","9.72222222222222","0","","","","","","","","",""
+"3","baseline","65","2026-09-29T02:18:51.8688017Z","65.0109219","0.999040100000002","15.8203125","0.195500160604164","","","","","","","","",""
+"3","baseline","66","2026-09-29T02:18:52.8654882Z","66.0076504","0.996728500000003","24.609375","0","","","","","","","","",""
+"3","baseline","67","2026-09-29T02:18:53.8718104Z","67.0138807","1.0062303","43.6538461538462","0","","","","","","","","",""
+"3","baseline","68","2026-09-29T02:18:54.8763167Z","68.0184954","1.00461469999999","15.0390625","0","","","","","","","","",""
+"3","baseline","69","2026-09-29T02:18:55.8596462Z","69.0016809","0.983185500000005","4.96031746031746","0","","","","","","","","",""
+"3","baseline","70","2026-09-29T02:18:56.8620510Z","70.0041441","1.00246319999999","4.8828125","0","","","","","","","","",""
+"3","baseline","71","2026-09-29T02:18:57.8649364Z","71.0069847","1.00284060000001","9.9609375","0","","","","","","","","",""
+"3","baseline","72","2026-09-29T02:18:58.8637783Z","72.0059744","0.998989699999996","7.2265625","0","","","","","","","","",""
+"3","baseline","73","2026-09-29T02:18:59.8619443Z","73.0042195","0.998245099999991","6.25","0","","","","","","","","",""
+"3","baseline","74","2026-09-29T02:19:00.8607503Z","74.0029379","0.998718400000001","7.03125","0","","","","","","","","",""
+"3","baseline","75","2026-09-29T02:19:01.8621488Z","75.0041535","1.00121560000001","8.984375","0","","","","","","","","",""
+"3","baseline","76","2026-09-29T02:19:02.8628879Z","76.0051374","1.00098389999999","8.7890625","0","","","","","","","","",""
+"3","baseline","77","2026-09-29T02:19:03.8614118Z","77.0035895","0.998452099999994","7.2265625","0","","","","","","","","",""
+"3","baseline","78","2026-09-29T02:19:04.8672642Z","78.0094905","1.00590100000001","7.8125","0","","","","","","","","",""
+"3","baseline","79","2026-09-29T02:19:05.8717836Z","79.0137396","1.0042491","10.5769230769231","0","","","","","","","","",""
+"3","baseline","80","2026-09-29T02:19:06.8735849Z","80.0157309","1.0019913","4.8828125","0","","","","","","","","",""
+"3","baseline","81","2026-09-29T02:19:07.8724871Z","81.0145772","0.998846299999997","4.6875","0","","","","","","","","",""
+"3","baseline","82","2026-09-29T02:19:08.8583442Z","82.0003958","0.985818600000002","7.14285714285714","0","","","","","","","","",""
+"3","baseline","83","2026-09-29T02:19:09.8624322Z","83.0045239","1.0041281","13.8671875","0","","","","","","","","",""
+"3","baseline","84","2026-09-29T02:19:10.8622971Z","84.0044787","0.999954799999998","6.0546875","0","","","","","","","","",""
+"3","baseline","85","2026-09-29T02:19:11.8616614Z","85.0038642","0.999385500000002","7.8125","0","","","","","","","","",""
+"3","baseline","86","2026-09-29T02:19:12.8645742Z","86.0066488","1.0027846","8.984375","0","","","","","","","","",""
+"3","baseline","87","2026-09-29T02:19:13.8646911Z","87.0063674","0.999718600000008","10.3515625","0","","","","","","","","",""
+"3","baseline","88","2026-09-29T02:19:14.8681324Z","88.0104051","1.0040377","6.25","0","","","","","","","","",""
+"3","baseline","89","2026-09-29T02:19:15.8701548Z","89.0122467","1.00184159999999","8.7890625","0","","","","","","","","",""
+"3","baseline","90","2026-09-29T02:19:16.8685438Z","90.0107649","0.998518200000007","11.1328125","0.195602343552675","","","","","","","","",""
+"3","baseline","91","2026-09-29T02:19:17.8652679Z","91.0074411","0.996676199999996","8.59375","0","","","","","","","","",""
+"3","baseline","92","2026-09-29T02:19:18.8743219Z","92.0164819","1.00904080000001","10.5769230769231","0","","","","","","","","",""
+"3","baseline","93","2026-09-29T02:19:19.8718899Z","93.0139949","0.997512999999998","18.9453125","0","","","","","","","","",""
+"3","baseline","94","2026-09-29T02:19:20.8711407Z","94.0132905","0.999295599999996","23.2421875","0","","","","","","","","",""
+"3","baseline","95","2026-09-29T02:19:21.8711727Z","95.0132891","0.999998599999998","16.015625","0","","","","","","","","",""
+"3","baseline","96","2026-09-29T02:19:22.8705642Z","96.0127215","0.999432400000003","8.7890625","0","","","","","","","","",""
+"3","baseline","97","2026-09-29T02:19:23.8724767Z","97.0145091","1.0017876","8.02348336594912","0","","","","","","","","",""
+"3","baseline","98","2026-09-29T02:19:24.8609056Z","98.0029672","0.988458100000003","5.34653465346535","0","","","","","","","","",""
+"3","baseline","99","2026-09-29T02:19:25.8634094Z","99.0054534","1.00248619999999","6.25","0","","","","","","","","",""
+"3","baseline","100","2026-09-29T02:19:26.8617707Z","100.0039272","0.998473799999999","6.4453125","0","","","","","","","","",""
+"3","baseline","101","2026-09-29T02:19:27.8662791Z","101.008379","1.0044518","5.859375","0","","","","","","","","",""
+"3","baseline","102","2026-09-29T02:19:28.8655899Z","102.0077192","0.999340200000006","5.078125","0","","","","","","","","",""
+"3","baseline","103","2026-09-29T02:19:29.8785775Z","103.0207575","1.01303830000001","9.03846153846154","0","","","","","","","","",""
+"3","baseline","104","2026-09-29T02:19:30.8631328Z","104.0051347","0.984377199999997","4.96031746031746","0","","","","","","","","",""
+"3","baseline","105","2026-09-29T02:19:31.8663967Z","105.0084751","1.0033404","5.46875","0","","","","","","","","",""
+"3","baseline","106","2026-09-29T02:19:32.8790608Z","106.0211372","1.0126621","9.42307692307692","0","","","","","","","","",""
+"3","baseline","107","2026-09-29T02:19:33.8591554Z","107.0015092","0.980372000000003","4.96031746031746","0","","","","","","","","",""
+"3","baseline","108","2026-09-29T02:19:34.8609082Z","108.0030021","1.00149289999999","6.4453125","0","","","","","","","","",""
+"3","baseline","109","2026-09-29T02:19:35.8634795Z","109.0054622","1.00246010000001","4.6875","0","","","","","","","","",""
+"3","baseline","110","2026-09-29T02:19:36.8637534Z","110.0058387","1.0003765","7.8125","0","","","","","","","","",""
+"3","baseline","111","2026-09-29T02:19:37.8693439Z","111.0109844","1.0051457","8.3984375","0","","","","","","","","",""
+"3","baseline","112","2026-09-29T02:19:38.8674116Z","112.0097211","0.998736699999995","5.6640625","0","","","","","","","","",""
+"3","baseline","113","2026-09-29T02:19:39.8686967Z","113.0108102","1.0010891","5.46875","0","","","","","","","","",""
+"3","baseline","114","2026-09-29T02:19:40.8726016Z","114.0147984","1.00398819999999","7.5","0","","","","","","","","",""
+"3","baseline","115","2026-09-29T02:19:41.8715336Z","115.0136611","0.998862700000004","9.375","0","","","","","","","","",""
+"3","baseline","116","2026-09-29T02:19:42.8696615Z","116.0117289","0.998067800000001","15.8730158730159","0","","","","","","","","",""
+"3","baseline","117","2026-09-29T02:19:43.8747115Z","117.0169909","1.005262","10.7692307692308","0","","","","","","","","",""
+"3","baseline","118","2026-09-29T02:19:44.8625457Z","118.0047226","0.987731699999998","7.14285714285714","0","","","","","","","","",""
+"3","baseline","119","2026-09-29T02:19:45.8609462Z","119.0030456","0.998322999999999","7.421875","0","","","","","","","","",""
+"3","baseline","120","2026-09-29T02:19:46.8615527Z","120.0037945","1.0007489","6.25","0","","","","","","","","",""
+"3","baseline","121","2026-09-29T02:19:47.8671776Z","121.009234","1.00543949999999","5.078125","0","","","","","","","","",""
+"3","baseline","122","2026-09-29T02:19:48.8706069Z","122.0127722","1.00353820000001","9.42307692307692","0","","","","","","","","",""
+"3","baseline","123","2026-09-29T02:19:49.8713100Z","123.0133684","1.00059619999999","9.1796875","0","","","","","","","","",""
+"3","baseline","124","2026-09-29T02:19:50.8691900Z","124.0113035","0.997935100000007","14.0873015873016","0","","","","","","","","",""
+"3","baseline","125","2026-09-29T02:19:51.8689513Z","125.0110287","0.9997252","12.6953125","0","","","","","","","","",""
+"3","baseline","126","2026-09-29T02:19:52.8808072Z","126.0228083","1.0117796","13.4615384615385","0","","","","","","","","",""
+"3","baseline","127","2026-09-29T02:19:53.8646461Z","127.0067316","0.983923300000001","8.13492063492063","0","","","","","","","","",""
+"3","baseline","128","2026-09-29T02:19:54.8681452Z","128.0102362","1.00350459999999","9.5703125","0","","","","","","","","",""
+"3","baseline","129","2026-09-29T02:19:55.8724514Z","129.0151475","1.0049113","9.80769230769231","0","","","","","","","","",""
+"3","baseline","130","2026-09-29T02:19:56.8678450Z","130.010059","0.994911500000001","7.93650793650794","0","","","","","","","","",""
+"3","baseline","131","2026-09-29T02:19:57.8682533Z","131.0104011","1.00034210000001","7.8125","0","","","","","","","","",""
+"3","baseline","132","2026-09-29T02:19:58.8672344Z","132.009374","0.998972900000012","8.59375","0","","","","","","","","",""
+"3","baseline","133","2026-09-29T02:19:59.8682373Z","133.0103801","1.00100609999998","6.0546875","0","","","","","","","","",""
+"3","baseline","134","2026-09-29T02:20:00.8655380Z","134.0076914","0.997311300000007","7.8125","0","","","","","","","","",""
+"3","baseline","135","2026-09-29T02:20:01.8784999Z","135.0206838","1.0129924","7.69230769230769","0","","","","","","","","",""
+"3","baseline","136","2026-09-29T02:20:02.8703136Z","136.0120481","0.991364299999987","10.3174603174603","0","","","","","","","","",""
+"3","baseline","137","2026-09-29T02:20:03.8743651Z","137.0163703","1.00432220000002","9.03846153846154","0.194471953323342","","","","","","","","",""
+"3","baseline","138","2026-09-29T02:20:04.8643948Z","138.0066179","0.990247599999975","39.2857142857143","0","","","","","","","","",""
+"3","baseline","139","2026-09-29T02:20:05.8614490Z","139.0035623","0.996944400000018","77.5390625","0","","","","","","","","",""
+"3","baseline","140","2026-09-29T02:20:06.8719369Z","140.0141212","1.01055890000001","86.9230769230769","0","","","","","","","","",""
+"3","baseline","141","2026-09-29T02:20:07.8689535Z","141.0110299","0.996908699999977","24.8015873015873","0","","","","","","","","",""
+"3","baseline","142","2026-09-29T02:20:08.8684150Z","142.0105469","0.999516999999997","19.7265625","0","","","","","","","","",""
+"3","baseline","143","2026-09-29T02:20:09.8662160Z","143.0082789","0.997732000000013","21.875","0","","","","","","","","",""
+"3","baseline","144","2026-09-29T02:20:10.8761850Z","144.018425","1.01014610000001","21.7307692307692","0","","","","","","","","",""
+"3","baseline","145","2026-09-29T02:20:11.8597565Z","145.0018341","0.983409099999989","21.6269841269841","0","","","","","","","","",""
+"3","baseline","146","2026-09-29T02:20:12.8740036Z","146.0160543","1.01422020000001","27.5","0","","","","","","","","",""
+"3","baseline","147","2026-09-29T02:20:13.8707058Z","147.0128646","0.996810299999993","9.5703125","0","","","","","","","","",""
+"3","baseline","148","2026-09-29T02:20:14.8674612Z","148.0096067","0.996742100000006","13.6904761904762","0","","","","","","","","",""
+"3","baseline","149","2026-09-29T02:20:15.8669354Z","149.0089557","0.999348999999995","5.078125","0","","","","","","","","",""
+"3","baseline","150","2026-09-29T02:20:16.8680634Z","150.0102054","1.00124969999999","9.375","0","","","","","","","","",""
+"3","baseline","151","2026-09-29T02:20:17.8687859Z","151.0109135","1.0007081","7.6171875","0","","","","","","","","",""
+"3","baseline","152","2026-09-29T02:20:18.8659629Z","152.0080481","0.99713460000001","3.515625","0","","","","","","","","",""
+"3","baseline","153","2026-09-29T02:20:19.8664865Z","153.008747","1.0006989","10.3515625","0","","","","","","","","",""
+"3","baseline","154","2026-09-29T02:20:20.8688968Z","154.0111044","1.00235739999999","13.4765625","0","","","","","","","","",""
+"3","baseline","155","2026-09-29T02:20:21.8712968Z","155.0134141","1.00230970000001","7.30769230769231","0","","","","","","","","",""
+"3","baseline","156","2026-09-29T02:20:22.8737911Z","156.0158824","1.00246829999998","7.6171875","0","","","","","","","","",""
+"3","baseline","157","2026-09-29T02:20:23.8707402Z","157.0134149","0.997532500000005","15.0390625","0","","","","","","","","",""
+"3","baseline","158","2026-09-29T02:20:24.8695488Z","158.0117382","0.99832330000001","15.4761904761905","0","","","","","","","","",""
+"3","baseline","159","2026-09-29T02:20:25.8679063Z","159.0100412","0.998302999999993","7.2265625","0","","","","","","","","",""
+"3","baseline","160","2026-09-29T02:20:26.8685860Z","160.0107509","1.00070970000002","7.03125","0","","","","","","","","",""
+"3","baseline","161","2026-09-29T02:20:27.8811219Z","161.0232502","1.0124993","6.53846153846154","0","","","","","","","","",""
+"3","baseline","162","2026-09-29T02:20:28.8687478Z","162.0108834","0.987633199999976","5.55555555555556","0","","","","","","","","",""
+"3","baseline","163","2026-09-29T02:20:29.8673452Z","163.0094401","0.998556700000023","9.375","0","","","","","","","","",""
+"3","baseline","164","2026-09-29T02:20:30.8724582Z","164.0145128","1.0050727","11.1538461538462","0","","","","","","","","",""
+"3","baseline","165","2026-09-29T02:20:31.8679948Z","165.010147","0.995634199999984","28.5714285714286","0","","","","","","","","",""
+"3","baseline","166","2026-09-29T02:20:32.8696618Z","166.0118394","1.0016924","41.6015625","0","","","","","","","","",""
+"3","baseline","167","2026-09-29T02:20:33.8678941Z","167.0100451","0.9982057","14.84375","0","","","","","","","","",""
+"3","baseline","168","2026-09-29T02:20:34.8671996Z","168.0096021","0.99955700000001","7.8125","0","","","","","","","","",""
+"3","baseline","169","2026-09-29T02:20:35.8668593Z","169.0090622","0.999460099999993","7.421875","0","","","","","","","","",""
+"3","baseline","170","2026-09-29T02:20:36.8803823Z","170.0224294","1.0133672","7.88461538461539","0","","","","","","","","",""
+"3","baseline","171","2026-09-29T02:20:37.8665251Z","171.0087292","0.986299800000012","7.14285714285714","0","","","","","","","","",""
+"3","baseline","172","2026-09-29T02:20:38.8654333Z","172.0075437","0.99881449999998","6.4453125","0","","","","","","","","",""
+"3","baseline","173","2026-09-29T02:20:39.8668457Z","173.008918","1.00137430000001","5.078125","0","","","","","","","","",""
+"3","baseline","174","2026-09-29T02:20:40.8776323Z","174.0196893","1.01077129999999","6.53846153846154","0","","","","","","","","",""
+"3","baseline","175","2026-09-29T02:20:41.8617276Z","175.0038002","0.984110900000019","6.94444444444444","0","","","","","","","","",""
+"3","baseline","176","2026-09-29T02:20:42.8663889Z","176.0084542","1.00465399999999","4.6875","0","","","","","","","","",""
+"3","baseline","177","2026-09-29T02:20:43.8780683Z","177.0201504","1.01169620000002","6.53846153846154","0","","","","","","","","",""
+"3","baseline","178","2026-09-29T02:20:44.8638292Z","178.0058593","0.985708899999992","4.76190476190476","0","","","","","","","","",""
+"3","baseline","179","2026-09-29T02:20:45.8621078Z","179.003916","0.998056700000006","6.4453125","0","","","","","","","","",""
+"3","baseline","180","2026-09-29T02:20:46.8621762Z","180.0043032","1.00038719999998","5.46875","0","","","","","","","","",""
+"3","baseline","181","2026-09-29T02:20:47.8637825Z","181.0058158","1.00151260000001","6.8359375","0","","","","","","","","",""
+"3","baseline","182","2026-09-29T02:20:48.8620878Z","182.0041291","0.998313300000007","5.859375","0","","","","","","","","",""
+"3","baseline","183","2026-09-29T02:20:49.8610103Z","183.0026358","0.998506699999979","6.25","0","","","","","","","","",""
+"3","baseline","184","2026-09-29T02:20:50.8631265Z","184.0047089","1.00207310000002","4.1015625","0","","","","","","","","",""
+"3","baseline","185","2026-09-29T02:20:51.8643844Z","185.0071085","1.00239959999999","4.6875","0","","","","","","","","",""
+"3","baseline","186","2026-09-29T02:20:52.8751816Z","186.0173024","1.01019390000002","10.1923076923077","0","","","","","","","","",""
+"3","baseline","187","2026-09-29T02:20:53.8599664Z","187.0022484","0.984945999999979","9.92063492063492","0","","","","","","","","",""
+"3","baseline","188","2026-09-29T02:20:54.8586497Z","188.0007707","0.998522300000019","8.203125","0","","","","","","","","",""
+"3","baseline","189","2026-09-29T02:20:55.8594958Z","189.0015419","1.00077119999997","5.87084148727984","0","","","","","","","","",""
+"3","baseline","190","2026-09-29T02:20:56.8728881Z","190.0150882","1.0135463","6.33397312859885","0","","","","","","","","",""
+"3","baseline","191","2026-09-29T02:20:57.8730373Z","191.0151803","1.00009210000002","6.0546875","0","","","","","","","","",""
+"3","baseline","192","2026-09-29T02:20:58.8730831Z","192.0146608","0.999480500000004","5.078125","0","","","","","","","","",""
+"3","baseline","193","2026-09-29T02:20:59.8602853Z","193.0024831","0.987822299999976","5.35714285714286","0","","","","","","","","",""
+"3","baseline","194","2026-09-29T02:21:00.8674645Z","194.0095087","1.00702560000002","6.4453125","0","","","","","","","","",""
+"3","baseline","195","2026-09-29T02:21:01.8666975Z","195.0088831","0.999374399999994","10.9375","0","","","","","","","","",""
+"3","baseline","196","2026-09-29T02:21:02.8692233Z","196.0113674","1.00248429999999","8.0078125","0","","","","","","","","",""
+"3","baseline","197","2026-09-29T02:21:03.8700027Z","197.012264","1.0008966","8.984375","0","","","","","","","","",""
+"3","baseline","198","2026-09-29T02:21:04.8717752Z","198.0140293","1.00176530000002","7.69230769230769","0.194968322420428","","","","","","","","",""
+"3","baseline","199","2026-09-29T02:21:05.8733522Z","199.0154763","1.00144699999998","11.328125","0","","","","","","","","",""
+"3","baseline","200","2026-09-29T02:21:06.8590304Z","200.0010891","0.985612800000013","6.54761904761905","0","","","","","","","","",""
+"3","baseline","201","2026-09-29T02:21:07.8719616Z","201.0141928","1.01310369999999","9.61538461538461","0","","","","","","","","",""
+"3","baseline","202","2026-09-29T02:21:08.8719329Z","202.0141149","0.999922099999992","6.25","0","","","","","","","","",""
+"3","baseline","203","2026-09-29T02:21:09.8687914Z","203.0108933","0.996778400000011","10.1190476190476","0","","","","","","","","",""
+"3","baseline","204","2026-09-29T02:21:10.8662996Z","204.0086157","0.997722399999986","7.421875","0","","","","","","","","",""
+"3","baseline","205","2026-09-29T02:21:11.8810567Z","205.023172","1.01455630000001","5.76923076923077","0","","","","","","","","",""
+"3","baseline","206","2026-09-29T02:21:12.8676942Z","206.0093705","0.9861985","6.74603174603175","0","","","","","","","","",""
+"3","baseline","207","2026-09-29T02:21:13.8654925Z","207.007707","0.998336499999994","11.1328125","0","","","","","","","","",""
+"3","baseline","208","2026-09-29T02:21:14.8679206Z","208.0100074","1.0023004","6.4453125","0","","","","","","","","",""
+"3","baseline","209","2026-09-29T02:21:15.8655596Z","209.0076362","0.997628800000001","7.04500978473581","0","","","","","","","","",""
+"3","baseline","210","2026-09-29T02:21:16.8798366Z","210.0220245","1.01438830000001","7.86948176583493","0","","","","","","","","",""
+"3","baseline","211","2026-09-29T02:21:17.8616894Z","211.0037276","0.981703100000004","6.54761904761905","0","","","","","","","","",""
+"3","baseline","212","2026-09-29T02:21:18.8624610Z","212.0045064","1.00077880000001","6.25","0","","","","","","","","",""
+"3","baseline","213","2026-09-29T02:21:19.8654540Z","213.0075437","1.00303729999999","6.8359375","0","","","","","","","","",""
+"3","baseline","214","2026-09-29T02:21:20.8678732Z","214.0100048","1.0024611","7.6171875","0","","","","","","","","",""
+"3","baseline","215","2026-09-29T02:21:21.8655854Z","215.0077467","0.997741899999994","8.3984375","0","","","","","","","","",""
+"3","baseline","216","2026-09-29T02:21:22.8676165Z","216.0096859","1.00193920000001","6.25","0","","","","","","","","",""
+"3","baseline","217","2026-09-29T02:21:23.8698747Z","217.0119491","1.00226319999999","11.1328125","0","","","","","","","","",""
+"3","baseline","218","2026-09-29T02:21:24.8723009Z","218.0144353","1.00248620000002","15.3846153846154","0.194828118332198","","","","","","","","",""
+"3","baseline","219","2026-09-29T02:21:25.8580882Z","219.0000857","0.985650399999997","6.34920634920635","0","","","","","","","","",""
+"3","baseline","220","2026-09-29T02:21:26.8591131Z","220.0012321","1.00114639999998","5.078125","0","","","","","","","","",""
+"3","baseline","221","2026-09-29T02:21:27.8620585Z","221.0041301","1.00289800000002","5.859375","0","","","","","","","","",""
+"3","baseline","222","2026-09-29T02:21:28.8613673Z","222.0034692","0.999339099999986","5.6640625","0","","","","","","","","",""
+"3","baseline","223","2026-09-29T02:21:29.8658763Z","223.0079527","1.00448349999999","5.859375","0","","","","","","","","",""
+"3","baseline","224","2026-09-29T02:21:30.8673843Z","224.0095296","1.0015769","4.1015625","0","","","","","","","","",""
+"3","baseline","225","2026-09-29T02:21:31.8716935Z","225.0136877","1.00415810000001","10.7692307692308","0","","","","","","","","",""
+"3","baseline","226","2026-09-29T02:21:32.8732673Z","226.0147823","1.00109459999999","5.46875","0","","","","","","","","",""
+"3","baseline","227","2026-09-29T02:21:33.8588155Z","227.0004215","0.985639200000008","7.34126984126984","0","","","","","","","","",""
+"3","baseline","228","2026-09-29T02:21:34.8733450Z","228.0155141","1.0150926","8.46153846153846","0","","","","","","","","",""
+"3","baseline","229","2026-09-29T02:21:35.8642843Z","229.0063316","0.990817499999991","8.73015873015873","0","","","","","","","","",""
+"3","baseline","230","2026-09-29T02:21:36.8618727Z","230.0039793","0.997647700000016","8.59375","0","","","","","","","","",""
+"3","baseline","231","2026-09-29T02:21:37.8626389Z","231.0047182","1.00073889999999","6.640625","0","","","","","","","","",""
+"3","baseline","232","2026-09-29T02:21:38.8640079Z","232.0062616","1.0015434","4.296875","0","","","","","","","","",""
+"3","baseline","233","2026-09-29T02:21:39.8698701Z","233.0119016","1.00564","6.4453125","0","","","","","","","","",""
+"3","baseline","234","2026-09-29T02:21:40.8767181Z","234.018781","1.0068794","8.84615384615385","0","","","","","","","","",""
+"3","baseline","235","2026-09-29T02:21:41.8603724Z","235.0030752","0.984294199999994","7.53968253968254","0","","","","","","","","",""
+"3","baseline","236","2026-09-29T02:21:42.8667035Z","236.0089538","1.00587860000002","4.6875","0","","","","","","","","",""
+"3","baseline","237","2026-09-29T02:21:43.8684320Z","237.0104903","1.00153649999999","6.0546875","0","","","","","","","","",""
+"3","baseline","238","2026-09-29T02:21:44.8672014Z","238.0088045","0.99831420000001","10.546875","0","","","","","","","","",""
+"3","baseline","239","2026-09-29T02:21:45.8669102Z","239.0089175","1.000113","9.1796875","0","","","","","","","","",""
+"3","baseline","240","2026-09-29T02:21:46.8688539Z","240.0110414","1.00212389999999","7.421875","0","","","","","","","","",""
+"3","baseline","241","2026-09-29T02:21:47.8680428Z","241.0096989","0.998657500000007","8.984375","0","","","","","","","","",""
+"3","baseline","242","2026-09-29T02:21:48.8674802Z","242.0097691","1.00007020000001","6.4453125","0","","","","","","","","",""
+"3","baseline","243","2026-09-29T02:21:49.8695585Z","243.0116422","1.00187309999998","13.28125","0","","","","","","","","",""
+"3","baseline","244","2026-09-29T02:21:50.8704015Z","244.0125581","1.0009159","9.03846153846154","0","","","","","","","","",""
+"3","baseline","245","2026-09-29T02:21:51.8789211Z","245.0209806","1.00842250000002","11.328125","0","","","","","","","","",""
+"3","baseline","246","2026-09-29T02:21:52.8641417Z","246.0062653","0.985284699999994","6.15079365079365","0","","","","","","","","",""
+"3","baseline","247","2026-09-29T02:21:53.8617016Z","247.0037796","0.997514300000006","7.8125","0","","","","","","","","",""
+"3","baseline","248","2026-09-29T02:21:54.8632008Z","248.005235","1.0014554","8.02348336594912","0","","","","","","","","",""
+"3","baseline","249","2026-09-29T02:21:55.8606329Z","249.0028402","0.997605199999981","11.5009746588694","0","","","","","","","","",""
+"3","baseline","250","2026-09-29T02:21:56.8598841Z","250.0021315","0.99929130000001","7.03125","0","","","","","","","","",""
+"3","baseline","251","2026-09-29T02:21:57.8624237Z","251.0044449","1.00231339999999","6.0546875","0","","","","","","","","",""
+"3","baseline","252","2026-09-29T02:21:58.8638953Z","252.0060875","1.0016426","5.2734375","0","","","","","","","","",""
+"3","baseline","253","2026-09-29T02:21:59.8616286Z","253.0038253","0.99773780000001","5.6640625","0","","","","","","","","",""
+"3","baseline","254","2026-09-29T02:22:00.8580877Z","254.0002276","0.9964023","5.859375","0","","","","","","","","",""
+"3","baseline","255","2026-09-29T02:22:01.8643875Z","255.0064665","1.0062389","5.6640625","0","","","","","","","","",""
+"3","baseline","256","2026-09-29T02:22:02.8721408Z","256.0145179","1.0080514","7.69230769230769","0","","","","","","","","",""
+"3","baseline","257","2026-09-29T02:22:03.8713532Z","257.0134296","0.998911700000008","7.421875","0","","","","","","","","",""
+"3","baseline","258","2026-09-29T02:22:04.8902483Z","258.0257021","1.01227249999999","15.4142581888247","0","","","","","","","","",""
+"3","baseline","259","2026-09-29T02:22:05.8710715Z","259.0132641","0.987562000000025","22.5742574257426","0","","","","","","","","",""
+"3","baseline","260","2026-09-29T02:22:06.8710805Z","260.0132122","0.999948099999983","9.765625","0","","","","","","","","",""
+"3","baseline","261","2026-09-29T02:22:07.8758445Z","261.0179912","1.00477899999998","9.5703125","0","","","","","","","","",""
+"3","baseline","262","2026-09-29T02:22:08.8607053Z","262.0028623","0.984871100000021","5.35714285714286","0","","","","","","","","",""
+"3","baseline","263","2026-09-29T02:22:09.8639952Z","263.0059879","1.00312559999998","9.1796875","0","","","","","","","","",""
+"3","baseline","264","2026-09-29T02:22:10.8740854Z","264.0162051","1.0102172","7.88461538461539","0","","","","","","","","",""
+"3","baseline","265","2026-09-29T02:22:11.8634856Z","265.0055843","0.98937920000003","5.95238095238095","0","","","","","","","","",""
+"3","baseline","266","2026-09-29T02:22:12.8604092Z","266.0024512","0.996866899999986","7.421875","0","","","","","","","","",""
+"3","baseline","267","2026-09-29T02:22:13.8635173Z","267.0056104","1.00315919999997","8.0078125","0","","","","","","","","",""
+"3","baseline","268","2026-09-29T02:22:14.8657046Z","268.0079817","1.00237130000005","8.3984375","0","","","","","","","","",""
+"3","baseline","269","2026-09-29T02:22:15.8804053Z","269.0224731","1.0144914","8.84615384615385","0","","","","","","","","",""
+"3","baseline","270","2026-09-29T02:22:16.8629140Z","270.0050867","0.982613599999979","6.74603174603175","0","","","","","","","","",""
+"3","baseline","271","2026-09-29T02:22:17.8671791Z","271.0095048","1.00441810000001","7.8125","0","","","","","","","","",""
+"3","baseline","272","2026-09-29T02:22:18.8676372Z","272.0098286","1.00032379999999","5.6640625","0","","","","","","","","",""
+"3","baseline","273","2026-09-29T02:22:19.8685271Z","273.0105616","1.00073299999997","3.7109375","0","","","","","","","","",""
+"3","baseline","274","2026-09-29T02:22:20.8685953Z","274.0114112","1.00084960000004","7.2265625","0","","","","","","","","",""
+"3","baseline","275","2026-09-29T02:22:21.8735095Z","275.0153174","1.00390620000002","8.65384615384615","0","","","","","","","","",""
+"3","baseline","276","2026-09-29T02:22:22.8596585Z","276.002009","0.986691599999972","6.15079365079365","0","","","","","","","","",""
+"3","baseline","277","2026-09-29T02:22:23.8643192Z","277.0065326","1.00452360000003","4.4921875","0","","","","","","","","",""
+"3","baseline","278","2026-09-29T02:22:24.8643337Z","278.0063829","0.999850299999991","8.7890625","0","","","","","","","","",""
+"3","baseline","279","2026-09-29T02:22:25.8634434Z","279.0056779","0.999294999999961","6.0546875","0","","","","","","","","",""
+"3","baseline","280","2026-09-29T02:22:26.8637403Z","280.0058894","1.00021150000003","5.2734375","0","","","","","","","","",""
+"3","baseline","281","2026-09-29T02:22:27.8618803Z","281.0040367","0.998147299999971","7.03125","0","","","","","","","","",""
+"3","baseline","282","2026-09-29T02:22:28.8621498Z","282.0043271","1.00029040000004","7.421875","0","","","","","","","","",""
+"3","baseline","283","2026-09-29T02:22:29.8621474Z","283.0041956","0.999868499999991","6.8359375","0","","","","","","","","",""
+"3","baseline","284","2026-09-29T02:22:30.8599659Z","284.0021618","0.997966200000008","5.46875","0","","","","","","","","",""
+"3","baseline","285","2026-09-29T02:22:31.8607152Z","285.0027369","1.00057509999999","5.46875","0","","","","","","","","",""
+"3","baseline","286","2026-09-29T02:22:32.8603592Z","286.0026923","0.999955399999976","7.8125","0","","","","","","","","",""
+"3","baseline","287","2026-09-29T02:22:33.8621766Z","287.0042802","1.0015879","7.03125","0","","","","","","","","",""
+"3","baseline","288","2026-09-29T02:22:34.8611180Z","288.0032215","0.998941300000013","9.375","0","","","","","","","","",""
+"3","baseline","289","2026-09-29T02:22:35.8625951Z","289.0046462","1.00142469999997","6.0546875","0","","","","","","","","",""
+"3","baseline","290","2026-09-29T02:22:36.8603318Z","290.0025108","0.997864600000014","9.9609375","0","","","","","","","","",""
+"3","baseline","291","2026-09-29T02:22:37.8602713Z","291.0023403","0.999829500000033","6.0546875","0","","","","","","","","",""
+"3","baseline","292","2026-09-29T02:22:38.8615391Z","292.0036547","1.00131439999996","5.46875","0","","","","","","","","",""
+"3","baseline","293","2026-09-29T02:22:39.8672034Z","293.0093825","1.00572779999999","4.6875","0","","","","","","","","",""
+"3","baseline","294","2026-09-29T02:22:40.8653929Z","294.0075278","0.998145300000033","10.7421875","0","","","","","","","","",""
+"3","baseline","295","2026-09-29T02:22:41.8672696Z","295.0093114","1.00178360000001","7.03125","0","","","","","","","","",""
+"3","baseline","296","2026-09-29T02:22:42.8757546Z","296.0180145","1.00870309999999","5.76923076923077","0","","","","","","","","",""
+"3","baseline","297","2026-09-29T02:22:43.8626049Z","297.004676","0.986661499999968","6.54761904761905","0","","","","","","","","",""
+"3","baseline","298","2026-09-29T02:22:44.8578628Z","298.0000127","0.995336700000053","9.1796875","0","","","","","","","","",""
+"3","baseline","299","2026-09-29T02:22:45.8728185Z","299.0152267","1.01521399999996","6.73076923076923","0","","","","","","","","",""
+"3","baseline","300","2026-09-29T02:22:46.8621542Z","300.0044275","0.989200799999992","5.35714285714286","0","","","","","","","","",""
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block-end.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block-end.json
new file mode 100644
index 0000000..0b844dd
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block-end.json
@@ -0,0 +1,12 @@
+{
+ "state": "block",
+ "layers": {
+ "shutdown": true,
+ "local_shutdown": true,
+ "update": false,
+ "remote": true,
+ "sleep": true
+ },
+ "uptime_seconds": 333,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block-start.json b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block-start.json
new file mode 100644
index 0000000..6e48522
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block-start.json
@@ -0,0 +1,12 @@
+{
+ "state": "block",
+ "layers": {
+ "shutdown": true,
+ "local_shutdown": true,
+ "update": false,
+ "remote": true,
+ "sleep": true
+ },
+ "uptime_seconds": 32,
+ "blocked_count": 0
+}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block.csv b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block.csv
new file mode 100644
index 0000000..c650438
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/run-3-block.csv
@@ -0,0 +1,301 @@
+"run","scenario","sample","utc","elapsed_s","interval_s","system_cpu_pct","collector_cpu_pct","pid","process_cpu_s","cpu_pct","private_mib","working_set_mib","threads","handles","io_read_bytes_s","io_write_bytes_s"
+"3","block","1","2026-09-29T02:12:17.7852724Z","1.0039688","1.0039651","10.3515625","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","2","2026-09-29T02:12:18.7881578Z","2.0067596","1.0027908","6.0546875","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","3","2026-09-29T02:12:19.8004849Z","3.0191655","1.0124059","6.15384615384615","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","4","2026-09-29T02:12:20.7875314Z","4.0063625","0.987197","4.36507936507936","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","5","2026-09-29T02:12:21.8019011Z","5.0205974","1.0142349","7.11538461538461","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","6","2026-09-29T02:12:22.7892409Z","6.0079452","0.9873478","6.34920634920635","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","7","2026-09-29T02:12:23.7910993Z","7.009769","1.0018238","8.203125","0.19495693753732","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","8","2026-09-29T02:12:24.7907605Z","8.0095073","0.9997383","6.0546875","0.195363626661097","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","9","2026-09-29T02:12:25.7967977Z","9.0150351","1.0055278","6.15384615384615","0.194238786834138","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","10","2026-09-29T02:12:26.7964227Z","10.0145088","0.999473699999999","7.2265625","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","11","2026-09-29T02:12:27.7999348Z","11.0186482","1.0041394","10.3515625","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","12","2026-09-29T02:12:28.7836420Z","12.0024171","0.983768899999999","5.35714285714286","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","13","2026-09-29T02:12:29.7998174Z","13.0184281","1.016011","4.03846153846154","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","14","2026-09-29T02:12:30.7821479Z","14.0004308","0.982002700000001","5.35714285714286","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","15","2026-09-29T02:12:31.7943456Z","15.0129232","1.0124924","12.5","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","16","2026-09-29T02:12:32.7886841Z","16.0072115","0.994288300000001","39.2857142857143","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","17","2026-09-29T02:12:33.7984656Z","17.0172974","1.0100859","22.8846153846154","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","18","2026-09-29T02:12:34.8005160Z","18.019338","1.0020406","13.671875","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","19","2026-09-29T02:12:35.8000599Z","19.0187003","0.999362300000001","9.765625","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","20","2026-09-29T02:12:36.7833436Z","20.0019725","0.983272200000002","5.95238095238095","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","21","2026-09-29T02:12:37.7974256Z","21.0160867","1.0141142","8.26923076923077","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","22","2026-09-29T02:12:38.7823570Z","22.0010012","0.984914499999999","4.76190476190476","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","23","2026-09-29T02:12:39.7821996Z","23.0009087","0.999907500000003","7.6171875","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","24","2026-09-29T02:12:40.7967788Z","24.01555","1.0146413","5.96153846153846","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","25","2026-09-29T02:12:41.7932103Z","25.0118896","0.996339600000002","8.203125","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","26","2026-09-29T02:12:42.7916722Z","26.0102281","0.998338499999999","8.33333333333333","0","24176","0","0","3.2890625","14.0859375","11","194","0","0"
+"3","block","27","2026-09-29T02:12:43.7979560Z","27.0166004","1.0063723","14.6153846153846","0.194075790838043","24176","0.015625","0.194075790838043","3.26171875","14.07421875","10","194","0","0"
+"3","block","28","2026-09-29T02:12:44.7968472Z","28.0155434","0.998943000000001","5.859375","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","29","2026-09-29T02:12:45.7955831Z","29.0144031","0.998859700000001","6.25","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","30","2026-09-29T02:12:46.7907358Z","30.0093874","0.994984299999999","9.12698412698413","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","31","2026-09-29T02:12:47.7945731Z","31.0133327","1.0039453","14.8076923076923","0.194544961762359","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","32","2026-09-29T02:12:48.7827086Z","32.0014901","0.988157399999999","5.75396825396825","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","33","2026-09-29T02:12:49.7830634Z","33.0016454","1.0001553","9.19765166340509","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","34","2026-09-29T02:12:50.7860168Z","34.0047785","1.0031331","6.23781676413255","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","35","2026-09-29T02:12:51.8021073Z","35.0209564","1.0161779","5.96153846153846","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","36","2026-09-29T02:12:52.7886065Z","36.0072458","0.986289400000004","4.76190476190476","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","37","2026-09-29T02:12:53.7919936Z","37.0107639","1.0035181","10.8527131782946","0.194627780007157","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","38","2026-09-29T02:12:54.7994564Z","38.0180532","1.0072893","7.94573643410853","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","39","2026-09-29T02:12:55.8012158Z","39.0199128","1.0018596","7.6171875","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","40","2026-09-29T02:12:56.7920565Z","40.0107399","0.990827099999997","8.0078125","0.197120668177123","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","41","2026-09-29T02:12:57.7967936Z","41.0150124","1.0042725","9.765625","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","42","2026-09-29T02:12:58.7838099Z","42.0025755","0.987563100000003","5.95238095238095","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","43","2026-09-29T02:12:59.7831013Z","43.001708","0.999132500000002","6.640625","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","44","2026-09-29T02:13:00.7855723Z","44.004181","1.00247299999999","6.25","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","45","2026-09-29T02:13:01.7983689Z","45.017035","1.012854","11.5384615384615","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","46","2026-09-29T02:13:02.7815286Z","46.0002265","0.983191499999997","4.56349206349206","0","24176","0","0","3.26171875","14.07421875","10","194","0","0"
+"3","block","47","2026-09-29T02:13:03.7952681Z","47.0140665","1.01384","9.42307692307692","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","48","2026-09-29T02:13:04.7947503Z","48.0133814","0.999314900000002","4.8828125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","49","2026-09-29T02:13:05.7940165Z","49.0126012","0.999219799999999","7.421875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","50","2026-09-29T02:13:06.7909685Z","50.0096251","0.997023900000002","13.0952380952381","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","51","2026-09-29T02:13:07.8009450Z","51.0195744","1.0099493","26.5384615384615","0.193388420587054","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","52","2026-09-29T02:13:08.7977484Z","52.0163703","0.996795900000002","7.8125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","53","2026-09-29T02:13:09.7844189Z","53.0031189","0.986748599999999","5.55555555555556","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","54","2026-09-29T02:13:10.7914955Z","54.0101631","1.0070442","9.9609375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","55","2026-09-29T02:13:11.7878746Z","55.0066981","0.996534999999994","7.8125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","56","2026-09-29T02:13:12.7883706Z","56.0071745","1.0004764","6.0546875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","57","2026-09-29T02:13:13.7890121Z","57.0076895","1.000515","6.640625","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","58","2026-09-29T02:13:14.7986395Z","58.0172797","1.0095902","4.80769230769231","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","59","2026-09-29T02:13:15.7839767Z","59.0026277","0.985348000000002","8.92857142857143","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","60","2026-09-29T02:13:16.7829655Z","60.0016495","0.999021800000001","3.90625","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","61","2026-09-29T02:13:17.7880398Z","61.0068992","1.0052497","5.078125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","62","2026-09-29T02:13:18.7909688Z","62.0096371","1.0027379","10.546875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","63","2026-09-29T02:13:19.7896544Z","63.0083323","0.9986952","9.765625","0.195567676704564","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","64","2026-09-29T02:13:20.8011193Z","64.0196726","1.01134029999999","6.73076923076923","0.193122433665504","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","65","2026-09-29T02:13:21.8007784Z","65.0193905","0.999717900000007","4.6875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","66","2026-09-29T02:13:22.8013559Z","66.0200024","1.0006119","4.8828125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","67","2026-09-29T02:13:23.8022242Z","67.0206511","1.0006487","6.8359375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","68","2026-09-29T02:13:24.8013958Z","68.0199474","0.999296299999997","7.03125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","69","2026-09-29T02:13:25.7996424Z","69.0182542","0.998306800000009","7.03125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","70","2026-09-29T02:13:26.7989024Z","70.0174781","0.99922389999999","7.421875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","71","2026-09-29T02:13:27.7838693Z","71.0025767","0.985098600000001","7.53968253968254","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","72","2026-09-29T02:13:28.7949724Z","72.0136069","1.01103020000001","7.5","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","73","2026-09-29T02:13:29.7855419Z","73.0043464","0.990739500000004","5.15873015873016","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","74","2026-09-29T02:13:30.7979429Z","74.0165506","1.0122042","5.19230769230769","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","75","2026-09-29T02:13:31.7967346Z","75.0148863","0.998335699999998","6.4453125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","76","2026-09-29T02:13:32.7925928Z","76.0112793","0.996392999999998","6.8359375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","77","2026-09-29T02:13:33.7902013Z","77.0089125","0.997633199999996","12.5","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","78","2026-09-29T02:13:34.8009825Z","78.0196813","1.01076880000001","6.34615384615385","0.193231627252442","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","79","2026-09-29T02:13:35.8030771Z","79.0216325","1.00195119999999","9.1796875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","80","2026-09-29T02:13:36.7917535Z","80.0110469","0.989414400000001","9.1796875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","81","2026-09-29T02:13:37.7914525Z","81.0100833","0.999036399999994","13.2936507936508","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","82","2026-09-29T02:13:38.7918938Z","82.0106265","1.00054320000001","13.8671875","0.195206463848835","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","83","2026-09-29T02:13:39.7961807Z","83.0149393","1.00431279999999","8.07692307692308","0.194473773509609","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","84","2026-09-29T02:13:40.7974278Z","84.0160652","1.00112590000001","5.859375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","85","2026-09-29T02:13:41.7820608Z","85.0008491","0.984783899999996","4.37375745526839","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","86","2026-09-29T02:13:42.7849494Z","86.0036184","1.0027693","6.23781676413255","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","87","2026-09-29T02:13:43.7957179Z","87.0145325","1.01091410000001","6.34615384615385","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","88","2026-09-29T02:13:44.7937994Z","88.0126495","0.998116999999993","9.1796875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","89","2026-09-29T02:13:45.7923684Z","89.0111573","0.998507799999999","14.0625","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","90","2026-09-29T02:13:46.7927967Z","90.0115496","1.0003923","9.1796875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","91","2026-09-29T02:13:47.7900816Z","91.0086839","0.997134299999999","8.53174603174603","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","92","2026-09-29T02:13:48.7902092Z","92.0090321","1.0003482","11.9140625","0.195244515859577","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","93","2026-09-29T02:13:49.7894276Z","93.0081405","0.999108399999997","10.546875","0.195486796027339","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","94","2026-09-29T02:13:50.7882134Z","94.0068187","0.998678200000001","11.328125","0.195571005755407","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","95","2026-09-29T02:13:51.7874040Z","95.0062095","0.9993908","5.2734375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","96","2026-09-29T02:13:52.7883712Z","96.0071303","1.0009208","6.4453125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","97","2026-09-29T02:13:53.7872831Z","97.0059433","0.998812999999998","6.25","0.195544611453796","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","98","2026-09-29T02:13:54.8027902Z","98.0215179","1.01557459999999","5.76923076923077","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","99","2026-09-29T02:13:55.8015507Z","99.0201193","0.998601399999998","7.03125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","100","2026-09-29T02:13:56.7987379Z","100.0168571","0.996737800000005","6.4453125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","101","2026-09-29T02:13:57.7819705Z","101.0006234","0.983766299999999","7.14285714285714","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","102","2026-09-29T02:13:58.7876702Z","102.006551","1.00592760000001","10.3515625","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","103","2026-09-29T02:13:59.7875769Z","103.0061685","0.999617499999999","5.859375","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","104","2026-09-29T02:14:00.7875925Z","104.0063083","1.0001398","5.6640625","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","105","2026-09-29T02:14:01.7984879Z","105.0171643","1.01085599999999","4.03846153846154","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","106","2026-09-29T02:14:02.7814077Z","106.0001153","0.982951","6.15079365079365","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","107","2026-09-29T02:14:03.7824366Z","107.0010227","1.0009074","7.6171875","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","108","2026-09-29T02:14:04.7863311Z","108.0051919","1.00416920000001","5.46875","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","109","2026-09-29T02:14:05.7871443Z","109.0057338","1.0005419","6.4453125","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","110","2026-09-29T02:14:06.8018626Z","110.0205729","1.01483909999999","7.11538461538461","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","111","2026-09-29T02:14:07.7969200Z","111.0154728","0.994899900000007","9.375","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","112","2026-09-29T02:14:08.7851207Z","112.0037935","0.988320700000003","8.92857142857143","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","113","2026-09-29T02:14:09.8023528Z","113.0209554","1.01716189999999","6.15384615384615","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","114","2026-09-29T02:14:10.8009376Z","114.019543","0.998587600000008","8.203125","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","115","2026-09-29T02:14:11.7948619Z","115.0135017","0.993958699999993","7.421875","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","116","2026-09-29T02:14:12.7833485Z","116.0021901","0.988688400000001","4.76190476190476","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","117","2026-09-29T02:14:13.7900608Z","117.0088371","1.006647","8.7890625","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","118","2026-09-29T02:14:14.7959090Z","118.0147078","1.0058707","8.07692307692308","0.19417257108692","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","119","2026-09-29T02:14:15.7944133Z","119.01256","0.997852199999997","6.25","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","120","2026-09-29T02:14:16.7933980Z","120.0121488","0.999588799999998","9.5703125","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","121","2026-09-29T02:14:17.7888819Z","121.0076165","0.995467700000006","21.6269841269841","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","122","2026-09-29T02:14:18.8016882Z","122.0208557","1.0132392","26.5384615384615","0.192760505120607","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","123","2026-09-29T02:14:19.7962813Z","123.0151037","0.994247999999999","26.953125","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","124","2026-09-29T02:14:20.7950962Z","124.013633","0.998529300000001","15.625","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","125","2026-09-29T02:14:21.7949882Z","125.0136441","1.00001109999999","6.4453125","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","126","2026-09-29T02:14:22.7940735Z","126.0127107","0.999066600000006","11.5234375","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","127","2026-09-29T02:14:23.7950307Z","127.013614","1.00090329999999","6.640625","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","128","2026-09-29T02:14:24.7885767Z","128.0072488","0.993634799999995","33.1349206349206","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","129","2026-09-29T02:14:25.7992297Z","129.017923","1.01067420000001","21.1538461538462","0.193249713903845","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","130","2026-09-29T02:14:26.7947481Z","130.0133306","0.995407599999993","15.234375","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","131","2026-09-29T02:14:27.7926243Z","131.0113782","0.998047600000007","12.5","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","132","2026-09-29T02:14:28.7949297Z","132.0135008","1.00212260000001","8.203125","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","133","2026-09-29T02:14:29.7929164Z","133.0114657","0.997964899999999","13.28125","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","134","2026-09-29T02:14:30.7951213Z","134.0133741","1.00190839999999","9.9609375","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","135","2026-09-29T02:14:31.7907161Z","135.0094878","0.996113699999995","8.34990059642147","0","24176","0.015625","0.196074504346242","3.26171875","14.078125","10","192","0","0"
+"3","block","136","2026-09-29T02:14:32.7876939Z","136.0063784","0.9968906","5.45808966861598","0.195921698930655","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","137","2026-09-29T02:14:33.7878330Z","137.0065832","1.00020480000001","9.1796875","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","138","2026-09-29T02:14:34.7896726Z","138.0082971","1.0017139","4.8828125","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","139","2026-09-29T02:14:35.7939881Z","139.0126429","1.00434580000001","9.42307692307692","0.194467383644157","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","140","2026-09-29T02:14:36.7944951Z","140.0130913","1.00044839999998","6.0546875","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","141","2026-09-29T02:14:37.7918663Z","141.0106432","0.997551900000019","11.5079365079365","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","142","2026-09-29T02:14:38.7935677Z","142.0122618","1.0016186","10.5769230769231","0.194996878053183","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","143","2026-09-29T02:14:39.7927036Z","143.011429","0.999167199999988","9.5703125","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","144","2026-09-29T02:14:40.7911957Z","144.00988","0.998450999999989","9.12698412698413","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","145","2026-09-29T02:14:41.7925847Z","145.0113929","1.00151290000002","16.1538461538462","0.195017458087655","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","146","2026-09-29T02:14:42.7933440Z","146.0120288","1.00063589999999","11.71875","0","24176","0","0","3.26171875","14.078125","10","192","0","0"
+"3","block","147","2026-09-29T02:14:43.7975161Z","147.0160956","1.0040668","5.859375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","148","2026-09-29T02:14:44.7851804Z","148.0037085","0.987612899999988","5.56660039761431","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","149","2026-09-29T02:14:45.8008948Z","149.0194866","1.01577810000001","7.2936660268714","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","150","2026-09-29T02:14:46.7896455Z","150.0082044","0.988717799999989","4.96031746031746","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","151","2026-09-29T02:14:47.7919206Z","151.0107349","1.00253050000001","7.6171875","0.194819509231888","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","152","2026-09-29T02:14:48.7942378Z","152.012881","1.0021461","15.1923076923077","0.19489423747695","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","153","2026-09-29T02:14:49.7844854Z","153.0031538","0.990272800000014","11.1111111111111","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","154","2026-09-29T02:14:50.7844129Z","154.0029556","0.9998018","11.1328125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","155","2026-09-29T02:14:51.8004225Z","155.0190593","1.01610369999997","6.34615384615385","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","156","2026-09-29T02:14:52.7878031Z","156.0064512","0.987391900000006","8.53174603174603","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","157","2026-09-29T02:14:53.7883217Z","157.007049","1.00059780000001","6.640625","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","158","2026-09-29T02:14:54.7947627Z","158.0136623","1.0066133","11.9230769230769","0.194029325859295","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","159","2026-09-29T02:14:55.7845241Z","159.0031022","0.989439900000008","7.93650793650794","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","160","2026-09-29T02:14:56.7841958Z","160.0029048","0.999802599999981","5.2734375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","161","2026-09-29T02:14:57.7918363Z","161.0104315","1.0075267","9.1796875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","162","2026-09-29T02:14:58.7956010Z","162.0142831","1.00385160000002","11.1538461538462","0.194563120684368","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","163","2026-09-29T02:14:59.7811208Z","162.9998351","0.985551999999984","8.92857142857143","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","164","2026-09-29T02:15:00.7956664Z","164.0144057","1.01457060000001","5.19230769230769","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","165","2026-09-29T02:15:01.7923565Z","165.0110933","0.996687600000001","13.28125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","166","2026-09-29T02:15:02.7990654Z","166.0176577","1.0065644","7.2265625","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","167","2026-09-29T02:15:03.7854848Z","167.0043261","0.986668399999985","5.15873015873016","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","168","2026-09-29T02:15:04.7993335Z","168.0180254","1.01369930000001","5.19230769230769","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","169","2026-09-29T02:15:05.7809082Z","168.9995351","0.981509700000004","6.94444444444444","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","170","2026-09-29T02:15:06.7939765Z","170.0125046","1.0129695","7.30769230769231","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","171","2026-09-29T02:15:07.7917189Z","171.0104238","0.997919199999984","21.2301587301587","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","172","2026-09-29T02:15:08.7900586Z","172.008837","0.998413200000016","11.71875","0.195622914440631","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","173","2026-09-29T02:15:09.7941986Z","173.0123483","1.00351129999999","17.1153846153846","0.194629098845228","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","174","2026-09-29T02:15:10.7918575Z","174.0104679","0.998119599999995","11.1111111111111","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","175","2026-09-29T02:15:11.7934279Z","175.0116299","1.00116200000002","11.9230769230769","0.195085810288441","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","176","2026-09-29T02:15:12.7916171Z","176.0101387","0.998508799999996","12.6984126984127","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","177","2026-09-29T02:15:13.7902380Z","177.0088368","0.998698099999984","8.3984375","0.195567108818974","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","178","2026-09-29T02:15:14.7901487Z","178.0087431","0.999906300000021","11.328125","0.19533080249619","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","179","2026-09-29T02:15:15.7892656Z","179.00796","0.999216899999993","7.03125","0.195465569087153","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","180","2026-09-29T02:15:16.8009690Z","180.0196197","1.0116597","5.38461538461539","0.193061461279915","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","181","2026-09-29T02:15:17.7997470Z","181.0183164","0.998696700000011","5.859375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","182","2026-09-29T02:15:18.7987019Z","182.0174861","0.999169699999982","6.4453125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","183","2026-09-29T02:15:19.7834123Z","183.0016157","0.984129600000017","11.3095238095238","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","184","2026-09-29T02:15:20.7846964Z","184.0033206","1.00170489999999","6.0546875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","185","2026-09-29T02:15:21.7876182Z","185.0064025","1.00308189999998","11.71875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","186","2026-09-29T02:15:22.8027070Z","186.0213984","1.0149959","5","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","187","2026-09-29T02:15:23.7899193Z","187.0084442","0.987045800000004","6.74603174603175","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","188","2026-09-29T02:15:24.7901477Z","188.008762","1.0003178","4.1015625","0.195250449407177","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","189","2026-09-29T02:15:25.7961097Z","189.0149977","1.00623569999999","13.2692307692308","0.194102137302425","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","190","2026-09-29T02:15:26.7814473Z","189.9999898","0.984992099999999","7.34126984126984","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","191","2026-09-29T02:15:27.7861101Z","191.0048144","1.00482460000001","5.2734375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","192","2026-09-29T02:15:28.7897345Z","192.0084472","1.00363279999999","5.46875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","193","2026-09-29T02:15:29.7895477Z","193.0082369","0.999789700000008","10.15625","0.195353582858474","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","194","2026-09-29T02:15:30.8006585Z","194.0192813","1.0110444","6.34615384615385","0.193178954356504","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","195","2026-09-29T02:15:31.7974213Z","195.0157702","0.996488900000003","4.296875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","196","2026-09-29T02:15:32.7953263Z","196.0140968","0.998326600000013","6.25","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","197","2026-09-29T02:15:33.7823122Z","197.0010594","0.986962599999998","6.94444444444444","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","198","2026-09-29T02:15:34.7931339Z","198.0117812","1.0107218","10.1923076923077","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","199","2026-09-29T02:15:35.7916933Z","199.0103806","0.998599399999989","8.73015873015873","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","200","2026-09-29T02:15:36.7875669Z","200.0062935","0.995912900000008","9.1796875","0.196114037683414","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","201","2026-09-29T02:15:37.7873262Z","201.0060159","0.999722399999996","7.2265625","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","202","2026-09-29T02:15:38.7885679Z","202.0071758","1.0011599","6.4453125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","203","2026-09-29T02:15:39.8021074Z","203.0203305","1.0131547","8.46153846153846","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","204","2026-09-29T02:15:40.7993046Z","204.0175187","0.997188199999982","6.25","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","205","2026-09-29T02:15:41.7817075Z","205.00037","0.982851300000021","7.93650793650794","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","206","2026-09-29T02:15:42.7836628Z","206.00237","1.00199999999998","5.078125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","207","2026-09-29T02:15:43.7843143Z","207.0030186","1.00064860000001","5.2734375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","208","2026-09-29T02:15:44.8002284Z","208.0188481","1.0158295","5.19230769230769","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","209","2026-09-29T02:15:45.7840843Z","209.0027849","0.983936800000009","7.73809523809524","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","210","2026-09-29T02:15:46.7831114Z","210.0017003","0.998915399999987","5.6640625","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","211","2026-09-29T02:15:47.7842308Z","211.0029609","1.00126059999999","6.0546875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","212","2026-09-29T02:15:48.7998297Z","212.0185896","1.01562870000001","5.38461538461539","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","213","2026-09-29T02:15:49.7983347Z","213.0169436","0.998354000000006","11.328125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","214","2026-09-29T02:15:50.7990244Z","214.0177321","1.0007885","12.3046875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","215","2026-09-29T02:15:51.7928670Z","215.011465","0.993732899999998","8.59375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","216","2026-09-29T02:15:52.7999353Z","216.0186937","1.00722870000001","7.03125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","217","2026-09-29T02:15:53.8015687Z","217.0204296","1.0017359","9.5703125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","218","2026-09-29T02:15:54.7983385Z","218.0170084","0.99657879999998","8.984375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","219","2026-09-29T02:15:55.7832149Z","219.0017782","0.984769800000009","4.56349206349206","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","220","2026-09-29T02:15:56.7855190Z","220.0041671","1.0023889","5.6640625","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","221","2026-09-29T02:15:57.7891278Z","221.0074325","1.0032654","7.421875","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","222","2026-09-29T02:15:58.8004890Z","222.0191864","1.0117539","5.38461538461539","0.19304348616793","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","223","2026-09-29T02:15:59.7881341Z","223.0068701","0.987683699999991","6.54761904761905","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","224","2026-09-29T02:16:00.7897011Z","224.008332","1.00146190000001","9.9609375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","225","2026-09-29T02:16:01.7900487Z","225.0087644","1.00043239999999","13.4765625","0.195228083376749","24176","0.015625","0.195228083376749","3.26171875","14.078125","10","194","0","0"
+"3","block","226","2026-09-29T02:16:02.7880917Z","226.0067595","0.997995099999997","6.25","0.19570486869124","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","227","2026-09-29T02:16:03.7903618Z","227.0090946","1.00233510000001","5.2734375","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","228","2026-09-29T02:16:04.7977340Z","228.0158813","1.00678669999999","8.46153846153846","0.193995907971372","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","229","2026-09-29T02:16:05.7840058Z","229.0028494","0.986968100000013","8.13492063492063","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","230","2026-09-29T02:16:06.7987886Z","230.0175631","1.01471369999999","5","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","231","2026-09-29T02:16:07.7877081Z","231.0063483","0.988785199999995","2.57936507936508","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","232","2026-09-29T02:16:08.7910214Z","232.0096105","1.00326219999999","7.03125","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","233","2026-09-29T02:16:09.7922339Z","233.0109302","1.00131970000001","13.4874759152216","0.195055085803263","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","234","2026-09-29T02:16:10.7953410Z","234.0140473","1.0031171","14.6198830409357","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","235","2026-09-29T02:16:11.7817437Z","235.0003812","0.986333900000005","4.96031746031746","0","24176","0","0","3.26171875","14.078125","10","194","0","0"
+"3","block","236","2026-09-29T02:16:12.7942734Z","236.0129757","1.01259450000001","5.38461538461539","0","24176","0","0","3.23046875","14.0625","9","192","0","0"
+"3","block","237","2026-09-29T02:16:13.7902349Z","237.0088574","0.995881699999984","12.1031746031746","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","238","2026-09-29T02:16:14.7914295Z","238.010162","1.0013046","10.9375","0.195058027297588","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","239","2026-09-29T02:16:15.7897819Z","239.0086069","0.99844490000001","7.421875","0.195616703535666","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","240","2026-09-29T02:16:16.8015447Z","240.0201028","1.0114959","5.76923076923077","0.193092725338778","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","241","2026-09-29T02:16:17.7897317Z","241.0086527","0.98854990000001","7.14285714285714","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","242","2026-09-29T02:16:18.7936622Z","242.0123225","1.00366979999998","8.07692307692308","0.194598362927731","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","243","2026-09-29T02:16:19.7942630Z","243.0131337","1.00081120000002","7.8125","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","244","2026-09-29T02:16:20.7962253Z","244.0149685","1.00183479999998","10.15625","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","245","2026-09-29T02:16:21.7889554Z","245.0079976","0.993029100000001","7.73809523809524","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","246","2026-09-29T02:16:22.7893693Z","246.0080269","1.00002929999999","6.25","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","247","2026-09-29T02:16:23.7919738Z","247.0106868","1.00265990000003","9.1796875","0.194794366464636","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","248","2026-09-29T02:16:24.7927444Z","248.0113225","1.00063569999998","7.88461538461539","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","249","2026-09-29T02:16:25.7932585Z","249.0119821","1.00065960000001","8.984375","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","250","2026-09-29T02:16:26.7836245Z","250.0022977","0.990315600000002","6.34920634920635","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","251","2026-09-29T02:16:27.7870628Z","251.0056765","1.00337880000001","8.59375","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","252","2026-09-29T02:16:28.7886504Z","252.007306","1.00162950000001","4.6875","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","253","2026-09-29T02:16:29.7874424Z","253.0066687","0.999362699999978","7.03125","0.195437052033265","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","254","2026-09-29T02:16:30.7971266Z","254.0158841","1.00921540000002","9.42307692307692","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","255","2026-09-29T02:16:31.7953730Z","255.0140412","0.998157099999986","6.640625","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","256","2026-09-29T02:16:32.7912915Z","256.0099094","0.99586819999999","27.3809523809524","0","24176","0.015625","0.196122840351767","3.2578125","14.078125","10","192","0","0"
+"3","block","257","2026-09-29T02:16:33.7998573Z","257.0187366","1.00882720000004","27.3076923076923","0.193603522981926","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","258","2026-09-29T02:16:34.8000404Z","258.0186974","0.999960799999997","14.84375","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","259","2026-09-29T02:16:35.7986596Z","259.0172426","0.998545199999967","6.0546875","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","260","2026-09-29T02:16:36.7833693Z","260.0020281","0.984785499999987","5.57768924302789","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","261","2026-09-29T02:16:37.7821003Z","261.0008583","0.998830200000043","7.78210116731517","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","262","2026-09-29T02:16:38.7959371Z","262.0145634","1.01370509999998","5.96153846153846","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","263","2026-09-29T02:16:39.7816251Z","263.0003229","0.985759500000029","5.56660039761431","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","264","2026-09-29T02:16:40.7822295Z","264.0009199","1.00059699999997","7.60233918128655","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","265","2026-09-29T02:16:41.7851275Z","265.0035883","1.0026684","8.7890625","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","266","2026-09-29T02:16:42.7896167Z","266.0081869","1.00459860000001","4.4921875","0","24176","0","0","3.2578125","14.078125","10","192","0","0"
+"3","block","267","2026-09-29T02:16:43.7878243Z","267.0063336","0.998146700000007","5.859375","0.195675144745756","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","268","2026-09-29T02:16:44.7973145Z","268.0158946","1.00956099999996","6.53846153846154","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","269","2026-09-29T02:16:45.7821217Z","269.000914","0.985019399999999","6.34920634920635","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","270","2026-09-29T02:16:46.7962370Z","270.0147804","1.01386640000004","5.19230769230769","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","271","2026-09-29T02:16:47.7828285Z","271.0010232","0.986242799999957","4.96031746031746","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","272","2026-09-29T02:16:48.7837340Z","272.0023625","1.00133930000004","4.1015625","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","273","2026-09-29T02:16:49.7863416Z","273.0049589","1.00259639999996","6.640625","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","274","2026-09-29T02:16:50.8023935Z","274.0211568","1.01619790000001","10.5769230769231","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","275","2026-09-29T02:16:51.7946657Z","275.0133571","0.992200300000036","8.7890625","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","276","2026-09-29T02:16:52.7964233Z","276.0150725","1.00171539999997","9.5703125","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","277","2026-09-29T02:16:53.7841115Z","277.0026154","0.987542899999994","7.53968253968254","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","278","2026-09-29T02:16:54.7972928Z","278.0159282","1.01331279999999","7.11538461538461","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","279","2026-09-29T02:16:55.7860505Z","279.0046037","0.988675499999999","5.15873015873016","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","280","2026-09-29T02:16:56.7878160Z","280.0066311","1.00202740000003","6.640625","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","281","2026-09-29T02:16:57.7889925Z","281.0075574","1.0009263","7.2265625","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","282","2026-09-29T02:16:58.7976146Z","282.0162148","1.0086574","5","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","283","2026-09-29T02:16:59.7823717Z","283.0010726","0.984857799999986","5.95238095238095","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","284","2026-09-29T02:17:00.7821474Z","284.0007803","0.999707699999988","7.8125","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","285","2026-09-29T02:17:01.7847901Z","285.0034083","1.00262800000002","6.0546875","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","286","2026-09-29T02:17:02.7992656Z","286.0180374","1.01462909999998","5.76923076923077","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","287","2026-09-29T02:17:03.8016458Z","287.0202899","1.0022525","5.6640625","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","288","2026-09-29T02:17:04.7893421Z","288.0080345","0.987744600000042","8.53174603174603","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","289","2026-09-29T02:17:05.7876492Z","289.0064433","0.998408799999993","6.8359375","0.195623776553253","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","290","2026-09-29T02:17:06.7896987Z","290.0083357","1.00189239999997","7.2265625","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","291","2026-09-29T02:17:07.7980562Z","291.0165976","1.00826190000004","5.76923076923077","0.193712070246821","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","292","2026-09-29T02:17:08.7967272Z","292.0154898","0.9988922","5.2734375","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","293","2026-09-29T02:17:09.7903094Z","293.0089158","0.993425999999999","10.3174603174603","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","294","2026-09-29T02:17:10.7965315Z","294.0152847","1.00636889999998","11.7307692307692","0.194076446519763","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","295","2026-09-29T02:17:11.7821940Z","295.0007551","0.985470399999997","7.14285714285714","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","296","2026-09-29T02:17:12.7882686Z","296.0069179","1.00616279999997","4.4921875","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","297","2026-09-29T02:17:13.7880793Z","297.0067217","0.999803800000052","7.2265625","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","298","2026-09-29T02:17:14.7875152Z","298.0061411","0.999419399999965","8.203125","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","299","2026-09-29T02:17:15.7987571Z","299.017375","1.01123389999998","3.84615384615385","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
+"3","block","300","2026-09-29T02:17:16.7845235Z","300.0032511","0.985876100000041","8.13492063492063","0","24176","0","0","3.3515625","14.27734375","13","194","0","0"
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/status.txt b/docs/benchmarks/2026-09-29-v0.2.0/results/status.txt
new file mode 100644
index 0000000..ab330d9
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/status.txt
@@ -0,0 +1 @@
+SUCCESS
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/results/update-layer-evidence.jsonl b/docs/benchmarks/2026-09-29-v0.2.0/results/update-layer-evidence.jsonl
new file mode 100644
index 0000000..a82ff29
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/results/update-layer-evidence.jsonl
@@ -0,0 +1,3 @@
+{"timestamp":"2026-09-29T01:49:36.968Z","event":"update_monitoring_started","source":"update_orchestrator","action":"Layer 3 skipped because the scheduled task \\Microsoft\\Windows\\UpdateOrchestrator\\Reboot does not exist on this machine.","success":false}
+{"timestamp":"2026-09-29T02:00:43.263Z","event":"update_monitoring_started","source":"update_orchestrator","action":"Layer 3 skipped because the scheduled task \\Microsoft\\Windows\\UpdateOrchestrator\\Reboot does not exist on this machine.","success":false}
+{"timestamp":"2026-09-29T02:11:46.743Z","event":"update_monitoring_started","source":"update_orchestrator","action":"Layer 3 skipped because the scheduled task \\Microsoft\\Windows\\UpdateOrchestrator\\Reboot does not exist on this machine.","success":false}
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/summary.csv b/docs/benchmarks/2026-09-29-v0.2.0/summary.csv
new file mode 100644
index 0000000..656ab7b
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/summary.csv
@@ -0,0 +1,93 @@
+scope,scenario,metric,n,mean,median,p95,maximum,minimum
+pooled,baseline,system_cpu_pct,900,9.310717623187722,7.8125,17.1153846153846,86.9230769230769,3.515625
+pooled,baseline,collector_cpu_pct,900,0.013671551857681225,0.0,0.194617520833106,1.37095722107078,0.0
+pooled,baseline,interval_s,900,1.0000236361111112,1.00029585000002,1.01091550000001,1.0194018,0.980372000000003
+pooled,allow,cpu_pct,900,0.0023870911123183057,0.0,0.0,0.19714806679066,0.0
+pooled,allow,private_mib,900,1.9550390625,1.95703125,2.01953125,2.04296875,1.90625
+pooled,allow,working_set_mib,900,12.56752170138889,12.5625,12.71484375,12.75390625,12.4921875
+pooled,allow,threads,900,5.985555555555556,5.0,8.0,8.0,5.0
+pooled,allow,handles,900,174.67111111111112,174.0,176.0,176.0,174.0
+pooled,allow,io_read_bytes_s,900,0.0,0.0,0.0,0.0,0.0
+pooled,allow,io_write_bytes_s,900,0.0,0.0,0.0,0.0,0.0
+pooled,allow,system_cpu_pct,900,9.140272307001851,7.715201465201465,18.359375,46.09375,3.515625
+pooled,allow,collector_cpu_pct,900,0.049477888509870324,0.0,0.195845552424593,0.393158948740528,0.0
+pooled,allow,interval_s,900,1.000025832888889,0.9999746000000015,1.01361110000001,1.0248538,0.9665964
+pooled,block,cpu_pct,900,0.004991235622742559,0.0,0.0,0.197048179181501,0.0
+pooled,block,private_mib,900,3.251236979166667,3.24609375,3.3359375,3.359375,3.19140625
+pooled,block,working_set_mib,900,13.946493055555555,14.046875,14.265625,14.27734375,13.0234375
+pooled,block,threads,900,10.333333333333334,10.0,13.0,13.0,9.0
+pooled,block,handles,900,193.48888888888888,194.0,194.0,194.0,192.0
+pooled,block,io_read_bytes_s,900,0.0,0.0,0.0,0.0,0.0
+pooled,block,io_write_bytes_s,900,0.0,0.0,0.0,0.0,0.0
+pooled,block,system_cpu_pct,900,9.026946098286222,7.421875,18.0555555555556,45.7692307692308,2.57936507936508
+pooled,block,collector_cpu_pct,900,0.040146895226407533,0.0,0.195518694014706,0.389974016374465,0.0
+pooled,block,interval_s,900,1.0000167937777777,1.00011315,1.01275580000001,1.0183159,0.979117800000012
+1,baseline,system_cpu_pct,300,9.4270893620663,8.169022817460315,17.6923076923077,40.2777777777778,3.76984126984127
+1,baseline,collector_cpu_pct,300,0.020181581221190112,0.0,0.195230678822508,1.37095722107078,0.0
+1,baseline,interval_s,300,1.0000352026666668,1.0002395000000002,1.0089906,1.0150003,0.9812941
+1,allow,cpu_pct,300,0.0026040354623398957,0.0,0.0,0.196429792660654,0.0
+1,allow,private_mib,300,1.943046875,1.9140625,2.0,2.0,1.9140625
+1,allow,working_set_mib,300,12.527005208333334,12.4921875,12.66796875,12.66796875,12.4921875
+1,allow,threads,300,5.98,5.0,8.0,8.0,5.0
+1,allow,handles,300,174.66666666666666,174.0,176.0,176.0,174.0
+1,allow,io_read_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+1,allow,io_write_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+1,allow,system_cpu_pct,300,9.331818218824207,7.480778769841271,19.7265625,41.2109375,3.515625
+1,allow,collector_cpu_pct,300,0.042966585128608285,0.0,0.195573414492276,0.393158948740528,0.0
+1,allow,interval_s,300,1.000050385,0.999954199999996,1.01377969999999,1.0248538,0.9665964
+1,block,cpu_pct,300,0.003906120846718285,0.0,0.0,0.195852151016912,0.0
+1,block,private_mib,300,3.2445703125,3.234375,3.3359375,3.359375,3.203125
+1,block,working_set_mib,300,14.0693359375,14.046875,14.265625,14.26953125,13.92578125
+1,block,threads,300,10.366666666666667,10.0,13.0,13.0,9.0
+1,block,handles,300,193.48,194.0,194.0,194.0,192.0
+1,block,io_read_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+1,block,io_write_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+1,block,system_cpu_pct,300,8.863378133805679,7.324481074481075,17.7734375,45.7692307692308,3.90625
+1,block,collector_cpu_pct,300,0.02929590635038713,0.0,0.19531873066751,0.196246831163168,0.0
+1,block,interval_s,300,1.0000330643333333,1.000224900000005,1.01188690000004,1.0183159,0.979117800000012
+2,baseline,system_cpu_pct,300,9.093366993306686,7.97216021825397,15.0793650793651,41.6666666666667,4.296875
+2,baseline,collector_cpu_pct,300,0.015624672579777866,0.0,0.194995787841381,0.390417844291822,0.0
+2,baseline,interval_s,300,1.0000209553333335,1.00044265,1.0106092,1.0194018,0.981294300000002
+2,allow,cpu_pct,300,0.0032551589579972104,0.0,0.0,0.19714806679066,0.0
+2,allow,private_mib,300,1.9863020833333334,1.95703125,2.04296875,2.04296875,1.95703125
+2,allow,working_set_mib,300,12.60734375,12.578125,12.75390625,12.75390625,12.578125
+2,allow,threads,300,5.99,5.0,8.0,8.0,5.0
+2,allow,handles,300,174.67333333333335,174.0,176.0,176.0,174.0
+2,allow,io_read_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+2,allow,io_write_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+2,allow,system_cpu_pct,300,9.528057373402646,8.357699805068226,20.0392927308448,46.09375,3.96825396825397
+2,allow,collector_cpu_pct,300,0.05273357511955474,0.0,0.195630438588794,0.197271146027562,0.0
+2,allow,interval_s,300,1.0000151683333331,0.999932800000009,1.01079730000001,1.01451029999998,0.985216799999996
+2,block,cpu_pct,300,0.008463486718889725,0.0,0.0,0.197048179181501,0.0
+2,block,private_mib,300,3.2369270833333332,3.244140625,3.2890625,3.2890625,3.19140625
+2,block,working_set_mib,300,13.669856770833333,14.01953125,14.0390625,14.04296875,13.0234375
+2,block,threads,300,10.26,10.0,12.0,12.0,9.0
+2,block,handles,300,193.49333333333334,194.0,194.0,194.0,192.0
+2,block,io_read_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+2,block,io_write_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+2,block,system_cpu_pct,300,9.668837806705387,8.0078125,19.53125,41.468253968254,3.515625
+2,block,collector_cpu_pct,300,0.0546871449528259,0.0,0.195682437648375,0.389974016374465,0.0
+2,block,interval_s,300,1.0000064923333332,1.0000182,1.01092840000001,1.015154,0.98461309999999
+3,baseline,system_cpu_pct,300,9.41169548279246,7.4609375,20.1171875,86.9230769230769,3.515625
+3,baseline,collector_cpu_pct,300,0.0052082565098137265,0.0,0.0,0.196882381041712,0.0
+3,baseline,interval_s,300,1.0000147503333332,1.0003615499999952,1.0121634,1.01521399999996,0.980372000000003
+3,allow,cpu_pct,300,0.0013020677796996792,0.0,0.0,0.194801185847389,0.0
+3,allow,private_mib,300,1.9357682291666667,1.90625,1.99609375,1.99609375,1.90625
+3,allow,working_set_mib,300,12.568216145833333,12.5390625,12.71484375,12.71484375,12.5390625
+3,allow,threads,300,5.986666666666666,5.0,8.0,8.0,5.0
+3,allow,handles,300,174.67333333333335,174.0,176.0,176.0,174.0
+3,allow,io_read_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+3,allow,io_write_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+3,allow,system_cpu_pct,300,8.56093271608931,7.421875,15.625,37.109375,3.90625
+3,allow,collector_cpu_pct,300,0.052733745077837124,0.0,0.197443288222162,0.39194420580791,0.0
+3,allow,interval_s,300,1.0000119453333334,1.000105950000005,1.01430719999999,1.0191368,0.978705200000036
+3,block,cpu_pct,300,0.002604138477735689,0.0,0.0,0.196122840351767,0.0
+3,block,private_mib,300,3.2722135416666664,3.26171875,3.3515625,3.3515625,3.23046875
+3,block,working_set_mib,300,14.100286458333333,14.078125,14.27734375,14.27734375,14.0625
+3,block,threads,300,10.373333333333333,10.0,13.0,13.0,9.0
+3,block,handles,300,193.49333333333334,194.0,194.0,194.0,192.0
+3,block,io_read_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+3,block,io_write_bytes_s,300,0.0,0.0,0.0,0.0,0.0
+3,block,system_cpu_pct,300,8.548628772863976,7.2601142634357,15.1923076923077,39.2857142857143,2.57936507936508
+3,block,collector_cpu_pct,300,0.03645793868829966,0.0,0.195363626661097,0.197120668177123,0.0
+3,block,interval_s,300,1.0000108246666666,1.0001475499999999,1.0142349,1.01716189999999,0.981509700000004
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/summary.json b/docs/benchmarks/2026-09-29-v0.2.0/summary.json
new file mode 100644
index 0000000..91bd9bd
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/summary.json
@@ -0,0 +1,1014 @@
+[
+ {
+ "scope": "pooled",
+ "scenario": "baseline",
+ "metric": "system_cpu_pct",
+ "n": 900,
+ "mean": 9.310717623187722,
+ "median": 7.8125,
+ "p95": 17.1153846153846,
+ "maximum": 86.9230769230769,
+ "minimum": 3.515625
+ },
+ {
+ "scope": "pooled",
+ "scenario": "baseline",
+ "metric": "collector_cpu_pct",
+ "n": 900,
+ "mean": 0.013671551857681225,
+ "median": 0.0,
+ "p95": 0.194617520833106,
+ "maximum": 1.37095722107078,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "baseline",
+ "metric": "interval_s",
+ "n": 900,
+ "mean": 1.0000236361111112,
+ "median": 1.00029585000002,
+ "p95": 1.01091550000001,
+ "maximum": 1.0194018,
+ "minimum": 0.980372000000003
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "cpu_pct",
+ "n": 900,
+ "mean": 0.0023870911123183057,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.19714806679066,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "private_mib",
+ "n": 900,
+ "mean": 1.9550390625,
+ "median": 1.95703125,
+ "p95": 2.01953125,
+ "maximum": 2.04296875,
+ "minimum": 1.90625
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "working_set_mib",
+ "n": 900,
+ "mean": 12.56752170138889,
+ "median": 12.5625,
+ "p95": 12.71484375,
+ "maximum": 12.75390625,
+ "minimum": 12.4921875
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "threads",
+ "n": 900,
+ "mean": 5.985555555555556,
+ "median": 5.0,
+ "p95": 8.0,
+ "maximum": 8.0,
+ "minimum": 5.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "handles",
+ "n": 900,
+ "mean": 174.67111111111112,
+ "median": 174.0,
+ "p95": 176.0,
+ "maximum": 176.0,
+ "minimum": 174.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "io_read_bytes_s",
+ "n": 900,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "io_write_bytes_s",
+ "n": 900,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "system_cpu_pct",
+ "n": 900,
+ "mean": 9.140272307001851,
+ "median": 7.715201465201465,
+ "p95": 18.359375,
+ "maximum": 46.09375,
+ "minimum": 3.515625
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "collector_cpu_pct",
+ "n": 900,
+ "mean": 0.049477888509870324,
+ "median": 0.0,
+ "p95": 0.195845552424593,
+ "maximum": 0.393158948740528,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "allow",
+ "metric": "interval_s",
+ "n": 900,
+ "mean": 1.000025832888889,
+ "median": 0.9999746000000015,
+ "p95": 1.01361110000001,
+ "maximum": 1.0248538,
+ "minimum": 0.9665964
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "cpu_pct",
+ "n": 900,
+ "mean": 0.004991235622742559,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.197048179181501,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "private_mib",
+ "n": 900,
+ "mean": 3.251236979166667,
+ "median": 3.24609375,
+ "p95": 3.3359375,
+ "maximum": 3.359375,
+ "minimum": 3.19140625
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "working_set_mib",
+ "n": 900,
+ "mean": 13.946493055555555,
+ "median": 14.046875,
+ "p95": 14.265625,
+ "maximum": 14.27734375,
+ "minimum": 13.0234375
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "threads",
+ "n": 900,
+ "mean": 10.333333333333334,
+ "median": 10.0,
+ "p95": 13.0,
+ "maximum": 13.0,
+ "minimum": 9.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "handles",
+ "n": 900,
+ "mean": 193.48888888888888,
+ "median": 194.0,
+ "p95": 194.0,
+ "maximum": 194.0,
+ "minimum": 192.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "io_read_bytes_s",
+ "n": 900,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "io_write_bytes_s",
+ "n": 900,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "system_cpu_pct",
+ "n": 900,
+ "mean": 9.026946098286222,
+ "median": 7.421875,
+ "p95": 18.0555555555556,
+ "maximum": 45.7692307692308,
+ "minimum": 2.57936507936508
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "collector_cpu_pct",
+ "n": 900,
+ "mean": 0.040146895226407533,
+ "median": 0.0,
+ "p95": 0.195518694014706,
+ "maximum": 0.389974016374465,
+ "minimum": 0.0
+ },
+ {
+ "scope": "pooled",
+ "scenario": "block",
+ "metric": "interval_s",
+ "n": 900,
+ "mean": 1.0000167937777777,
+ "median": 1.00011315,
+ "p95": 1.01275580000001,
+ "maximum": 1.0183159,
+ "minimum": 0.979117800000012
+ },
+ {
+ "scope": 1,
+ "scenario": "baseline",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 9.4270893620663,
+ "median": 8.169022817460315,
+ "p95": 17.6923076923077,
+ "maximum": 40.2777777777778,
+ "minimum": 3.76984126984127
+ },
+ {
+ "scope": 1,
+ "scenario": "baseline",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.020181581221190112,
+ "median": 0.0,
+ "p95": 0.195230678822508,
+ "maximum": 1.37095722107078,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "baseline",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.0000352026666668,
+ "median": 1.0002395000000002,
+ "p95": 1.0089906,
+ "maximum": 1.0150003,
+ "minimum": 0.9812941
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "cpu_pct",
+ "n": 300,
+ "mean": 0.0026040354623398957,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.196429792660654,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "private_mib",
+ "n": 300,
+ "mean": 1.943046875,
+ "median": 1.9140625,
+ "p95": 2.0,
+ "maximum": 2.0,
+ "minimum": 1.9140625
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "working_set_mib",
+ "n": 300,
+ "mean": 12.527005208333334,
+ "median": 12.4921875,
+ "p95": 12.66796875,
+ "maximum": 12.66796875,
+ "minimum": 12.4921875
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "threads",
+ "n": 300,
+ "mean": 5.98,
+ "median": 5.0,
+ "p95": 8.0,
+ "maximum": 8.0,
+ "minimum": 5.0
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "handles",
+ "n": 300,
+ "mean": 174.66666666666666,
+ "median": 174.0,
+ "p95": 176.0,
+ "maximum": 176.0,
+ "minimum": 174.0
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "io_read_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "io_write_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 9.331818218824207,
+ "median": 7.480778769841271,
+ "p95": 19.7265625,
+ "maximum": 41.2109375,
+ "minimum": 3.515625
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.042966585128608285,
+ "median": 0.0,
+ "p95": 0.195573414492276,
+ "maximum": 0.393158948740528,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "allow",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.000050385,
+ "median": 0.999954199999996,
+ "p95": 1.01377969999999,
+ "maximum": 1.0248538,
+ "minimum": 0.9665964
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "cpu_pct",
+ "n": 300,
+ "mean": 0.003906120846718285,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.195852151016912,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "private_mib",
+ "n": 300,
+ "mean": 3.2445703125,
+ "median": 3.234375,
+ "p95": 3.3359375,
+ "maximum": 3.359375,
+ "minimum": 3.203125
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "working_set_mib",
+ "n": 300,
+ "mean": 14.0693359375,
+ "median": 14.046875,
+ "p95": 14.265625,
+ "maximum": 14.26953125,
+ "minimum": 13.92578125
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "threads",
+ "n": 300,
+ "mean": 10.366666666666667,
+ "median": 10.0,
+ "p95": 13.0,
+ "maximum": 13.0,
+ "minimum": 9.0
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "handles",
+ "n": 300,
+ "mean": 193.48,
+ "median": 194.0,
+ "p95": 194.0,
+ "maximum": 194.0,
+ "minimum": 192.0
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "io_read_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "io_write_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 8.863378133805679,
+ "median": 7.324481074481075,
+ "p95": 17.7734375,
+ "maximum": 45.7692307692308,
+ "minimum": 3.90625
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.02929590635038713,
+ "median": 0.0,
+ "p95": 0.19531873066751,
+ "maximum": 0.196246831163168,
+ "minimum": 0.0
+ },
+ {
+ "scope": 1,
+ "scenario": "block",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.0000330643333333,
+ "median": 1.000224900000005,
+ "p95": 1.01188690000004,
+ "maximum": 1.0183159,
+ "minimum": 0.979117800000012
+ },
+ {
+ "scope": 2,
+ "scenario": "baseline",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 9.093366993306686,
+ "median": 7.97216021825397,
+ "p95": 15.0793650793651,
+ "maximum": 41.6666666666667,
+ "minimum": 4.296875
+ },
+ {
+ "scope": 2,
+ "scenario": "baseline",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.015624672579777866,
+ "median": 0.0,
+ "p95": 0.194995787841381,
+ "maximum": 0.390417844291822,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "baseline",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.0000209553333335,
+ "median": 1.00044265,
+ "p95": 1.0106092,
+ "maximum": 1.0194018,
+ "minimum": 0.981294300000002
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "cpu_pct",
+ "n": 300,
+ "mean": 0.0032551589579972104,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.19714806679066,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "private_mib",
+ "n": 300,
+ "mean": 1.9863020833333334,
+ "median": 1.95703125,
+ "p95": 2.04296875,
+ "maximum": 2.04296875,
+ "minimum": 1.95703125
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "working_set_mib",
+ "n": 300,
+ "mean": 12.60734375,
+ "median": 12.578125,
+ "p95": 12.75390625,
+ "maximum": 12.75390625,
+ "minimum": 12.578125
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "threads",
+ "n": 300,
+ "mean": 5.99,
+ "median": 5.0,
+ "p95": 8.0,
+ "maximum": 8.0,
+ "minimum": 5.0
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "handles",
+ "n": 300,
+ "mean": 174.67333333333335,
+ "median": 174.0,
+ "p95": 176.0,
+ "maximum": 176.0,
+ "minimum": 174.0
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "io_read_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "io_write_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 9.528057373402646,
+ "median": 8.357699805068226,
+ "p95": 20.0392927308448,
+ "maximum": 46.09375,
+ "minimum": 3.96825396825397
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.05273357511955474,
+ "median": 0.0,
+ "p95": 0.195630438588794,
+ "maximum": 0.197271146027562,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "allow",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.0000151683333331,
+ "median": 0.999932800000009,
+ "p95": 1.01079730000001,
+ "maximum": 1.01451029999998,
+ "minimum": 0.985216799999996
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "cpu_pct",
+ "n": 300,
+ "mean": 0.008463486718889725,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.197048179181501,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "private_mib",
+ "n": 300,
+ "mean": 3.2369270833333332,
+ "median": 3.244140625,
+ "p95": 3.2890625,
+ "maximum": 3.2890625,
+ "minimum": 3.19140625
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "working_set_mib",
+ "n": 300,
+ "mean": 13.669856770833333,
+ "median": 14.01953125,
+ "p95": 14.0390625,
+ "maximum": 14.04296875,
+ "minimum": 13.0234375
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "threads",
+ "n": 300,
+ "mean": 10.26,
+ "median": 10.0,
+ "p95": 12.0,
+ "maximum": 12.0,
+ "minimum": 9.0
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "handles",
+ "n": 300,
+ "mean": 193.49333333333334,
+ "median": 194.0,
+ "p95": 194.0,
+ "maximum": 194.0,
+ "minimum": 192.0
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "io_read_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "io_write_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 9.668837806705387,
+ "median": 8.0078125,
+ "p95": 19.53125,
+ "maximum": 41.468253968254,
+ "minimum": 3.515625
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.0546871449528259,
+ "median": 0.0,
+ "p95": 0.195682437648375,
+ "maximum": 0.389974016374465,
+ "minimum": 0.0
+ },
+ {
+ "scope": 2,
+ "scenario": "block",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.0000064923333332,
+ "median": 1.0000182,
+ "p95": 1.01092840000001,
+ "maximum": 1.015154,
+ "minimum": 0.98461309999999
+ },
+ {
+ "scope": 3,
+ "scenario": "baseline",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 9.41169548279246,
+ "median": 7.4609375,
+ "p95": 20.1171875,
+ "maximum": 86.9230769230769,
+ "minimum": 3.515625
+ },
+ {
+ "scope": 3,
+ "scenario": "baseline",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.0052082565098137265,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.196882381041712,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "baseline",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.0000147503333332,
+ "median": 1.0003615499999952,
+ "p95": 1.0121634,
+ "maximum": 1.01521399999996,
+ "minimum": 0.980372000000003
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "cpu_pct",
+ "n": 300,
+ "mean": 0.0013020677796996792,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.194801185847389,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "private_mib",
+ "n": 300,
+ "mean": 1.9357682291666667,
+ "median": 1.90625,
+ "p95": 1.99609375,
+ "maximum": 1.99609375,
+ "minimum": 1.90625
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "working_set_mib",
+ "n": 300,
+ "mean": 12.568216145833333,
+ "median": 12.5390625,
+ "p95": 12.71484375,
+ "maximum": 12.71484375,
+ "minimum": 12.5390625
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "threads",
+ "n": 300,
+ "mean": 5.986666666666666,
+ "median": 5.0,
+ "p95": 8.0,
+ "maximum": 8.0,
+ "minimum": 5.0
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "handles",
+ "n": 300,
+ "mean": 174.67333333333335,
+ "median": 174.0,
+ "p95": 176.0,
+ "maximum": 176.0,
+ "minimum": 174.0
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "io_read_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "io_write_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 8.56093271608931,
+ "median": 7.421875,
+ "p95": 15.625,
+ "maximum": 37.109375,
+ "minimum": 3.90625
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.052733745077837124,
+ "median": 0.0,
+ "p95": 0.197443288222162,
+ "maximum": 0.39194420580791,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "allow",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.0000119453333334,
+ "median": 1.000105950000005,
+ "p95": 1.01430719999999,
+ "maximum": 1.0191368,
+ "minimum": 0.978705200000036
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "cpu_pct",
+ "n": 300,
+ "mean": 0.002604138477735689,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.196122840351767,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "private_mib",
+ "n": 300,
+ "mean": 3.2722135416666664,
+ "median": 3.26171875,
+ "p95": 3.3515625,
+ "maximum": 3.3515625,
+ "minimum": 3.23046875
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "working_set_mib",
+ "n": 300,
+ "mean": 14.100286458333333,
+ "median": 14.078125,
+ "p95": 14.27734375,
+ "maximum": 14.27734375,
+ "minimum": 14.0625
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "threads",
+ "n": 300,
+ "mean": 10.373333333333333,
+ "median": 10.0,
+ "p95": 13.0,
+ "maximum": 13.0,
+ "minimum": 9.0
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "handles",
+ "n": 300,
+ "mean": 193.49333333333334,
+ "median": 194.0,
+ "p95": 194.0,
+ "maximum": 194.0,
+ "minimum": 192.0
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "io_read_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "io_write_bytes_s",
+ "n": 300,
+ "mean": 0.0,
+ "median": 0.0,
+ "p95": 0.0,
+ "maximum": 0.0,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "system_cpu_pct",
+ "n": 300,
+ "mean": 8.548628772863976,
+ "median": 7.2601142634357,
+ "p95": 15.1923076923077,
+ "maximum": 39.2857142857143,
+ "minimum": 2.57936507936508
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "collector_cpu_pct",
+ "n": 300,
+ "mean": 0.03645793868829966,
+ "median": 0.0,
+ "p95": 0.195363626661097,
+ "maximum": 0.197120668177123,
+ "minimum": 0.0
+ },
+ {
+ "scope": 3,
+ "scenario": "block",
+ "metric": "interval_s",
+ "n": 300,
+ "mean": 1.0000108246666666,
+ "median": 1.0001475499999999,
+ "p95": 1.0142349,
+ "maximum": 1.01716189999999,
+ "minimum": 0.981509700000004
+ }
+]
\ No newline at end of file
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/validation.json b/docs/benchmarks/2026-09-29-v0.2.0/validation.json
new file mode 100644
index 0000000..959aaae
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/validation.json
@@ -0,0 +1,78 @@
+{
+ "passed": true,
+ "samples": 2700,
+ "runs": [
+ {
+ "run": 1,
+ "scenario": "baseline",
+ "samples": 300,
+ "elapsed_s": 300.0117647,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.0150003
+ },
+ {
+ "run": 1,
+ "scenario": "allow",
+ "samples": 300,
+ "elapsed_s": 300.0151189,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.0248538
+ },
+ {
+ "run": 1,
+ "scenario": "block",
+ "samples": 300,
+ "elapsed_s": 300.0099228,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.0183159
+ },
+ {
+ "run": 2,
+ "scenario": "baseline",
+ "samples": 300,
+ "elapsed_s": 300.0062893,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.0194018
+ },
+ {
+ "run": 2,
+ "scenario": "allow",
+ "samples": 300,
+ "elapsed_s": 300.0045551,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.01451029999998
+ },
+ {
+ "run": 2,
+ "scenario": "block",
+ "samples": 300,
+ "elapsed_s": 300.001951,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.015154
+ },
+ {
+ "run": 3,
+ "scenario": "baseline",
+ "samples": 300,
+ "elapsed_s": 300.0044275,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.01521399999996
+ },
+ {
+ "run": 3,
+ "scenario": "allow",
+ "samples": 300,
+ "elapsed_s": 300.0035865,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.0191368
+ },
+ {
+ "run": 3,
+ "scenario": "block",
+ "samples": 300,
+ "elapsed_s": 300.0032511,
+ "intervals_over_1_25s": 0,
+ "max_interval_s": 1.01716189999999
+ }
+ ]
+}
\ No newline at end of file
diff --git a/docs/benchmarks/2026-09-29-v0.2.0/verify.py b/docs/benchmarks/2026-09-29-v0.2.0/verify.py
new file mode 100644
index 0000000..9977ace
--- /dev/null
+++ b/docs/benchmarks/2026-09-29-v0.2.0/verify.py
@@ -0,0 +1,33 @@
+"""Read-only integrity and reproducibility check for this archived campaign."""
+import hashlib
+from pathlib import Path
+import shutil
+import subprocess
+import sys
+import tempfile
+
+root = Path(__file__).resolve().parent
+manifest = root / 'SHA256SUMS.txt'
+expected = {}
+for line in manifest.read_text(encoding='utf-8-sig').splitlines():
+ digest, name = line.split(' ', 1)
+ path = (root / name).resolve()
+ if not path.is_relative_to(root) or name in expected:
+ raise SystemExit('Invalid or duplicate manifest path')
+ expected[name] = digest
+actual = {p.relative_to(root).as_posix() for p in root.rglob('*') if p.is_file() and p != manifest}
+if actual != set(expected):
+ raise SystemExit('Manifest coverage differs from directory contents')
+for name, digest in expected.items():
+ if hashlib.sha256((root / name).read_bytes()).hexdigest() != digest:
+ raise SystemExit(f'Checksum mismatch: {name}')
+with tempfile.TemporaryDirectory(prefix='wardoff-evidence-') as temp:
+ copy = Path(temp) / 'campaign'
+ shutil.copytree(root, copy)
+ result = subprocess.run([sys.executable, str(copy/'analyze.py')], capture_output=True, text=True)
+ if result.returncode:
+ raise SystemExit('Analysis failed: ' + result.stderr)
+ for name in ['summary.csv', 'summary.json', 'validation.json', 'RAPPORT.md']:
+ if (root/name).read_text(encoding='utf-8') != (copy/name).read_text(encoding='utf-8'):
+ raise SystemExit(f'Recomputed artifact differs: {name}')
+print(f'PASS: {len(expected)} file hashes verified; statistics and report reproduced; stored evidence unchanged.')
diff --git a/scripts/check-docs.ps1 b/scripts/check-docs.ps1
new file mode 100644
index 0000000..f613725
--- /dev/null
+++ b/scripts/check-docs.ps1
@@ -0,0 +1,199 @@
+<#
+.SYNOPSIS
+Checks local Markdown destinations with a lightweight syntax scan.
+.DESCRIPTION
+External URLs and anchors are ignored, anchor existence is not validated, and this is not a full Markdown parser.
+#>
+[CmdletBinding()]
+param(
+ [string]$RepoRoot
+)
+
+$ErrorActionPreference = 'Stop'
+$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
+if ([string]::IsNullOrWhiteSpace($RepoRoot)) {
+ $RepoRoot = Split-Path -Parent $scriptDirectory
+}
+$resolvedRoot = (Resolve-Path -LiteralPath $RepoRoot).Path
+$errors = [System.Collections.Generic.List[string]]::new()
+$utf8Strict = New-Object System.Text.UTF8Encoding($false, $true)
+
+function Add-DocError {
+ param([string]$Message)
+ $script:errors.Add($Message)
+}
+
+function Get-TargetPath {
+ param([string]$Target)
+ $value = $Target.Trim()
+ if ($value.StartsWith('<')) {
+ $endAngle = $value.IndexOf('>')
+ if ($endAngle -ge 0) {
+ $value = $value.Substring(0, $endAngle + 1)
+ }
+ }
+ if ($value.StartsWith('<') -and $value.EndsWith('>')) {
+ $value = $value.Substring(1, $value.Length - 2)
+ }
+ $titleMatch = [regex]::Match($value, '^(?.*?)(?:\s+["''][^"'']*["''])$')
+ if ($titleMatch.Success) {
+ $value = $titleMatch.Groups['destination'].Value
+ }
+ $value = $value.Trim()
+ if ([string]::IsNullOrWhiteSpace($value) -or $value.StartsWith('#') -or $value.StartsWith('//')) {
+ return $null
+ }
+ if ($value -match '^[A-Za-z][A-Za-z0-9+.-]*:') {
+ return $null
+ }
+ $fragmentIndex = $value.IndexOf('#')
+ if ($fragmentIndex -ge 0) {
+ $value = $value.Substring(0, $fragmentIndex)
+ }
+ if ([string]::IsNullOrWhiteSpace($value)) {
+ return $null
+ }
+ try {
+ return [Uri]::UnescapeDataString($value)
+ } catch {
+ return $value
+ }
+}
+
+function Test-Target {
+ param(
+ [string]$SourcePath,
+ [int]$LineNumber,
+ [string]$Target
+ )
+ $relativeTarget = Get-TargetPath $Target
+ if ($null -eq $relativeTarget) {
+ return
+ }
+ if ([IO.Path]::IsPathRooted($relativeTarget)) {
+ $candidate = $relativeTarget
+ } else {
+ $candidate = Join-Path (Split-Path -Parent $SourcePath) $relativeTarget
+ }
+ try {
+ $fullCandidate = [IO.Path]::GetFullPath($candidate)
+ } catch {
+ Add-DocError ("{0}:{1}: malformed local link target '{2}'" -f $SourcePath, $LineNumber, $Target)
+ return
+ }
+ if (-not (Test-Path -LiteralPath $fullCandidate)) {
+ Add-DocError ("{0}:{1}: missing local link target '{2}'" -f $SourcePath, $LineNumber, $Target)
+ }
+}
+
+function Get-InlineTargets {
+ param([string]$Line)
+ $matches = [regex]::Matches($Line, '!?(?' -and $angle) { $angle = $false }
+ $position++
+ }
+ if ($position -lt $Line.Length) {
+ $content = $Line.Substring($start, $position - $start).Trim()
+ if ($content.StartsWith('<')) {
+ $end = $content.IndexOf('>')
+ if ($end -ge 0) { $content = $content.Substring(0, $end + 1) }
+ } else {
+ $titleMatch = [regex]::Match($content, '^(?.*?)(?:\s+["''][^"'']*["''])$')
+ if ($titleMatch.Success) { $content = $titleMatch.Groups['destination'].Value }
+ }
+ [pscustomobject]@{ Target = $content }
+ }
+ }
+}
+
+try {
+ # Git emits unquoted paths as UTF-8. Windows PowerShell otherwise decodes
+ # them using the console code page, which corrupts non-ASCII filenames.
+ $previousConsoleEncoding = [Console]::OutputEncoding
+ try {
+ [Console]::OutputEncoding = $utf8Strict
+ $gitOutput = & git -C $resolvedRoot -c core.quotepath=false ls-files --cached --others --exclude-standard -- '*.md' 2>&1
+ $gitExitCode = $LASTEXITCODE
+ } finally {
+ [Console]::OutputEncoding = $previousConsoleEncoding
+ }
+ if ($gitExitCode -ne 0) {
+ throw "Unable to enumerate Markdown files with Git: $($gitOutput -join ' ')"
+ }
+ $paths = @($gitOutput | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | ForEach-Object { $_.ToString().Trim() } | Sort-Object -Unique)
+
+ foreach ($relativePath in $paths) {
+ $sourcePath = Join-Path $resolvedRoot ($relativePath -replace '/', '\')
+ if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
+ Add-DocError ("{0}: Markdown file listed by Git is missing" -f $sourcePath)
+ continue
+ }
+ try {
+ $bytes = [IO.File]::ReadAllBytes($sourcePath)
+ $text = $utf8Strict.GetString($bytes)
+ } catch {
+ Add-DocError ("{0}: invalid UTF-8 Markdown ({1})" -f $sourcePath, $_.Exception.Message)
+ continue
+ }
+ if ($text.IndexOf([char]0) -ge 0) {
+ Add-DocError ("{0}: Markdown contains embedded NUL" -f $sourcePath)
+ continue
+ }
+ $lines = $text -split "`r`n|`n|`r"
+ $inFence = $false
+ $fenceCharacter = $null
+ $fenceLength = 0
+ for ($index = 0; $index -lt $lines.Count; $index++) {
+ $line = $lines[$index]
+ if (-not $inFence) {
+ $openingFence = [regex]::Match($line, '^\s{0,3}(?`{3,}|~{3,})')
+ if ($openingFence.Success) {
+ $inFence = $true
+ $fenceCharacter = $openingFence.Groups['marker'].Value.Substring(0, 1)
+ $fenceLength = $openingFence.Groups['marker'].Value.Length
+ continue
+ }
+ } else {
+ $closingFence = [regex]::Match($line, '^\s{0,3}(?`{3,}|~{3,})\s*$')
+ if ($closingFence.Success -and
+ $closingFence.Groups['marker'].Value.Substring(0, 1) -eq $fenceCharacter -and
+ $closingFence.Groups['marker'].Value.Length -ge $fenceLength) {
+ $inFence = $false
+ $fenceCharacter = $null
+ $fenceLength = 0
+ }
+ continue
+ }
+ $parseLine = [regex]::Replace($line, '`+[^`]*`+', '')
+ foreach ($link in Get-InlineTargets $parseLine) {
+ Test-Target $sourcePath ($index + 1) $link.Target
+ }
+ $reference = [regex]::Match($parseLine, '^\s{0,3}\[[^\]]+\]:\s*(?<[^>\r\n]*>(?:\s+["''][^"'']*["''])?|.+?)\s*$')
+ if ($reference.Success) {
+ Test-Target $sourcePath ($index + 1) $reference.Groups['target'].Value
+ }
+ }
+ }
+ if ($errors.Count -gt 0) {
+ $errors | ForEach-Object { Write-Error $_ }
+ exit 1
+ }
+ Write-Output ("Documentation checks passed ({0} Markdown files; local anchors are not validated)." -f $paths.Count)
+ exit 0
+} catch {
+ Write-Error $_.Exception.Message
+ exit 1
+}
diff --git a/scripts/check.ps1 b/scripts/check.ps1
new file mode 100644
index 0000000..b5af51f
--- /dev/null
+++ b/scripts/check.ps1
@@ -0,0 +1,53 @@
+<#
+.SYNOPSIS
+Runs the repository's lightweight documentation and Cargo validation checks.
+.DESCRIPTION
+The Docs mode performs only the local Markdown scan; it does not validate anchors or parse full Markdown.
+#>
+[CmdletBinding()]
+param(
+ [ValidateSet('Fast', 'Full', 'Docs')]
+ [string]$Mode = 'Fast'
+)
+
+$ErrorActionPreference = 'Stop'
+$repoRoot = (Resolve-Path -LiteralPath (Split-Path -Parent $PSScriptRoot)).Path
+$originalLocation = (Get-Location).Path
+
+function Invoke-CheckStep {
+ param(
+ [string]$Label,
+ [scriptblock]$Action
+ )
+ Write-Output ("==> {0}" -f $Label)
+ & $Action
+ if ($LASTEXITCODE -ne 0) {
+ throw ("{0} failed with exit code {1}." -f $Label, $LASTEXITCODE)
+ }
+ Write-Output ("PASS: {0}" -f $Label)
+}
+
+try {
+ Set-Location -LiteralPath $repoRoot
+ $docsScript = Join-Path $PSScriptRoot 'check-docs.ps1'
+ Invoke-CheckStep 'Markdown documentation' { & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $docsScript -RepoRoot $repoRoot }
+ if ($Mode -eq 'Docs') {
+ Write-Output 'Documentation checks completed.'
+ exit 0
+ }
+
+ Invoke-CheckStep 'cargo fmt --all -- --check' { & cargo fmt --all -- --check }
+ Invoke-CheckStep 'cargo check --locked' { & cargo check --locked }
+ Invoke-CheckStep 'cargo test --locked' { & cargo test --locked }
+ if ($Mode -eq 'Full') {
+ Invoke-CheckStep 'cargo clippy --locked --all-targets --all-features -- -D warnings' { & cargo clippy --locked --all-targets --all-features -- -D warnings }
+ Invoke-CheckStep 'cargo build --release --locked' { & cargo build --release --locked }
+ }
+ Write-Output ("{0} checks completed." -f $Mode)
+ exit 0
+} catch {
+ Write-Error $_.Exception.Message
+ exit 1
+} finally {
+ Set-Location -LiteralPath $originalLocation
+}
diff --git a/scripts/release-candidate.ps1 b/scripts/release-candidate.ps1
new file mode 100644
index 0000000..154831e
--- /dev/null
+++ b/scripts/release-candidate.ps1
@@ -0,0 +1,109 @@
+<#
+.SYNOPSIS
+Validates release provenance or packages a previously checked Windows binary.
+.DESCRIPTION
+Validate performs only Git/GitHub reads. Package never compiles or starts the
+protection runtime. This script never creates a tag, release or asset remotely.
+#>
+[CmdletBinding()]
+param(
+ [ValidateSet('Validate', 'Package')][string] $Mode = 'Validate',
+ [string] $TagName = $env:RELEASE_TAG,
+ [string] $Repository = $env:GITHUB_REPOSITORY,
+ [string] $CandidateCommit = $env:GITHUB_SHA,
+ [string] $ContextPath,
+ [string] $PackageDirectory,
+ [string] $ExpectedSha256
+)
+$ErrorActionPreference = 'Stop'
+Set-StrictMode -Version Latest
+$repoRoot = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..')).Path
+. (Join-Path $PSScriptRoot 'release-guard.ps1')
+
+function Invoke-ReleaseGit {
+ param([string[]] $GitArgs)
+ $result = @(& git -C $repoRoot @GitArgs)
+ if ($LASTEXITCODE -ne 0) { throw 'Release Git read failed.' }
+ return $result
+}
+
+function Read-ReleaseApiPages {
+ param([string] $Endpoint)
+ $json = & gh api --method GET --paginate --slurp $Endpoint
+ if ($LASTEXITCODE -ne 0) { throw 'Release GitHub read failed; no fallback is allowed.' }
+ return (ConvertFrom-ReleaseApiJson -Json ($json -join "`n"))
+}
+
+$head = @(Invoke-ReleaseGit @('rev-parse', 'HEAD'))[0]
+if ($CandidateCommit -notmatch '^[0-9a-fA-F]{40}$' -or $head -ne $CandidateCommit) {
+ throw 'Checkout is not the requested candidate commit.'
+}
+if (@(Invoke-ReleaseGit @('status', '--porcelain=v1')).Count -ne 0) { throw 'Release checkout is dirty.' }
+if ([string]::IsNullOrWhiteSpace($ContextPath)) { throw 'A release context path is required.' }
+
+if ($Mode -eq 'Validate') {
+ # Validate names/versions before interpolating them in a Git or API argument.
+ $null = Get-ReleaseVersion -RepoRoot $repoRoot -TagName $TagName
+ if ($Repository -cne 'RomainROCH/Wardoff') { throw 'Release repository is not authorized.' }
+ $remote = 'https://github.com/' + $Repository + '.git'
+ $null = Invoke-ReleaseGit @('fetch', '--no-tags', $remote, '+refs/heads/main:refs/remotes/release/main')
+ & git -C $repoRoot merge-base --is-ancestor $head refs/remotes/release/main
+ $ancestryExit = $LASTEXITCODE
+ if ($ancestryExit -notin @(0, 1)) { throw 'Main ancestry is indeterminate.' }
+ $remoteRefs = Invoke-ReleaseGit @('ls-remote', '--exit-code', $remote, ('refs/tags/' + $TagName), ('refs/tags/' + $TagName + '^{}'))
+ $tagCommit = Resolve-ReleaseTagCommit -TagName $TagName -RemoteRefs $remoteRefs
+ $runsEndpoint = "repos/$Repository/actions/workflows/ci.yml/runs?branch=main&event=push&head_sha=$head&per_page=100"
+ $runs = @(foreach ($page in @(Read-ReleaseApiPages $runsEndpoint)) { $page.workflow_runs })
+ $ci = Select-ReleaseCiRun -CiRuns $runs -Repository $Repository -CandidateCommit $head
+ $jobs = @(foreach ($page in @(Read-ReleaseApiPages "repos/$Repository/actions/runs/$($ci.id)/attempts/$($ci.run_attempt)/jobs?per_page=100")) { $page.jobs })
+ $releases = @(foreach ($page in @(Read-ReleaseApiPages "repos/$Repository/releases?per_page=100")) { $page })
+ $runs = @(foreach ($page in @(Read-ReleaseApiPages $runsEndpoint)) { $page.workflow_runs })
+ $recheckedCi = Select-ReleaseCiRun -CiRuns $runs -Repository $Repository -CandidateCommit $head
+ if ($recheckedCi.id -ne $ci.id -or $recheckedCi.run_attempt -ne $ci.run_attempt -or $recheckedCi.updated_at -cne $ci.updated_at) {
+ throw 'CI evidence changed during release validation; retry only after it settles.'
+ }
+ $context = Assert-ReleaseCandidate -RepoRoot $repoRoot -Repository $Repository -TagName $TagName -CandidateCommit $head -RemoteTagCommit $tagCommit -MainContainsCandidate ($ancestryExit -eq 0) -CiRuns $runs -CiJobs $jobs -ExistingReleases $releases
+ $context | ConvertTo-Json | Set-Content -LiteralPath $ContextPath -Encoding utf8
+ Write-Output "PASS: $TagName at $head; main CI run $($context.CiRunId)."
+ exit 0
+}
+
+$context = Get-Content -LiteralPath $ContextPath -Raw | ConvertFrom-Json
+$version = Get-ReleaseVersion -RepoRoot $repoRoot -TagName $context.Tag
+if ($context.Commit -ne $head -or $context.Tag -cne $TagName -or $context.Version -cne $version -or
+ -not (Test-ReleasePositiveInteger $context.CiRunId)) { throw 'Release context differs from the checkout.' }
+if ($env:GITHUB_RUN_ID -notmatch '^[1-9][0-9]*$') { throw 'Build run ID is missing.' }
+if ($ExpectedSha256 -notmatch '^[0-9a-fA-F]{64}$') { throw 'The pre-smoke binary hash is required.' }
+. (Join-Path $repoRoot 'tests/smoke_helpers.ps1')
+$binary = Join-Path $repoRoot 'target/release/wardoff.exe'
+$hash = (Get-FileHash -LiteralPath $binary -Algorithm SHA256).Hash
+if ($hash -ne $ExpectedSha256) { throw 'Smoke changed the release binary.' }
+$versionOutput = @(& $binary --version)
+if ($LASTEXITCODE -ne 0 -or ($versionOutput -join "`n").Trim() -cne "wardoff $version") { throw 'Release executable version differs.' }
+$helpOutput = @(& $binary --help)
+if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace(($helpOutput -join "`n"))) { throw 'Release help failed.' }
+[xml]$manifest = Get-EmbeddedManifestContent -Path $binary
+$identity = $manifest.SelectNodes("/*[local-name()='assembly']/*[local-name()='assemblyIdentity']")
+$level = $manifest.SelectNodes("//*[local-name()='requestedExecutionLevel']")
+if ($identity.Count -ne 1 -or $identity[0].GetAttribute('version') -cne ($version + '.0') -or
+ $level.Count -ne 1 -or $level[0].GetAttribute('level') -cne 'asInvoker' -or $level[0].GetAttribute('uiAccess') -cne 'false') {
+ throw 'Embedded release manifest differs from the source contract.'
+}
+$null = Assert-ReleaseWindowsVersion -FileVersionInfo (Get-Item -LiteralPath $binary).VersionInfo -Version $version
+$rustVersion = (& rustc -Vv) -join "`n"
+if ($LASTEXITCODE -ne 0 -or $rustVersion -notmatch 'host: x86_64-pc-windows-msvc') { throw 'Release must use the MSVC host toolchain.' }
+if (Test-Path -LiteralPath $PackageDirectory) { throw 'Package destination already exists.' }
+$null = New-Item -ItemType Directory -Path $PackageDirectory
+Copy-Item -LiteralPath $binary -Destination (Join-Path $PackageDirectory 'wardoff.exe')
+$info = [ordered]@{
+ tag = $TagName; source_commit = $head; version = $version; target = 'x86_64-pc-windows-msvc'
+ rustc = $rustVersion; unsigned = $true; sha256 = $hash; build_run_id = [long]$env:GITHUB_RUN_ID
+ run_url = "https://github.com/$Repository/actions/runs/$env:GITHUB_RUN_ID"
+ ci_run_id = $context.CiRunId; ci_attempt = $context.CiAttempt
+ tests = @('Full local checks', 'Developer tooling tests', 'Smoke safety tests', 'Release guard tests', 'Smoke tests with the same binary')
+ limits = @('Review explicit smoke skips in the run log.', 'Physical S3/monitor, Hibernate and Modern Standby acceptance remains incomplete.', 'Unsigned; community support only.')
+}
+$info | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $PackageDirectory 'build-info.json') -Encoding utf8
+"$hash wardoff.exe" | Set-Content -LiteralPath (Join-Path $PackageDirectory 'SHA256SUMS.txt') -Encoding ascii
+$null = Assert-ReleaseArtifact -PackageDirectory $PackageDirectory -CandidateCommit $head -TagName $TagName -ExpectedSha256 $ExpectedSha256 -ExpectedBuildRunId ([long]$env:GITHUB_RUN_ID)
+Write-Output "PASS: exact unsigned MSVC package, SHA256 $hash."
diff --git a/scripts/release-guard.ps1 b/scripts/release-guard.ps1
new file mode 100644
index 0000000..6a18c2a
--- /dev/null
+++ b/scripts/release-guard.ps1
@@ -0,0 +1,174 @@
+# Pure release policy. Network reads and binary execution belong to the driver.
+Set-StrictMode -Version Latest
+
+function ConvertFrom-ReleaseApiJson {
+ param([Parameter(Mandatory = $true)][string] $Json)
+ # Supported API hosts: Windows PowerShell 5.1 or PowerShell 7.5+. The latter
+ # needs DateKind to keep timestamp text for the strict UTC/rerun checks.
+ $jsonOptions = @{}
+ if ((Get-Command ConvertFrom-Json).Parameters.ContainsKey('DateKind')) {
+ $jsonOptions.DateKind = 'String'
+ }
+ return ($Json | ConvertFrom-Json @jsonOptions)
+}
+
+function Test-ReleasePositiveInteger {
+ param($Value)
+ return (($Value -is [int] -or $Value -is [long] -or $Value -is [uint32] -or $Value -is [uint64]) -and $Value -gt 0)
+}
+
+function Assert-ReleaseWindowsVersion {
+ param([object] $FileVersionInfo, [string] $Version)
+ # FileVersion is a display string (winres emits X.Y.Z). The fixed PE
+ # version resource has four numeric components and is the version contract.
+ $parts = @($FileVersionInfo.FileMajorPart, $FileVersionInfo.FileMinorPart,
+ $FileVersionInfo.FileBuildPart, $FileVersionInfo.FilePrivatePart)
+ foreach ($part in $parts) {
+ if ($part -isnot [int] -or $part -lt 0 -or $part -gt 65535) {
+ throw 'Windows file version component is invalid.'
+ }
+ }
+ $numericVersion = $parts -join '.'
+ if ($numericVersion -cne ($Version + '.0')) { throw 'Windows file version differs from the source contract.' }
+ return $numericVersion
+}
+
+function Get-ReleaseVersion {
+ param([string] $RepoRoot, [string] $TagName)
+ if ($TagName -cnotmatch '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$') {
+ throw 'Release tag must be a stable vX.Y.Z without leading zeroes.'
+ }
+ $version = $TagName.Substring(1)
+ foreach ($part in $version.Split('.')) {
+ if ([decimal]$part -gt 65535) { throw 'Release version exceeds the Windows version range.' }
+ }
+ $toml = Get-Content -LiteralPath (Join-Path $RepoRoot 'Cargo.toml') -Raw
+ $package = [regex]::Matches($toml, '(?ms)^\[package\]\s*\r?\n(.*?)(?=^\[|\z)')
+ if ($package.Count -ne 1 -or $package[0].Groups[1].Value -notmatch '(?m)^name\s*=\s*"wardoff"\s*$') {
+ throw 'Cargo.toml must declare the wardoff package.'
+ }
+ $versions = [regex]::Matches($package[0].Groups[1].Value, '(?m)^version\s*=\s*"([^"]+)"\s*$')
+ if ($versions.Count -ne 1 -or $versions[0].Groups[1].Value -cne $version) {
+ throw 'Tag and Cargo.toml package version differ.'
+ }
+ $lock = Get-Content -LiteralPath (Join-Path $RepoRoot 'Cargo.lock') -Raw
+ $packages = @([regex]::Matches($lock, '(?ms)^\[\[package\]\]\s*\r?\n(.*?)(?=^\[\[package\]\]|\z)') |
+ Where-Object { $_.Groups[1].Value -match '(?m)^name\s*=\s*"wardoff"\s*$' })
+ if ($packages.Count -ne 1) { throw 'Cargo.lock must contain exactly one wardoff package.' }
+ $locked = [regex]::Matches($packages[0].Groups[1].Value, '(?m)^version\s*=\s*"([^"]+)"\s*$')
+ if ($locked.Count -ne 1 -or $locked[0].Groups[1].Value -cne $version) {
+ throw 'Tag and Cargo.lock package version differ.'
+ }
+ [xml]$manifest = Get-Content -LiteralPath (Join-Path $RepoRoot 'wardoff.manifest') -Raw
+ $identity = $manifest.SelectNodes("/*[local-name()='assembly']/*[local-name()='assemblyIdentity']")
+ $level = $manifest.SelectNodes("//*[local-name()='requestedExecutionLevel']")
+ if ($identity.Count -ne 1 -or $identity[0].GetAttribute('name') -cne 'wardoff' -or
+ $identity[0].GetAttribute('version') -cne ($version + '.0') -or $level.Count -ne 1 -or
+ $level[0].GetAttribute('level') -cne 'asInvoker' -or $level[0].GetAttribute('uiAccess') -cne 'false') {
+ throw 'Manifest must match the package version and retain asInvoker/uiAccess=false.'
+ }
+ return $version
+}
+
+function Resolve-ReleaseTagCommit {
+ param([string] $TagName, [AllowEmptyCollection()][string[]] $RemoteRefs)
+ if ($TagName -cnotmatch '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$') { throw 'Invalid release tag.' }
+ $refName = 'refs/tags/' + $TagName
+ $base = @(); $peeled = @()
+ foreach ($line in $RemoteRefs) {
+ if ($line -notmatch '^([0-9a-fA-F]{40})\s+(\S+)$') { throw 'Malformed remote tag response.' }
+ $sha = $Matches[1]; $ref = $Matches[2]
+ if ($ref -ceq $refName) { $base += $sha }
+ elseif ($ref -ceq ($refName + '^{}')) { $peeled += $sha }
+ else { throw 'Unexpected remote tag reference.' }
+ }
+ if ($base.Count -ne 1 -or $peeled.Count -gt 1) { throw 'Remote tag is absent or ambiguous.' }
+ if ($peeled.Count -eq 1) { return $peeled[0].ToLowerInvariant() }
+ return $base[0].ToLowerInvariant()
+}
+
+function Select-ReleaseCiRun {
+ param([AllowEmptyCollection()][object[]] $CiRuns, [string] $Repository, [string] $CandidateCommit)
+ $matching = @($CiRuns | Where-Object {
+ $_.head_sha -eq $CandidateCommit -and $_.head_branch -ceq 'main' -and $_.event -ceq 'push' -and
+ $_.head_repository.full_name -ceq $Repository -and
+ $_.path -cin @('.github/workflows/ci.yml', '.github/workflows/ci.yml@refs/heads/main')
+ })
+ if ($matching.Count -eq 0) { throw 'No CI push/main run exists for the exact candidate commit.' }
+ foreach ($run in $matching) {
+ if (-not (Test-ReleasePositiveInteger $run.id) -or -not (Test-ReleasePositiveInteger $run.run_attempt)) {
+ throw 'CI run identity or attempt is invalid.'
+ }
+ $updated = [datetimeoffset]::MinValue
+ if ($run.updated_at -isnot [string] -or $run.updated_at -notmatch '(Z|\+00:00)$' -or
+ -not [datetimeoffset]::TryParse($run.updated_at, [ref]$updated)) { throw 'CI update timestamp is invalid or not UTC.' }
+ }
+ $selected = $matching | Sort-Object @{Expression = { [datetimeoffset]$_.updated_at }; Descending = $true}, @{Expression = { $_.id }; Descending = $true}, @{Expression = { $_.run_attempt }; Descending = $true} | Select-Object -First 1
+ if ($selected.status -cne 'completed' -or $selected.conclusion -cne 'success') {
+ throw 'The latest candidate CI run has not completed successfully.'
+ }
+ return $selected
+}
+
+function Assert-ReleaseDraftAvailable {
+ param([string] $TagName, [AllowEmptyCollection()][object[]] $Releases)
+ if (@($Releases | Where-Object { $_.tag_name -ceq $TagName }).Count -gt 0) {
+ throw 'A release or draft already exists for this tag; never overwrite it.'
+ }
+}
+
+function Assert-ReleaseCandidate {
+ param([string] $RepoRoot, [string] $Repository, [string] $TagName,
+ [string] $CandidateCommit, [string] $RemoteTagCommit, [bool] $MainContainsCandidate,
+ [AllowEmptyCollection()][object[]] $CiRuns, [AllowEmptyCollection()][object[]] $CiJobs,
+ [AllowEmptyCollection()][object[]] $ExistingReleases)
+ if ($Repository -cne 'RomainROCH/Wardoff') { throw 'Release repository is not authorized.' }
+ if ($CandidateCommit -notmatch '^[0-9a-fA-F]{40}$' -or $RemoteTagCommit -notmatch '^[0-9a-fA-F]{40}$' -or
+ $CandidateCommit -ne $RemoteTagCommit) { throw 'Remote tag does not identify the tested commit.' }
+ if (-not $MainContainsCandidate) { throw 'Candidate commit is not reachable from main.' }
+ $version = Get-ReleaseVersion -RepoRoot $RepoRoot -TagName $TagName
+ $run = Select-ReleaseCiRun -CiRuns $CiRuns -Repository $Repository -CandidateCommit $CandidateCommit
+ if ($CiJobs.Count -eq 0) { throw 'CI jobs are missing.' }
+ foreach ($job in $CiJobs) {
+ if ($job.run_id -ne $run.id -or $job.head_sha -ne $CandidateCommit -or -not (Test-ReleasePositiveInteger $job.run_id) -or
+ $job.status -cne 'completed' -or $job.conclusion -cne 'success') { throw 'A candidate CI job is not successful.' }
+ }
+ $windows = @($CiJobs | Where-Object { $_.name -ceq 'ci (windows-latest, stable)' })
+ if ($windows.Count -ne 1) { throw 'Required Windows CI job is missing or ambiguous.' }
+ foreach ($name in @('Full local checks', 'Developer tooling tests', 'Smoke safety tests', 'Release guard tests', 'Smoke tests')) {
+ $step = @($windows[0].steps | Where-Object { $_.name -ceq $name })
+ if ($step.Count -ne 1 -or $step[0].status -cne 'completed' -or $step[0].conclusion -cne 'success') {
+ throw "Required CI step is absent, skipped or failed: $name."
+ }
+ }
+ Assert-ReleaseDraftAvailable -TagName $TagName -Releases $ExistingReleases
+ return [pscustomobject]@{ Tag = $TagName; Version = $version; Commit = $CandidateCommit.ToLowerInvariant(); CiRunId = $run.id; CiAttempt = $run.run_attempt }
+}
+
+function Assert-ReleaseArtifact {
+ param([string] $PackageDirectory, [string] $CandidateCommit, [string] $TagName,
+ [string] $ExpectedSha256, $ExpectedBuildRunId)
+ if ($CandidateCommit -notmatch '^[0-9a-fA-F]{40}$' -or $ExpectedSha256 -notmatch '^[0-9a-fA-F]{64}$' -or
+ $TagName -cnotmatch '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$' -or
+ -not (Test-ReleasePositiveInteger $ExpectedBuildRunId)) { throw 'Artifact expectations are invalid.' }
+ $binary = Join-Path $PackageDirectory 'wardoff.exe'
+ $info = Get-Content -LiteralPath (Join-Path $PackageDirectory 'build-info.json') -Raw | ConvertFrom-Json
+ $hash = (Get-FileHash -LiteralPath $binary -Algorithm SHA256).Hash
+ $checksum = @(Get-Content -LiteralPath (Join-Path $PackageDirectory 'SHA256SUMS.txt'))
+ if ($checksum.Count -ne 1 -or $checksum[0] -cnotmatch '^([0-9a-fA-F]{64}) wardoff\.exe$' -or
+ $Matches[1] -ne $ExpectedSha256) { throw 'Package checksum file differs from the checked binary.' }
+ if ($hash -ne $ExpectedSha256 -or $info.sha256 -ne $ExpectedSha256 -or
+ $info.source_commit -ne $CandidateCommit -or $info.tag -cne $TagName -or
+ $info.version -cne $TagName.Substring(1) -or $info.target -cne 'x86_64-pc-windows-msvc' -or
+ $info.unsigned -isnot [bool] -or -not $info.unsigned -or
+ -not (Test-ReleasePositiveInteger $info.build_run_id) -or $info.build_run_id -ne $ExpectedBuildRunId -or
+ -not (Test-ReleasePositiveInteger $info.ci_run_id)) { throw 'Artifact hash or build metadata differs from the validated candidate.' }
+ return $info
+}
+
+function Assert-ReleaseTransferInputs {
+ param([string] $ArtifactId, [string] $Sha256)
+ if ($ArtifactId -cnotmatch '^[1-9][0-9]*$' -or $Sha256 -cnotmatch '^[0-9a-fA-F]{64}$') {
+ throw 'Exact artifact ID and binary SHA256 are required before downloading.'
+ }
+}
diff --git a/src/autostart.rs b/src/autostart.rs
index b38401d..5be1053 100644
--- a/src/autostart.rs
+++ b/src/autostart.rs
@@ -677,7 +677,7 @@ fn sid_to_string(sid: PSID, context: &str) -> Result {
}
let string_sid = LocalAllocatedWideString(string_sid);
- let sid = string_sid.to_string();
+ let sid = string_sid.to_string_lossy();
if sid.is_empty() {
return Err(format!(
"Wardoff could not {context} before updating {AUTOSTART_TASK_PATH}: the process token resolved to an empty SID string."
@@ -721,7 +721,7 @@ impl Drop for LocalSecurityDescriptor {
struct LocalAllocatedWideString(PWSTR);
impl LocalAllocatedWideString {
- fn to_string(&self) -> String {
+ fn to_string_lossy(&self) -> String {
if self.0.is_null() {
return String::new();
}
diff --git a/src/blocker/local.rs b/src/blocker/local.rs
index 9454168..a6105a9 100644
--- a/src/blocker/local.rs
+++ b/src/blocker/local.rs
@@ -479,7 +479,9 @@ fn read_unicode_property(event_record: &EVENT_RECORD, property_name: &str) -> Op
}
let utf16 = property_buffer
- .chunks_exact(2)
+ .as_chunks::<2>()
+ .0
+ .iter()
.map(|chunk| u16::from_ne_bytes([chunk[0], chunk[1]]))
.take_while(|value| *value != 0)
.collect::>();
diff --git a/src/cli.rs b/src/cli.rs
index 108b5bb..84914d8 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -73,7 +73,7 @@ pub struct WardoffCli {
/// Prints the newest structured Wardoff JSON log lines.
#[arg(long, conflicts_with_all = ["block", "allow", "status", "hide", "autostart"])]
log: bool,
- /// Overrides the default number of structured log lines shown by `--log`.
+ /// Overrides the default number of structured log lines shown by `--log` (maximum 100000).
#[arg(long, value_name = "N", requires = "log")]
tail: Option,
/// Internal marker used to prevent default-launch elevation loops.
@@ -237,6 +237,9 @@ mod tests {
assert!(error
.to_string()
.contains("Open-source Windows shutdown/reboot protection and idle-sleep prevention"));
+ assert!(error
+ .to_string()
+ .contains(&format!("maximum {}", crate::logger::MAX_TAIL_LINE_COUNT)));
}
#[test]
diff --git a/src/config.rs b/src/config.rs
deleted file mode 100644
index 130be7e..0000000
--- a/src/config.rs
+++ /dev/null
@@ -1 +0,0 @@
-//! Configuration scaffolding intentionally removed.
diff --git a/src/ipc.rs b/src/ipc.rs
index d335da8..bb0d7bc 100644
--- a/src/ipc.rs
+++ b/src/ipc.rs
@@ -1,3 +1,9 @@
+//! Session-scoped control and read-only status transports.
+//!
+//! `IpcServer::start` owns startup of both pipe workers; requests are queued back
+//! to the application thread, which owns mode changes. Keep wire types, access
+//! checks and retry behavior consistent with docs/ARCHITECTURE.md.
+
use crate::blocker::BlockerMode;
use crate::cli::StatusOutput;
use crate::logger::{self, EventSource};
@@ -7,19 +13,19 @@ use serde::{Deserialize, Serialize};
use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader, Write};
use std::mem::size_of;
-use std::os::windows::io::{FromRawHandle, RawHandle};
+use std::os::windows::io::{AsRawHandle, FromRawHandle, RawHandle};
use std::sync::{
atomic::{AtomicBool, Ordering},
mpsc::{self, Sender},
Arc,
};
use std::thread::{self, JoinHandle};
-use std::time::Duration;
+use std::time::{Duration, Instant};
use windows::core::{Error as WindowsError, PCWSTR, PWSTR};
use windows::Win32::Foundation::{
- CloseHandle, GetLastError, LocalFree, ERROR_ACCESS_DENIED, ERROR_FILE_NOT_FOUND,
- ERROR_INSUFFICIENT_BUFFER, ERROR_PATH_NOT_FOUND, ERROR_PIPE_BUSY, ERROR_PIPE_CONNECTED, HANDLE,
- HLOCAL, LPARAM, WPARAM,
+ CloseHandle, GetLastError, LocalFree, ERROR_ACCESS_DENIED, ERROR_BROKEN_PIPE,
+ ERROR_FILE_NOT_FOUND, ERROR_INSUFFICIENT_BUFFER, ERROR_NO_DATA, ERROR_PATH_NOT_FOUND,
+ ERROR_PIPE_BUSY, ERROR_PIPE_CONNECTED, HANDLE, HLOCAL, LPARAM, WPARAM,
};
use windows::Win32::Security::Authorization::{
ConvertSidToStringSidW, ConvertStringSecurityDescriptorToSecurityDescriptorW, SDDL_REVISION_1,
@@ -29,12 +35,12 @@ use windows::Win32::Security::{
TOKEN_USER,
};
use windows::Win32::Storage::FileSystem::{
- FILE_FLAGS_AND_ATTRIBUTES, FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_ACCESS_DUPLEX,
+ ReadFile, FILE_FLAGS_AND_ATTRIBUTES, FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_ACCESS_DUPLEX,
PIPE_ACCESS_OUTBOUND,
};
use windows::Win32::System::Pipes::{
- ConnectNamedPipe, CreateNamedPipeW, PIPE_READMODE_MESSAGE, PIPE_REJECT_REMOTE_CLIENTS,
- PIPE_TYPE_MESSAGE, PIPE_WAIT,
+ ConnectNamedPipe, CreateNamedPipeW, SetNamedPipeHandleState, PIPE_NOWAIT, PIPE_READMODE_BYTE,
+ PIPE_READMODE_MESSAGE, PIPE_REJECT_REMOTE_CLIENTS, PIPE_TYPE_MESSAGE, PIPE_WAIT,
};
use windows::Win32::System::Threading::{GetCurrentProcess, OpenProcessToken};
use windows::Win32::UI::WindowsAndMessaging::{PostThreadMessageW, WM_APP};
@@ -42,6 +48,10 @@ use windows::Win32::UI::WindowsAndMessaging::{PostThreadMessageW, WM_APP};
const IPC_SERVER_THREAD_NAME: &str = "wardoff-ipc-server";
const STATUS_SERVER_THREAD_NAME: &str = "wardoff-status-server";
const PIPE_BUFFER_SIZE: u32 = 4096;
+// Includes the terminating newline; all current control commands are much smaller.
+const MAX_REQUEST_BYTES: usize = 4096;
+const REQUEST_READ_TIMEOUT: Duration = Duration::from_secs(1);
+const REQUEST_READ_POLL_DELAY: Duration = Duration::from_millis(10);
const PIPE_CONNECT_ATTEMPTS: usize = 20;
const PIPE_CONNECT_DELAY: Duration = Duration::from_millis(100);
const INITIAL_PIPE_CLAIM_ATTEMPTS: usize = 10;
@@ -897,20 +907,95 @@ fn is_retryable_initial_pipe_claim_error(error_code: u32) -> bool {
}
fn read_request(pipe: &mut File) -> Result {
- let mut request_line = String::new();
- let bytes_read = {
- let mut reader = BufReader::new(pipe);
- reader
- .read_line(&mut request_line)
- .map_err(|error| format!("Wardoff could not read an IPC request: {error}"))?
- };
+ // Nonblocking byte reads also handle a JSON line split across pipe messages.
+ // The pipe is owned by this server thread; no helper thread or pending I/O survives a timeout.
+ let handle = HANDLE(pipe.as_raw_handle());
+ let read_mode = PIPE_READMODE_BYTE | PIPE_NOWAIT;
+ unsafe { SetNamedPipeHandleState(handle, Some(&read_mode), None, None) }
+ .map_err(|error| format!("Wardoff could not bound its IPC request read: {error}"))?;
+
+ let result = read_request_until_deadline(pipe);
+ // Valid commands keep the existing reply behavior. Rejections remain nonblocking:
+ // a client that never reads its error reply must not stall the next accept either.
+ if result.is_ok() {
+ let reply_mode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
+ unsafe { SetNamedPipeHandleState(handle, Some(&reply_mode), None, None) }
+ .map_err(|error| format!("Wardoff could not restore its IPC reply mode: {error}"))?;
+ }
+ result
+}
- if bytes_read == 0 {
- return Err("Wardoff received an empty IPC request.".to_string());
+fn read_request_until_deadline(pipe: &mut File) -> Result {
+ let deadline = Instant::now() + REQUEST_READ_TIMEOUT;
+ let mut request_line = Vec::with_capacity(MAX_REQUEST_BYTES);
+ loop {
+ if Instant::now() >= deadline {
+ return Err("Wardoff timed out reading an IPC request.".to_string());
+ }
+
+ let mut buffer = [0; 512];
+ let mut bytes_read = 0;
+ // std::fs::File::read maps ERROR_NO_DATA to EOF on Windows. Preserve that
+ // Win32 result here so an idle connected client really waits for the deadline.
+ let read = unsafe {
+ ReadFile(
+ HANDLE(pipe.as_raw_handle()),
+ Some(&mut buffer),
+ Some(&mut bytes_read),
+ None,
+ )
+ };
+ let error_code = unsafe { GetLastError() };
+ match read {
+ Ok(()) if bytes_read == 0 => {
+ return Err(incomplete_request_error(request_line.is_empty()))
+ }
+ Ok(()) => {
+ let bytes_read = bytes_read as usize;
+ let newline = buffer[..bytes_read].iter().position(|byte| *byte == b'\n');
+ let line_bytes = newline.map_or(bytes_read, |position| position + 1);
+ if request_line.len() + line_bytes > MAX_REQUEST_BYTES {
+ return Err(format!(
+ "Wardoff IPC request exceeds {MAX_REQUEST_BYTES} bytes."
+ ));
+ }
+ request_line.extend_from_slice(&buffer[..line_bytes]);
+ if newline.is_some() {
+ let line = std::str::from_utf8(&request_line)
+ .map_err(|error| format!("Wardoff received malformed IPC JSON: {error}"))?;
+ if line.trim().is_empty() {
+ return Err("Wardoff received an empty IPC request.".to_string());
+ }
+ return serde_json::from_str(line.trim_end())
+ .map_err(|error| format!("Wardoff received malformed IPC JSON: {error}"));
+ }
+ // A full buffer without a newline cannot complete within the frame limit.
+ if request_line.len() == MAX_REQUEST_BYTES {
+ return Err(format!(
+ "Wardoff IPC request exceeds {MAX_REQUEST_BYTES} bytes."
+ ));
+ }
+ }
+ Err(_) if error_code == ERROR_NO_DATA => {
+ // One absolute deadline, not a fresh timeout for every arriving byte.
+ thread::sleep(
+ REQUEST_READ_POLL_DELAY.min(deadline.saturating_duration_since(Instant::now())),
+ );
+ }
+ Err(_) if error_code == ERROR_BROKEN_PIPE => {
+ return Err(incomplete_request_error(request_line.is_empty()));
+ }
+ Err(error) => return Err(format!("Wardoff could not read an IPC request: {error}")),
+ }
}
+}
- serde_json::from_str(request_line.trim_end())
- .map_err(|error| format!("Wardoff received malformed IPC JSON: {error}"))
+fn incomplete_request_error(empty: bool) -> String {
+ if empty {
+ "Wardoff received an empty IPC request.".to_string()
+ } else {
+ "Wardoff received an IPC request without a terminating newline.".to_string()
+ }
}
fn write_response(pipe: &mut File, response: &IpcResponse) -> Result<(), String> {
@@ -1149,8 +1234,7 @@ fn current_process_user_sid_string(control_pipe_path: &str) -> Result std::io::Result<()> {
- let status_pipe_path =
- current_status_pipe_path().map_err(|error| std::io::Error::other(error))?;
+ let status_pipe_path = current_status_pipe_path().map_err(std::io::Error::other)?;
OpenOptions::new()
.read(true)
.open(status_pipe_path)
diff --git a/src/logger/mod.rs b/src/logger/mod.rs
index 0823db1..643de38 100644
--- a/src/logger/mod.rs
+++ b/src/logger/mod.rs
@@ -19,6 +19,8 @@ use windows::Win32::Storage::FileSystem::{
const DEFAULT_LOG_FILE_NAME: &str = "wardoff.jsonl";
const WRITER_THREAD_NAME: &str = "wardoff-structured-logger";
const DEFAULT_TAIL_LINE_COUNT: usize = 20;
+/// Bounds retained line bookkeeping independently of a caller's requested capacity.
+pub(crate) const MAX_TAIL_LINE_COUNT: usize = 100_000;
const MAX_LOG_BYTES: u64 = 5 * 1024 * 1024;
const MAX_LOG_FILES: usize = 3;
@@ -166,13 +168,23 @@ pub(crate) fn default_tail_line_count() -> usize {
/// Reads the newest structured log lines across the retained rotation set.
pub(crate) fn read_recent_lines(limit: usize) -> Result, String> {
+ read_recent_lines_from_path(&default_log_path(), limit)
+}
+
+fn read_recent_lines_from_path(base_path: &Path, limit: usize) -> Result, String> {
+ if limit > MAX_TAIL_LINE_COUNT {
+ return Err(format!(
+ "The --tail value cannot exceed {MAX_TAIL_LINE_COUNT} lines."
+ ));
+ }
+
if limit == 0 {
return Ok(Vec::new());
}
- let mut recent_lines = VecDeque::with_capacity(limit);
+ let mut recent_lines = VecDeque::new();
- for path in log_paths_oldest_to_newest(default_log_path()) {
+ for path in log_paths_oldest_to_newest(base_path) {
if log_file_metadata_if_exists(&path)?.is_none() {
continue;
}
@@ -186,6 +198,13 @@ pub(crate) fn read_recent_lines(limit: usize) -> Result, String> {
if recent_lines.len() == limit {
let _ = recent_lines.pop_front();
+ } else {
+ recent_lines.try_reserve(1).map_err(|error| {
+ format!(
+ "Wardoff could not reserve memory for recent log lines while reading {}: {error}",
+ path.display()
+ )
+ })?;
}
recent_lines.push_back(line);
}
@@ -479,14 +498,14 @@ fn rotated_log_path(base_path: &Path, index: usize) -> PathBuf {
parent.join(format!("{stem}.{index}.{extension}"))
}
-fn log_paths_oldest_to_newest(base_path: PathBuf) -> Vec {
+fn log_paths_oldest_to_newest(base_path: &Path) -> Vec {
let mut paths = Vec::with_capacity(MAX_LOG_FILES);
for index in (1..MAX_LOG_FILES).rev() {
- paths.push(rotated_log_path(&base_path, index));
+ paths.push(rotated_log_path(base_path, index));
}
- paths.push(base_path);
+ paths.push(base_path.to_path_buf());
paths
}
@@ -542,6 +561,67 @@ mod tests {
fs::remove_dir_all(base).unwrap();
}
+ #[test]
+ fn read_recent_lines_rejects_tail_above_limit_before_filesystem_access() {
+ let missing_path = unique_test_root("tail-limit-before-filesystem").join("wardoff.jsonl");
+
+ for limit in [MAX_TAIL_LINE_COUNT + 1, usize::MAX] {
+ let error = read_recent_lines_from_path(&missing_path, limit).unwrap_err();
+ assert!(error.contains("--tail"));
+ assert!(error.contains(&MAX_TAIL_LINE_COUNT.to_string()));
+ }
+ }
+
+ #[test]
+ fn read_recent_lines_zero_returns_empty_without_filesystem_access() {
+ let missing_path = unique_test_root("zero-tail-without-filesystem").join("wardoff.jsonl");
+
+ assert!(read_recent_lines_from_path(&missing_path, 0)
+ .unwrap()
+ .is_empty());
+ }
+
+ #[test]
+ fn read_recent_lines_returns_exact_limit_from_existing_file() {
+ let base = unique_test_root("exact-tail-limit");
+ fs::create_dir_all(&base).unwrap();
+ let log_path = base.join(DEFAULT_LOG_FILE_NAME);
+ fs::write(&log_path, "one\ntwo\nthree\n").unwrap();
+
+ let lines = read_recent_lines_from_path(&log_path, 2).unwrap();
+
+ assert_eq!(lines, ["two", "three"]);
+ assert_eq!(
+ read_recent_lines_from_path(&log_path, MAX_TAIL_LINE_COUNT).unwrap(),
+ ["one", "two", "three"]
+ );
+ fs::remove_dir_all(base).unwrap();
+ }
+
+ #[test]
+ fn read_recent_lines_ignores_absent_files() {
+ let missing_path = unique_test_root("absent-log-files").join(DEFAULT_LOG_FILE_NAME);
+
+ assert!(read_recent_lines_from_path(&missing_path, 20)
+ .unwrap()
+ .is_empty());
+ }
+
+ #[test]
+ fn read_recent_lines_preserves_rotation_order_and_handles_crlf() {
+ let base = unique_test_root("rotation-order");
+ fs::create_dir_all(&base).unwrap();
+ let log_path = base.join(DEFAULT_LOG_FILE_NAME);
+ fs::write(rotated_log_path(&log_path, 2), "one\r\ntwo\r\n").unwrap();
+ fs::write(rotated_log_path(&log_path, 1), "three\r\nfour\r\n").unwrap();
+ fs::write(&log_path, "five\r\nsix\r\n").unwrap();
+
+ let lines = read_recent_lines_from_path(&log_path, 4).unwrap();
+
+ assert_eq!(lines, ["three", "four", "five", "six"]);
+ fs::remove_dir_all(base).unwrap();
+ }
+
fn unique_test_root(name: &str) -> PathBuf {
let unique = SystemTime::now()
.duration_since(UNIX_EPOCH)
diff --git a/src/main.rs b/src/main.rs
index ec30e66..76d3926 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,10 +1,16 @@
+//! Process dispatch and effectful runtime orchestration.
+//!
+//! Start at `run_main` for CLI dispatch, `bootstrap`/`run` for lifecycle, and
+//! `Application` for IPC/tray effects. Pure decisions live in `runtime_policy`.
+//! See docs/DEVELOPMENT.md for task-specific entrypoints and validation.
+
mod autostart;
mod blocker;
mod cli;
-mod config;
mod instance;
mod ipc;
mod logger;
+mod runtime_policy;
mod session_scope;
mod tray;
mod windows_util;
@@ -18,9 +24,14 @@ use crate::instance::{
};
use crate::ipc::{
read_status, send_request, ClientError, IpcRequest, IpcResponse, IpcServer, PendingRequest,
- PipeMode, IPC_WAKE_MESSAGE,
+ IPC_WAKE_MESSAGE,
};
use crate::logger::EventSource;
+use crate::runtime_policy::{
+ ipc_request_for, pending_wake_restore_for_tray_power_action,
+ pending_wake_restore_ready_for_resume, resolved_autostart_state_for_tray, runtime_options_for,
+ PendingWakeRestore, RuntimeOptions, TraySurface,
+};
use crate::tray::{
spawn_tray_service, TrayAction, TrayServiceHandle, TrayVisibility, TRAY_ACTION_WAKE_MESSAGE,
};
@@ -44,6 +55,9 @@ use windows::Win32::UI::WindowsAndMessaging::{
const ELEVATED_RELAUNCH_MUTEX_RETRY_ATTEMPTS: usize = 20;
const ELEVATED_RELAUNCH_MUTEX_RETRY_DELAY: Duration = Duration::from_millis(100);
+// Callback bridge for the Win32 message loop on the application thread. `run`
+// registers it only while its local Application is alive and clears callbacks
+// before ordinary cleanup. Never dereference it from a background worker.
static ACTIVE_APPLICATION: AtomicPtr = AtomicPtr::new(std::ptr::null_mut());
/// Coordinates CLI, tray, and blocker scaffolding for the Wardoff binary.
@@ -58,38 +72,6 @@ struct Application {
_primary_instance: InstanceGuard,
}
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-enum TraySurface {
- Visible,
- Hidden,
- Headless,
-}
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-struct RuntimeOptions {
- initial_mode: BlockerMode,
- tray_surface: TraySurface,
-}
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-enum PendingWakeRestore {
- PendingSuspend(PowerAction),
- WaitingForResume(PowerAction),
-}
-
-impl PendingWakeRestore {
- fn action(self) -> PowerAction {
- match self {
- PendingWakeRestore::PendingSuspend(action)
- | PendingWakeRestore::WaitingForResume(action) => action,
- }
- }
-
- fn mark_system_suspended(self) -> Self {
- PendingWakeRestore::WaitingForResume(self.action())
- }
-}
-
/// Bootstraps logging, the central state manager, and the tray surface.
fn bootstrap(
primary_instance: InstanceGuard,
@@ -157,12 +139,44 @@ fn bootstrap(
Ok(application)
}
+/// Runs an operation and always runs its cleanup, preserving both failures when needed.
+fn run_with_cleanup(
+ state: &mut T,
+ loop_fn: Loop,
+ cleanup_fn: Cleanup,
+) -> Result<(), Box>
+where
+ Loop: FnOnce(&mut T) -> Result<(), Box>,
+ Cleanup: FnOnce(&mut T) -> Result<(), Box>,
+{
+ let loop_result = loop_fn(state);
+ let cleanup_result = cleanup_fn(state);
+
+ match (loop_result, cleanup_result) {
+ (Ok(()), Ok(())) => Ok(()),
+ (Err(loop_error), Ok(())) => Err(loop_error),
+ (Ok(()), Err(cleanup_error)) => Err(cleanup_error),
+ (Err(loop_error), Err(cleanup_error)) => Err(Box::new(other_error(format!(
+ "runtime loop failed: {loop_error}; cleanup failed: {cleanup_error}"
+ )))),
+ }
+}
+
/// Runs the shared Win32 event loop for the hidden Layer 1 windows and the tray icon.
fn run(mut application: Application) -> Result<(), Box> {
ACTIVE_APPLICATION.store(&mut application as *mut Application, Ordering::Release);
blocker::shutdown::set_end_session_cleanup_callback(forced_shutdown_cleanup_callback);
blocker::shutdown::set_power_broadcast_callback(power_broadcast_callback);
+ run_with_cleanup(&mut application, run_message_loop, |application| {
+ blocker::shutdown::clear_end_session_cleanup_callback();
+ blocker::shutdown::clear_power_broadcast_callback();
+ ACTIVE_APPLICATION.store(std::ptr::null_mut(), Ordering::Release);
+ application.shutdown()
+ })
+}
+
+fn run_message_loop(application: &mut Application) -> Result<(), Box> {
let mut message = MSG::default();
'message_loop: loop {
@@ -197,11 +211,6 @@ fn run(mut application: Application) -> Result<(), Box> {
unsafe { WaitMessage()? };
}
-
- blocker::shutdown::clear_end_session_cleanup_callback();
- blocker::shutdown::clear_power_broadcast_callback();
- ACTIVE_APPLICATION.store(std::ptr::null_mut(), Ordering::Release);
- application.shutdown()?;
Ok(())
}
@@ -521,50 +530,6 @@ where
}
}
-fn runtime_options_for(action: RequestedAction) -> RuntimeOptions {
- match action {
- RequestedAction::Default => RuntimeOptions {
- initial_mode: BlockerMode::Block,
- tray_surface: TraySurface::Visible,
- },
- RequestedAction::Block => RuntimeOptions {
- initial_mode: BlockerMode::Block,
- tray_surface: TraySurface::Headless,
- },
- RequestedAction::Allow => RuntimeOptions {
- initial_mode: BlockerMode::Allow,
- tray_surface: TraySurface::Visible,
- },
- RequestedAction::Hide => RuntimeOptions {
- initial_mode: BlockerMode::Block,
- tray_surface: TraySurface::Hidden,
- },
- RequestedAction::Autostart { .. } => {
- unreachable!("autostart changes do not start the primary runtime")
- }
- RequestedAction::Status | RequestedAction::Log { .. } => {
- unreachable!("read-only CLI actions never start the runtime")
- }
- }
-}
-
-fn ipc_request_for(action: RequestedAction) -> IpcRequest {
- match action {
- RequestedAction::Default | RequestedAction::Block | RequestedAction::Hide => {
- IpcRequest::SetMode {
- mode: PipeMode::Block,
- }
- }
- RequestedAction::Allow => IpcRequest::SetMode {
- mode: PipeMode::Allow,
- },
- RequestedAction::Autostart { enabled } => IpcRequest::SetAutostart { enabled },
- RequestedAction::Status | RequestedAction::Log { .. } => {
- unreachable!("read-only CLI actions do not use the control IPC request helper")
- }
- }
-}
-
fn ensure_message_queue() {
let mut message = MSG::default();
let _ = unsafe { PeekMessageW(&mut message, None, 0, 0, PM_NOREMOVE) };
@@ -1252,118 +1217,92 @@ fn runtime_request_label(action: RequestedAction) -> &'static str {
}
}
-fn pending_wake_restore_for_tray_power_action(
- previous_mode: BlockerMode,
- action: PowerAction,
-) -> Option {
- match (previous_mode, action) {
- (BlockerMode::Block, PowerAction::Sleep) => {
- Some(PendingWakeRestore::PendingSuspend(PowerAction::Sleep))
- }
- (BlockerMode::Block, PowerAction::Hibernate) => {
- Some(PendingWakeRestore::PendingSuspend(PowerAction::Hibernate))
- }
- _ => None,
- }
-}
-
-fn pending_wake_restore_ready_for_resume(
- pending_restore: Option,
-) -> Option {
- // Windows can deliver a resume notification to this runtime without an earlier
- // suspend broadcast reaching the hidden window, so any queued tray wake-restore
- // must still restore Block mode on resume even if Wardoff never observed suspend.
- match pending_restore {
- Some(PendingWakeRestore::PendingSuspend(action))
- | Some(PendingWakeRestore::WaitingForResume(action)) => Some(action),
- _ => None,
- }
-}
-
-fn resolved_autostart_state_for_tray(
- previous_state: Option,
- actual_state: Result,
-) -> Result {
- match actual_state {
- Ok(actual_state) => Ok(actual_state),
- Err(error) => previous_state.ok_or(error),
- }
-}
-
#[cfg(test)]
mod tests {
- use super::{
- pending_wake_restore_for_tray_power_action, pending_wake_restore_ready_for_resume,
- resolved_autostart_state_for_tray, BlockerMode, PendingWakeRestore, PowerAction,
- };
+ use super::run_with_cleanup;
+ use std::error::Error;
+ use std::io;
#[test]
- fn prefers_current_autostart_state_when_available() {
- assert_eq!(
- resolved_autostart_state_for_tray(Some(false), Ok(true)),
- Ok(true)
+ fn run_with_cleanup_returns_success_after_normal_loop_and_cleanup() {
+ let mut events = Vec::new();
+
+ let result = run_with_cleanup(
+ &mut events,
+ |events| {
+ events.push("loop");
+ Ok::<(), Box>(())
+ },
+ |events| {
+ events.push("cleanup");
+ Ok::<(), Box>(())
+ },
);
- }
- #[test]
- fn falls_back_to_previous_autostart_state_when_reread_fails() {
- assert_eq!(
- resolved_autostart_state_for_tray(Some(false), Err("read failed".to_string())),
- Ok(false)
- );
+ assert!(result.is_ok());
+ assert_eq!(events, ["loop", "cleanup"]);
}
#[test]
- fn preserves_unknown_autostart_state_when_reads_fail() {
- assert_eq!(
- resolved_autostart_state_for_tray(None, Err("read failed".to_string())),
- Err("read failed".to_string())
+ fn run_with_cleanup_runs_cleanup_after_loop_error() {
+ let mut events = Vec::new();
+
+ let result = run_with_cleanup(
+ &mut events,
+ |events| {
+ events.push("loop");
+ Err::<(), Box>(Box::new(io::Error::other("loop error")))
+ },
+ |events| {
+ events.push("cleanup");
+ Ok::<(), Box>(())
+ },
);
- }
- #[test]
- fn only_block_mode_sleep_and_hibernate_queue_restore_after_wake() {
- assert_eq!(
- pending_wake_restore_for_tray_power_action(BlockerMode::Block, PowerAction::Sleep),
- Some(PendingWakeRestore::PendingSuspend(PowerAction::Sleep))
- );
- assert_eq!(
- pending_wake_restore_for_tray_power_action(BlockerMode::Block, PowerAction::Hibernate),
- Some(PendingWakeRestore::PendingSuspend(PowerAction::Hibernate))
- );
- assert_eq!(
- pending_wake_restore_for_tray_power_action(BlockerMode::Allow, PowerAction::Sleep),
- None
- );
- assert_eq!(
- pending_wake_restore_for_tray_power_action(BlockerMode::Block, PowerAction::Shutdown),
- None
- );
+ assert_eq!(result.unwrap_err().to_string(), "loop error");
+ assert_eq!(events, ["loop", "cleanup"]);
}
#[test]
- fn pending_restore_marks_suspend_and_preserves_requested_action() {
- let pending = PendingWakeRestore::PendingSuspend(PowerAction::Hibernate);
- assert_eq!(
- pending.mark_system_suspended(),
- PendingWakeRestore::WaitingForResume(PowerAction::Hibernate)
+ fn run_with_cleanup_propagates_shutdown_error() {
+ let mut events = Vec::new();
+
+ let result = run_with_cleanup(
+ &mut events,
+ |events| {
+ events.push("loop");
+ Ok::<(), Box>(())
+ },
+ |events| {
+ events.push("shutdown");
+ Err::<(), Box>(Box::new(io::Error::other("shutdown error")))
+ },
);
- assert_eq!(pending.action(), PowerAction::Hibernate);
+
+ assert_eq!(result.unwrap_err().to_string(), "shutdown error");
+ assert_eq!(events, ["loop", "shutdown"]);
}
#[test]
- fn resume_restores_block_mode_even_if_suspend_was_not_observed() {
- assert_eq!(
- pending_wake_restore_ready_for_resume(Some(PendingWakeRestore::PendingSuspend(
- PowerAction::Sleep
- ))),
- Some(PowerAction::Sleep)
+ fn run_with_cleanup_preserves_both_errors_in_order() {
+ let mut events = Vec::new();
+
+ let result = run_with_cleanup(
+ &mut events,
+ |events| {
+ events.push("loop");
+ Err::<(), Box>(Box::new(io::Error::other("loop error")))
+ },
+ |events| {
+ events.push("shutdown");
+ Err::<(), Box>(Box::new(io::Error::other("shutdown error")))
+ },
);
+
assert_eq!(
- pending_wake_restore_ready_for_resume(Some(PendingWakeRestore::WaitingForResume(
- PowerAction::Sleep
- ))),
- Some(PowerAction::Sleep)
+ result.unwrap_err().to_string(),
+ "runtime loop failed: loop error; cleanup failed: shutdown error"
);
+ assert_eq!(events, ["loop", "shutdown"]);
}
}
diff --git a/src/runtime_policy.rs b/src/runtime_policy.rs
new file mode 100644
index 0000000..7fbdf12
--- /dev/null
+++ b/src/runtime_policy.rs
@@ -0,0 +1,280 @@
+//! Pure decisions shared by startup and the running application.
+//!
+//! This module maps CLI intent and tray state without performing Windows effects.
+//! Keep handles, threads, logging and Task Scheduler access in their existing owners.
+
+use crate::blocker::{BlockerMode, PowerAction};
+use crate::cli::RequestedAction;
+use crate::ipc::{IpcRequest, PipeMode};
+
+/// Selects whether startup creates a visible, hidden or absent tray surface.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub(crate) enum TraySurface {
+ /// Creates the normal visible tray icon.
+ Visible,
+ /// Keeps a tray service whose icon starts hidden.
+ Hidden,
+ /// Starts without a tray service.
+ Headless,
+}
+
+/// Describes primary startup without starting a runtime.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub(crate) struct RuntimeOptions {
+ /// Mode to acquire during primary bootstrap.
+ pub(crate) initial_mode: BlockerMode,
+ /// Tray service and initial visibility to create.
+ pub(crate) tray_surface: TraySurface,
+}
+
+/// Tracks a tray suspend request that should restore Block after resume.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub(crate) enum PendingWakeRestore {
+ /// A tray action queued restoration before a suspend notification arrived.
+ PendingSuspend(PowerAction),
+ /// Windows reported suspend; restoration still waits for resume.
+ WaitingForResume(PowerAction),
+}
+
+impl PendingWakeRestore {
+ /// Returns the power action whose Block state should be restored.
+ pub(crate) fn action(self) -> PowerAction {
+ match self {
+ PendingWakeRestore::PendingSuspend(action)
+ | PendingWakeRestore::WaitingForResume(action) => action,
+ }
+ }
+
+ /// Records a suspend notification without changing the requested action.
+ pub(crate) fn mark_system_suspended(self) -> Self {
+ PendingWakeRestore::WaitingForResume(self.action())
+ }
+}
+
+/// Maps runtime-launching actions; read-only and autostart actions must be dispatched earlier.
+pub(crate) fn runtime_options_for(action: RequestedAction) -> RuntimeOptions {
+ match action {
+ RequestedAction::Default => RuntimeOptions {
+ initial_mode: BlockerMode::Block,
+ tray_surface: TraySurface::Visible,
+ },
+ RequestedAction::Block => RuntimeOptions {
+ initial_mode: BlockerMode::Block,
+ tray_surface: TraySurface::Headless,
+ },
+ RequestedAction::Allow => RuntimeOptions {
+ initial_mode: BlockerMode::Allow,
+ tray_surface: TraySurface::Visible,
+ },
+ RequestedAction::Hide => RuntimeOptions {
+ initial_mode: BlockerMode::Block,
+ tray_surface: TraySurface::Hidden,
+ },
+ RequestedAction::Autostart { .. } => {
+ unreachable!("autostart changes do not start the primary runtime")
+ }
+ RequestedAction::Status | RequestedAction::Log { .. } => {
+ unreachable!("read-only CLI actions never start the runtime")
+ }
+ }
+}
+
+/// Maps secondary control actions; read-only actions must be dispatched earlier.
+pub(crate) fn ipc_request_for(action: RequestedAction) -> IpcRequest {
+ match action {
+ RequestedAction::Default | RequestedAction::Block | RequestedAction::Hide => {
+ IpcRequest::SetMode {
+ mode: PipeMode::Block,
+ }
+ }
+ RequestedAction::Allow => IpcRequest::SetMode {
+ mode: PipeMode::Allow,
+ },
+ RequestedAction::Autostart { enabled } => IpcRequest::SetAutostart { enabled },
+ RequestedAction::Status | RequestedAction::Log { .. } => {
+ unreachable!("read-only CLI actions do not use the control IPC request helper")
+ }
+ }
+}
+
+/// Queues wake restoration only when a Block-mode tray action requests suspend.
+pub(crate) fn pending_wake_restore_for_tray_power_action(
+ previous_mode: BlockerMode,
+ action: PowerAction,
+) -> Option {
+ match (previous_mode, action) {
+ (BlockerMode::Block, PowerAction::Sleep) => {
+ Some(PendingWakeRestore::PendingSuspend(PowerAction::Sleep))
+ }
+ (BlockerMode::Block, PowerAction::Hibernate) => {
+ Some(PendingWakeRestore::PendingSuspend(PowerAction::Hibernate))
+ }
+ _ => None,
+ }
+}
+
+/// Accepts resume even if Windows did not deliver the earlier suspend notification.
+pub(crate) fn pending_wake_restore_ready_for_resume(
+ pending_restore: Option,
+) -> Option {
+ // Windows can deliver a resume notification to this runtime without an earlier
+ // suspend broadcast reaching the hidden window, so any queued tray wake-restore
+ // must still restore Block mode on resume even if Wardoff never observed suspend.
+ match pending_restore {
+ Some(PendingWakeRestore::PendingSuspend(action))
+ | Some(PendingWakeRestore::WaitingForResume(action)) => Some(action),
+ _ => None,
+ }
+}
+
+/// Prefers the current task state, retaining the previous checkbox on a read failure.
+pub(crate) fn resolved_autostart_state_for_tray(
+ previous_state: Option,
+ actual_state: Result,
+) -> Result {
+ match actual_state {
+ Ok(actual_state) => Ok(actual_state),
+ Err(error) => previous_state.ok_or(error),
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::{
+ ipc_request_for, pending_wake_restore_for_tray_power_action,
+ pending_wake_restore_ready_for_resume, resolved_autostart_state_for_tray,
+ runtime_options_for, BlockerMode, IpcRequest, PendingWakeRestore, PipeMode, PowerAction,
+ RequestedAction, RuntimeOptions, TraySurface,
+ };
+
+ #[test]
+ fn startup_preserves_visible_hidden_and_headless_modes() {
+ for (action, initial_mode, tray_surface) in [
+ (
+ RequestedAction::Default,
+ BlockerMode::Block,
+ TraySurface::Visible,
+ ),
+ (
+ RequestedAction::Block,
+ BlockerMode::Block,
+ TraySurface::Headless,
+ ),
+ (
+ RequestedAction::Allow,
+ BlockerMode::Allow,
+ TraySurface::Visible,
+ ),
+ (
+ RequestedAction::Hide,
+ BlockerMode::Block,
+ TraySurface::Hidden,
+ ),
+ ] {
+ assert_eq!(
+ runtime_options_for(action),
+ RuntimeOptions {
+ initial_mode,
+ tray_surface
+ }
+ );
+ }
+ }
+
+ #[test]
+ fn secondary_commands_preserve_control_protocol_mapping() {
+ for action in [
+ RequestedAction::Default,
+ RequestedAction::Block,
+ RequestedAction::Hide,
+ ] {
+ assert!(matches!(
+ ipc_request_for(action),
+ IpcRequest::SetMode {
+ mode: PipeMode::Block
+ }
+ ));
+ }
+ assert!(matches!(
+ ipc_request_for(RequestedAction::Allow),
+ IpcRequest::SetMode {
+ mode: PipeMode::Allow
+ }
+ ));
+ for enabled in [false, true] {
+ assert!(
+ matches!(ipc_request_for(RequestedAction::Autostart { enabled }), IpcRequest::SetAutostart { enabled: actual } if actual == enabled)
+ );
+ }
+ }
+
+ #[test]
+ fn prefers_current_autostart_state_when_available() {
+ assert_eq!(
+ resolved_autostart_state_for_tray(Some(false), Ok(true)),
+ Ok(true)
+ );
+ }
+
+ #[test]
+ fn falls_back_to_previous_autostart_state_when_reread_fails() {
+ assert_eq!(
+ resolved_autostart_state_for_tray(Some(false), Err("read failed".to_string())),
+ Ok(false)
+ );
+ }
+
+ #[test]
+ fn preserves_unknown_autostart_state_when_reads_fail() {
+ assert_eq!(
+ resolved_autostart_state_for_tray(None, Err("read failed".to_string())),
+ Err("read failed".to_string())
+ );
+ }
+
+ #[test]
+ fn only_block_mode_sleep_and_hibernate_queue_restore_after_wake() {
+ assert_eq!(
+ pending_wake_restore_for_tray_power_action(BlockerMode::Block, PowerAction::Sleep),
+ Some(PendingWakeRestore::PendingSuspend(PowerAction::Sleep))
+ );
+ assert_eq!(
+ pending_wake_restore_for_tray_power_action(BlockerMode::Block, PowerAction::Hibernate),
+ Some(PendingWakeRestore::PendingSuspend(PowerAction::Hibernate))
+ );
+ assert_eq!(
+ pending_wake_restore_for_tray_power_action(BlockerMode::Allow, PowerAction::Sleep),
+ None
+ );
+ assert_eq!(
+ pending_wake_restore_for_tray_power_action(BlockerMode::Block, PowerAction::Shutdown),
+ None
+ );
+ }
+
+ #[test]
+ fn pending_restore_marks_suspend_and_preserves_requested_action() {
+ let pending = PendingWakeRestore::PendingSuspend(PowerAction::Hibernate);
+ assert_eq!(
+ pending.mark_system_suspended(),
+ PendingWakeRestore::WaitingForResume(PowerAction::Hibernate)
+ );
+ assert_eq!(pending.action(), PowerAction::Hibernate);
+ }
+
+ #[test]
+ fn resume_restores_block_mode_even_if_suspend_was_not_observed() {
+ assert_eq!(
+ pending_wake_restore_ready_for_resume(Some(PendingWakeRestore::PendingSuspend(
+ PowerAction::Sleep
+ ))),
+ Some(PowerAction::Sleep)
+ );
+ assert_eq!(
+ pending_wake_restore_ready_for_resume(Some(PendingWakeRestore::WaitingForResume(
+ PowerAction::Sleep
+ ))),
+ Some(PowerAction::Sleep)
+ );
+ }
+}
diff --git a/tests/developer_checks.ps1 b/tests/developer_checks.ps1
new file mode 100644
index 0000000..a7eff92
--- /dev/null
+++ b/tests/developer_checks.ps1
@@ -0,0 +1,155 @@
+[CmdletBinding()]
+param()
+
+$ErrorActionPreference = 'Stop'
+$checker = Join-Path $PSScriptRoot '..\scripts\check-docs.ps1'
+$entrypoint = Join-Path $PSScriptRoot '..\scripts\check.ps1'
+$fixtureRoot = Join-Path ([IO.Path]::GetTempPath()) ('wardoff-doc-check-' + [Guid]::NewGuid().ToString('N'))
+
+function Invoke-FixtureChecker {
+ param([switch]$ExpectFailure)
+
+ $previousErrorAction = $ErrorActionPreference
+ $ErrorActionPreference = 'Continue'
+ try {
+ $result = & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $checker -RepoRoot $fixtureRoot 2>&1
+ } finally {
+ $ErrorActionPreference = $previousErrorAction
+ }
+ $code = $LASTEXITCODE
+ if ($ExpectFailure) {
+ if ($code -eq 0) { throw "Expected checker failure, but it succeeded.`n$($result -join [Environment]::NewLine)" }
+ } elseif ($code -ne 0) {
+ throw "Expected checker success, exit code $code.`n$($result -join [Environment]::NewLine)"
+ }
+ return ($result -join [Environment]::NewLine)
+}
+
+function Assert-Contains {
+ param([string]$Text, [string]$Expected)
+ if ($Text.IndexOf($Expected, [StringComparison]::OrdinalIgnoreCase) -lt 0) {
+ throw "Expected output to contain '$Expected'.`n$Text"
+ }
+}
+
+function Invoke-Entrypoint {
+ param(
+ [ValidateSet('Docs', 'Full')]
+ [string]$Mode,
+ [switch]$ExpectFailure
+ )
+ $previousErrorAction = $ErrorActionPreference
+ $ErrorActionPreference = 'Continue'
+ try {
+ $result = & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $entrypoint -Mode $Mode 2>&1
+ } finally {
+ $ErrorActionPreference = $previousErrorAction
+ }
+ $code = $LASTEXITCODE
+ if ($ExpectFailure -and $code -eq 0) { throw "Expected $Mode entrypoint failure, but it succeeded." }
+ if (-not $ExpectFailure -and $code -ne 0) { throw "Expected $Mode entrypoint success, exit code $code.`n$($result -join [Environment]::NewLine)" }
+ return ($result -join [Environment]::NewLine)
+}
+
+try {
+ New-Item -ItemType Directory -Path $fixtureRoot -Force | Out-Null
+ Push-Location $fixtureRoot
+ git init --quiet
+ Set-Content -LiteralPath (Join-Path $fixtureRoot 'README.md') -Encoding utf8 -Value @'
+# Fixture
+
+[existing](docs/guide%20file.md)
+[reference][guide]
+[remote](https://example.invalid/no-file)
+[anchor](#section)
+`[inline-code](missing-inline.md)`
+
+````text
+[fenced-code](missing-fenced.md)
+```
+[still-fenced](missing-fenced-2.md)
+````
+
+[guide]: "optional title"
+[bare]: docs/guide%20file.md "optional title"
+'@
+ New-Item -ItemType Directory -Path (Join-Path $fixtureRoot 'docs') | Out-Null
+ Set-Content -LiteralPath (Join-Path $fixtureRoot 'docs\guide file.md') -Encoding utf8 -Value '# Guide'
+ # Keep the fixture name independent of Windows PowerShell source decoding.
+ $unicodePath = 'docs/n' + [char]0x00F6 + 'tes.md'
+ Set-Content -LiteralPath (Join-Path $fixtureRoot $unicodePath) -Encoding utf8 -Value '# Notes'
+ Set-Content -LiteralPath (Join-Path $fixtureRoot 'ignored.md') -Encoding utf8 -Value '[missing](nope.md)'
+ Add-Content -LiteralPath (Join-Path $fixtureRoot '.gitignore') -Encoding utf8 -Value 'ignored.md'
+ git add README.md 'docs/guide file.md' $unicodePath .gitignore
+
+ $success = Invoke-FixtureChecker
+ Assert-Contains $success 'Documentation checks passed'
+
+ $cargoPath = Join-Path $fixtureRoot 'cargo.cmd'
+ $cargoTrace = Join-Path $fixtureRoot 'cargo-trace.txt'
+ Set-Content -LiteralPath $cargoPath -Encoding ascii -Value '@echo off', 'echo %*>>"%~dp0cargo-trace.txt"', 'exit /b 7'
+ $oldPath = $env:PATH
+ try {
+ $env:PATH = $fixtureRoot + ';' + $oldPath
+ $docsEntry = Invoke-Entrypoint -Mode Docs
+ Assert-Contains $docsEntry 'Documentation checks completed.'
+ if (Test-Path -LiteralPath $cargoTrace) { throw 'Docs mode unexpectedly invoked Cargo.' }
+ $fullEntry = Invoke-Entrypoint -Mode Full -ExpectFailure
+ Assert-Contains $fullEntry 'cargo fmt --all -- --check failed'
+ $trace = Get-Content -LiteralPath $cargoTrace -Raw
+ Assert-Contains $trace 'fmt --all -- --check'
+ if ($trace -match '(?:^|\s)(?:check|test|clippy|build)(?:\s|$)') { throw "Full mode ran steps after the first failure: $trace" }
+ } finally {
+ $env:PATH = $oldPath
+ }
+ Remove-Item -LiteralPath $cargoPath, $cargoTrace -Force -ErrorAction SilentlyContinue
+
+ Set-Content -LiteralPath (Join-Path $fixtureRoot 'untracked.md') -Encoding utf8 -Value '[missing](untracked-target.md)'
+ $untrackedFailure = Invoke-FixtureChecker -ExpectFailure
+ Assert-Contains $untrackedFailure 'untracked.md:1'
+
+ Remove-Item -LiteralPath (Join-Path $fixtureRoot 'untracked.md')
+ Set-Content -LiteralPath (Join-Path $fixtureRoot 'broken.md') -Encoding utf8 -Value '[missing](does-not-exist.md)'
+ $brokenFailure = Invoke-FixtureChecker -ExpectFailure
+ Assert-Contains $brokenFailure 'broken.md:1'
+ Assert-Contains $brokenFailure 'does-not-exist.md'
+
+ Remove-Item -LiteralPath (Join-Path $fixtureRoot 'broken.md')
+ Set-Content -LiteralPath (Join-Path $fixtureRoot 'broken-reference.md') -Encoding utf8 -Value @'
+[reference][missing]
+
+[missing]: missing-reference.md
+'@
+ $brokenReferenceFailure = Invoke-FixtureChecker -ExpectFailure
+ Assert-Contains $brokenReferenceFailure 'broken-reference.md:3'
+ Assert-Contains $brokenReferenceFailure 'missing-reference.md'
+
+ Remove-Item -LiteralPath (Join-Path $fixtureRoot 'broken-reference.md')
+ $invalidPath = Join-Path $fixtureRoot 'invalid.md'
+ [IO.File]::WriteAllBytes($invalidPath, [byte[]](0x23, 0x20, 0xC3, 0x28))
+ $invalidFailure = Invoke-FixtureChecker -ExpectFailure
+ Assert-Contains $invalidFailure 'invalid.md'
+ Assert-Contains $invalidFailure 'UTF-8'
+
+ Remove-Item -LiteralPath $invalidPath
+ $nulPath = Join-Path $fixtureRoot 'nul.md'
+ [IO.File]::WriteAllBytes($nulPath, [byte[]](0x23, 0x20, 0x41, 0x00, 0x42))
+ $nulFailure = Invoke-FixtureChecker -ExpectFailure
+ Assert-Contains $nulFailure 'nul.md'
+ Assert-Contains $nulFailure 'NUL'
+
+ Write-Output 'Developer checks tests passed.'
+} finally {
+ Pop-Location -ErrorAction SilentlyContinue
+ $resolvedFixture = $null
+ if (Test-Path -LiteralPath $fixtureRoot) {
+ $resolvedFixture = (Resolve-Path -LiteralPath $fixtureRoot).Path
+ }
+ $tempRoot = [IO.Path]::GetFullPath([IO.Path]::GetTempPath()).TrimEnd('\')
+ $fixtureName = Split-Path -Leaf $resolvedFixture
+ if ($resolvedFixture -and $resolvedFixture.StartsWith($tempRoot + '\', [StringComparison]::OrdinalIgnoreCase) -and
+ $fixtureName.StartsWith('wardoff-doc-check-', [StringComparison]::OrdinalIgnoreCase)) {
+ Remove-Item -LiteralPath $fixtureRoot -Recurse -Force
+ }
+}
+exit 0
diff --git a/tests/ipc_request_limits.rs b/tests/ipc_request_limits.rs
new file mode 100644
index 0000000..9673166
--- /dev/null
+++ b/tests/ipc_request_limits.rs
@@ -0,0 +1,358 @@
+//! Runs the production IPC server on process-unique pipes with an inert UI consumer.
+//! No blocker, autostart, singleton, logger, or production endpoint is started.
+#![allow(dead_code)]
+
+use std::fs::{File, OpenOptions};
+use std::io::{Read, Write};
+use std::os::windows::io::AsRawHandle;
+use std::sync::mpsc;
+use std::sync::{
+ atomic::{AtomicUsize, Ordering},
+ Arc,
+};
+use std::thread::{self, JoinHandle};
+use std::time::{Duration, Instant};
+use windows::Win32::Foundation::HANDLE;
+use windows::Win32::System::Pipes::PeekNamedPipe;
+use windows::Win32::System::Threading::GetCurrentThreadId;
+use windows::Win32::UI::WindowsAndMessaging::{PeekMessageW, MSG, PM_NOREMOVE};
+
+mod blocker {
+ pub(crate) enum BlockerMode {
+ Block,
+ Allow,
+ }
+}
+
+mod cli {
+ #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
+ pub(crate) struct StatusOutput {
+ pub(crate) state: String,
+ }
+
+ impl StatusOutput {
+ pub(crate) fn to_json(&self) -> Result {
+ serde_json::to_string(self)
+ }
+ }
+}
+
+mod logger {
+ pub(crate) enum EventSource {
+ Ipc,
+ }
+
+ pub(crate) fn log_event(_: &str, _: EventSource, _: impl Into, _: bool) {}
+}
+
+mod session_scope {
+ pub(crate) fn current_control_pipe_path() -> Result {
+ Ok(format!(
+ r"\\.\pipe\WardoffIpcTest-Control-{}",
+ std::process::id()
+ ))
+ }
+
+ pub(crate) fn current_status_pipe_path() -> Result {
+ Ok(format!(
+ r"\\.\pipe\WardoffIpcTest-Status-{}",
+ std::process::id()
+ ))
+ }
+}
+
+#[path = "../src/ipc.rs"]
+mod ipc;
+
+struct TestRuntime {
+ server: ipc::IpcServer,
+ ui_thread: Option>,
+ dispatched: Arc,
+}
+
+impl TestRuntime {
+ fn start() -> Self {
+ let (request_tx, request_rx) = mpsc::channel::();
+ let (ready_tx, ready_rx) = mpsc::channel();
+ let dispatched = Arc::new(AtomicUsize::new(0));
+ let ui_dispatched = Arc::clone(&dispatched);
+ let ui_thread = thread::spawn(move || {
+ // PostThreadMessageW requires the target thread to own a message queue.
+ let mut message = MSG::default();
+ unsafe {
+ let _ = PeekMessageW(&mut message, None, 0, 0, PM_NOREMOVE);
+ }
+ ready_tx
+ .send(unsafe { GetCurrentThreadId() })
+ .expect("UI ready");
+ for pending in request_rx {
+ ui_dispatched.fetch_add(1, Ordering::SeqCst);
+ let response = match pending.request {
+ ipc::IpcRequest::Status => ipc::IpcResponse::Status {
+ status: cli::StatusOutput {
+ state: "inert".into(),
+ },
+ },
+ _ => ipc::IpcResponse::Ok,
+ };
+ let _ = pending.response_tx.send(response);
+ }
+ });
+ let server = ipc::IpcServer::start(request_tx, ready_rx.recv().expect("UI thread ID"))
+ .expect("isolated IPC startup");
+ Self {
+ server,
+ ui_thread: Some(ui_thread),
+ dispatched,
+ }
+ }
+
+ fn stop(&mut self) {
+ self.server.shutdown().expect("clean IPC shutdown");
+ if let Some(ui_thread) = self.ui_thread.take() {
+ ui_thread.join().expect("inert UI joined");
+ }
+ }
+}
+
+impl Drop for TestRuntime {
+ fn drop(&mut self) {
+ self.stop();
+ }
+}
+
+fn open_pipe(status: bool) -> File {
+ let path = if status {
+ session_scope::current_status_pipe_path()
+ } else {
+ session_scope::current_control_pipe_path()
+ }
+ .expect("isolated path");
+ let deadline = Instant::now() + Duration::from_secs(3);
+ loop {
+ match OpenOptions::new().read(true).write(!status).open(&path) {
+ Ok(pipe) => return pipe,
+ Err(error) if Instant::now() >= deadline => panic!("connect {path}: {error}"),
+ Err(_) => thread::sleep(Duration::from_millis(10)),
+ }
+ }
+}
+
+fn read_line_with_deadline(pipe: &mut File) -> Result {
+ let deadline = Instant::now() + Duration::from_secs(2);
+ let mut reply = Vec::new();
+ loop {
+ let mut buffer = [0; 512];
+ let mut available = 0;
+ // This test client is the sole reader, so observed bytes cannot be consumed elsewhere.
+ unsafe {
+ PeekNamedPipe(
+ HANDLE(pipe.as_raw_handle()),
+ None,
+ 0,
+ None,
+ Some(&mut available),
+ None,
+ )
+ }
+ .map_err(|error| error.to_string())?;
+ let to_read = buffer.len().min(available as usize);
+ if to_read != 0 {
+ match pipe.read(&mut buffer[..to_read]) {
+ Ok(0) => return Err("server disconnected before replying".into()),
+ Ok(size) => {
+ reply.extend_from_slice(&buffer[..size]);
+ if reply.contains(&b'\n') {
+ return String::from_utf8(reply).map_err(|error| error.to_string());
+ }
+ }
+ Err(error) => return Err(error.to_string()),
+ }
+ }
+ if Instant::now() >= deadline {
+ return Err("test client received no reply within 2 seconds".into());
+ }
+ thread::sleep(Duration::from_millis(10));
+ }
+}
+
+fn exchange(payload: &[u8]) -> Result {
+ let mut pipe = open_pipe(false);
+ // Match send_request's separate JSON and newline pipe messages.
+ if let Some(json) = payload.strip_suffix(b"\n") {
+ pipe.write_all(json).map_err(|error| error.to_string())?;
+ pipe.write_all(b"\n").map_err(|error| error.to_string())?;
+ } else {
+ pipe.write_all(payload).map_err(|error| error.to_string())?;
+ }
+ serde_json::from_str(&read_line_with_deadline(&mut pipe)?).map_err(|error| error.to_string())
+}
+
+fn assert_normal_command() {
+ assert!(matches!(
+ exchange(b"{\"command\":\"set_mode\",\"mode\":\"allow\"}\n"),
+ Ok(ipc::IpcResponse::Ok)
+ ));
+}
+
+fn assert_error(payload: &[u8], expected: &str) {
+ let reply = exchange(payload).expect("error response");
+ assert!(matches!(reply, ipc::IpcResponse::Error { message } if message.contains(expected)));
+ assert_normal_command();
+}
+
+#[test]
+fn isolated_runtime_rejects_bad_clients_and_recovers() {
+ let mut runtime = TestRuntime::start();
+ assert_normal_command();
+ assert!(matches!(
+ exchange(b"{\"command\":\"set_mode\",\"mode\":\"block\"}\r\n"),
+ Ok(ipc::IpcResponse::Ok)
+ ));
+
+ // A rejected client may keep its handle open and refuse to read the error.
+ // The unknown variant diagnostic can be larger than the outbound pipe buffer.
+ let mut unread = open_pipe(false);
+ let command = "x".repeat(4070);
+ let payload = format!("{{\"command\":\"{command}\"}}\n");
+ unread
+ .write_all(payload.as_bytes())
+ .expect("large malformed write");
+ assert_normal_command();
+ drop(unread);
+ for (payload, expected) in [
+ (&b"not JSON\n"[..], "malformed"),
+ (&b"\n"[..], "empty"),
+ (&b"{\"command\":\"unknown\"}\n"[..], "malformed"),
+ (&b"\xff\n"[..], "malformed"),
+ ] {
+ assert_error(payload, expected);
+ }
+
+ // The cap counts wire bytes including LF, regardless of JSON whitespace or message size.
+ let mut boundary = b"{\"command\":\"status\"}".to_vec();
+ boundary.resize(4095, b' ');
+ boundary.push(b'\n');
+ assert!(matches!(
+ exchange(&boundary),
+ Ok(ipc::IpcResponse::Status { .. })
+ ));
+ assert_normal_command();
+ boundary.insert(boundary.len() - 1, b' ');
+ assert_error(&boundary, "exceeds 4096 bytes");
+ assert_error(&vec![b' '; 4097], "exceeds 4096 bytes");
+
+ // Small individual messages must not bypass the cumulative frame cap.
+ let mut oversized = open_pipe(false);
+ for _ in 0..9 {
+ let _ = oversized.write_all(&[b' '; 512]);
+ }
+ let reply = read_line_with_deadline(&mut oversized).expect("fragmented oversized reply");
+ drop(oversized);
+ assert!(reply.contains("exceeds 4096 bytes"));
+ assert_normal_command();
+
+ // EOF never turns an unterminated control command into an accepted request.
+ for payload in [
+ &b""[..],
+ &b"{\"command\":\"set_mode\",\"mode\":\"allow\"}"[..],
+ ] {
+ let before = runtime.dispatched.load(Ordering::SeqCst);
+ let mut disconnected = open_pipe(false);
+ disconnected
+ .write_all(payload)
+ .expect("write before disconnect");
+ drop(disconnected);
+ assert_normal_command();
+ assert_eq!(runtime.dispatched.load(Ordering::SeqCst), before + 1);
+ }
+
+ // A syntactically valid request without its newline must expire while open.
+ let started = Instant::now();
+ let mut stalled = open_pipe(false);
+ stalled
+ .write_all(b"{\"command\":\"status\"}")
+ .expect("partial write");
+ let status_started = Instant::now();
+ let mut status_pipe = open_pipe(true);
+ let status = read_line_with_deadline(&mut status_pipe).expect("independent status response");
+ let status_elapsed = status_started.elapsed();
+ assert!(
+ status_elapsed < Duration::from_millis(500),
+ "status waited {status_elapsed:?}"
+ );
+ eprintln!("status during incomplete request: {status_elapsed:?}");
+ assert_eq!(
+ serde_json::from_str::(&status).expect("status JSON")["state"],
+ "inert"
+ );
+ drop(status_pipe);
+ let reply = read_line_with_deadline(&mut stalled);
+ drop(stalled); // Unblocks the original reader too, even if this assertion fails.
+ assert!(
+ matches!(reply.as_ref().ok().and_then(|line| serde_json::from_str::(line).ok()), Some(ipc::IpcResponse::Error { message }) if message.contains("timed out")),
+ "{reply:?}"
+ );
+ let partial_elapsed = started.elapsed();
+ assert!(partial_elapsed >= Duration::from_millis(800));
+ assert!(partial_elapsed < Duration::from_millis(1500));
+ eprintln!("unterminated request rejected: {partial_elapsed:?}");
+ assert_normal_command();
+
+ // A client sending nothing also expires; another queued client then succeeds.
+ let mut silent = open_pipe(false);
+ let normal = thread::spawn(assert_normal_command);
+ let reply = read_line_with_deadline(&mut silent).expect("silent timeout reply");
+ drop(silent);
+ assert!(reply.contains("timed out"));
+ normal
+ .join()
+ .expect("normal client recovered after timeout");
+
+ // Trickle traffic must not reset the absolute deadline.
+ let mut slow = open_pipe(false);
+ let mut slow_writer = slow.try_clone().expect("slow writer handle");
+ let started = Instant::now();
+ let writer = thread::spawn(move || {
+ for _ in 0..20 {
+ if slow_writer.write_all(b" ").is_err() {
+ break;
+ }
+ thread::sleep(Duration::from_millis(80));
+ }
+ });
+ let reply = read_line_with_deadline(&mut slow);
+ drop(slow);
+ let elapsed = started.elapsed();
+ writer.join().expect("slow writer joined");
+ assert!(reply.expect("trickle timeout reply").contains("timed out"));
+ assert!(elapsed < Duration::from_millis(1500));
+ assert!(elapsed >= Duration::from_millis(800));
+ eprintln!("trickle request rejected: {elapsed:?}");
+ assert_normal_command();
+
+ // Clean shutdown must still finish when the current control client is incomplete.
+ let mut shutdown_stall = open_pipe(false);
+ shutdown_stall
+ .write_all(b"{")
+ .expect("shutdown partial write");
+ let (stopped_tx, stopped_rx) = mpsc::channel();
+ let shutdown = thread::spawn(move || {
+ runtime.stop();
+ stopped_tx.send(()).expect("shutdown result");
+ });
+ let stopped = stopped_rx.recv_timeout(Duration::from_secs(2));
+ drop(shutdown_stall);
+ shutdown.join().expect("shutdown joined");
+ stopped.expect("shutdown completed despite incomplete client");
+ // Both owned endpoints are gone after orderly shutdown.
+ for path in [
+ session_scope::current_control_pipe_path(),
+ session_scope::current_status_pipe_path(),
+ ] {
+ assert!(OpenOptions::new()
+ .read(true)
+ .open(path.expect("test path"))
+ .is_err());
+ }
+}
diff --git a/tests/log_tail_cli.rs b/tests/log_tail_cli.rs
new file mode 100644
index 0000000..5cedb88
--- /dev/null
+++ b/tests/log_tail_cli.rs
@@ -0,0 +1,124 @@
+#![cfg(windows)]
+
+use std::fs;
+use std::path::PathBuf;
+use std::process::{Command, Output};
+use std::time::{SystemTime, UNIX_EPOCH};
+
+struct TempFixture {
+ root: PathBuf,
+}
+
+impl TempFixture {
+ fn new(name: &str) -> Self {
+ let unique = SystemTime::now()
+ .duration_since(UNIX_EPOCH)
+ .expect("system clock should be after the Unix epoch")
+ .as_nanos();
+ let root = std::env::temp_dir().join(format!("wardoff-log-tail-{name}-{unique}"));
+ fs::create_dir_all(root.join("Wardoff").join("logs")).expect("create log fixture root");
+ Self { root }
+ }
+
+ fn log_path(&self) -> PathBuf {
+ self.root.join("Wardoff").join("logs").join("wardoff.jsonl")
+ }
+
+ fn write_log(&self, name: &str, contents: &str) {
+ let path = if name == "wardoff.jsonl" {
+ self.log_path()
+ } else {
+ self.log_path()
+ .parent()
+ .expect("log path should have a parent")
+ .join(name)
+ };
+ fs::write(path, contents).expect("write log fixture");
+ }
+}
+
+impl Drop for TempFixture {
+ fn drop(&mut self) {
+ let _ = fs::remove_dir_all(&self.root);
+ }
+}
+
+fn run_cli(fixture: &TempFixture, args: &[&str]) -> Output {
+ Command::new(env!("CARGO_BIN_EXE_wardoff"))
+ .args(args)
+ .env("LOCALAPPDATA", &fixture.root)
+ .output()
+ .expect("run Wardoff CLI")
+}
+
+fn lines(contents: impl IntoIterator- ) -> String {
+ contents
+ .into_iter()
+ .map(|line| format!("{line}\r\n"))
+ .collect()
+}
+
+#[test]
+fn tail_above_limit_exits_one_without_panicking() {
+ let fixture = TempFixture::new("invalid");
+
+ for value in [usize::MAX.to_string(), "100001".to_string()] {
+ let output = run_cli(&fixture, &["--log", "--tail", &value]);
+
+ assert_eq!(output.status.code(), Some(1));
+ assert!(String::from_utf8_lossy(&output.stderr).contains("--tail"));
+ assert!(String::from_utf8_lossy(&output.stderr).contains("100000"));
+ assert!(!String::from_utf8_lossy(&output.stderr).contains("panicked"));
+ }
+}
+
+#[test]
+fn zero_tail_succeeds_with_empty_output() {
+ let fixture = TempFixture::new("zero");
+
+ let output = run_cli(&fixture, &["--log", "--tail", "0"]);
+
+ assert_eq!(output.status.code(), Some(0));
+ assert!(output.stdout.is_empty());
+}
+
+#[test]
+fn tail_limit_and_default_tail_return_expected_records() {
+ let all_fixture = TempFixture::new("limit");
+ all_fixture.write_log(
+ "wardoff.jsonl",
+ &lines((1..=3).map(|index| format!("record-{index}"))),
+ );
+
+ let all = run_cli(&all_fixture, &["--log", "--tail", "100000"]);
+ assert_eq!(all.status.code(), Some(0));
+ assert_eq!(String::from_utf8_lossy(&all.stdout).lines().count(), 3);
+
+ let default_fixture = TempFixture::new("default");
+ default_fixture.write_log(
+ "wardoff.jsonl",
+ &lines((1..=25).map(|index| format!("record-{index}"))),
+ );
+ let default = run_cli(&default_fixture, &["--log"]);
+ assert_eq!(default.status.code(), Some(0));
+ let default_output = String::from_utf8_lossy(&default.stdout);
+ let default_lines: Vec<_> = default_output.lines().collect();
+ assert_eq!(default_lines.len(), 20);
+ assert_eq!(default_lines[0], "record-6");
+ assert_eq!(default_lines[19], "record-25");
+}
+
+#[test]
+fn rotated_crlf_logs_are_returned_in_chronological_order() {
+ let fixture = TempFixture::new("rotation");
+ fixture.write_log("wardoff.2.jsonl", &lines(["old-1".into(), "old-2".into()]));
+ fixture.write_log("wardoff.1.jsonl", &lines(["mid-1".into(), "mid-2".into()]));
+ fixture.write_log("wardoff.jsonl", &lines(["new-1".into(), "new-2".into()]));
+
+ let output = run_cli(&fixture, &["--log", "--tail", "4"]);
+
+ assert_eq!(output.status.code(), Some(0));
+ let output_text = String::from_utf8_lossy(&output.stdout);
+ let output_lines: Vec<_> = output_text.lines().collect();
+ assert_eq!(output_lines, ["mid-1", "mid-2", "new-1", "new-2"]);
+}
diff --git a/tests/release_guards.ps1 b/tests/release_guards.ps1
new file mode 100644
index 0000000..20cd0f2
--- /dev/null
+++ b/tests/release_guards.ps1
@@ -0,0 +1,561 @@
+[CmdletBinding()]
+param()
+
+$ErrorActionPreference = 'Stop'
+$guardPath = Join-Path $PSScriptRoot '..\scripts\release-guard.ps1'
+$fixtureRoot = Join-Path ([IO.Path]::GetTempPath()) ('wardoff-release-guard-' + [Guid]::NewGuid().ToString('N'))
+$repoFixture = Join-Path $fixtureRoot 'repo'
+$packageFixture = Join-Path $fixtureRoot 'package'
+$repository = 'RomainROCH/Wardoff'
+$candidateCommit = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+$otherCommit = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
+$tagName = 'v0.2.1'
+$script:caseCount = 0
+
+function Assert-True {
+ param([bool]$Condition, [string]$Message)
+ if (-not $Condition) { throw $Message }
+}
+
+function Assert-Equal {
+ param($Actual, $Expected, [string]$Message)
+ if ($Actual -cne $Expected) { throw "$Message Expected '$Expected', received '$Actual'." }
+}
+
+function Assert-Throws {
+ param([scriptblock]$Action)
+ $caught = $false
+ try { & $Action | Out-Null } catch { $caught = $true }
+ if (-not $caught) { throw 'Expected the release guard to reject the fixture.' }
+}
+
+function Invoke-TestCase {
+ param([string]$Name, [scriptblock]$Action)
+ try { & $Action } catch { throw "Release guard test failed [$Name]: $($_.Exception.Message)" }
+ $script:caseCount++
+}
+
+function Write-VersionFixture {
+ param(
+ [string]$TomlVersion = '0.2.1',
+ [string]$LockVersion = '0.2.1',
+ [string]$ManifestVersion = '0.2.1.0',
+ [string]$Level = 'asInvoker',
+ [string]$UiAccess = 'false',
+ [string]$PackageName = 'wardoff',
+ [string]$LockPackageName = 'wardoff'
+ )
+ New-Item -ItemType Directory -Path $repoFixture -Force | Out-Null
+ Set-Content -LiteralPath (Join-Path $repoFixture 'Cargo.toml') -Encoding utf8 -Value @"
+[package]
+name = "$PackageName"
+version = "$TomlVersion"
+edition = "2021"
+
+[dependencies]
+some_dependency = "9.8.7"
+"@
+ Set-Content -LiteralPath (Join-Path $repoFixture 'Cargo.lock') -Encoding utf8 -Value @"
+version = 4
+
+[[package]]
+name = "some_dependency"
+version = "9.8.7"
+
+[[package]]
+name = "$LockPackageName"
+version = "$LockVersion"
+dependencies = ["some_dependency"]
+"@
+ Set-Content -LiteralPath (Join-Path $repoFixture 'wardoff.manifest') -Encoding utf8 -Value @"
+
+
+
+
+
+
+
+"@
+}
+
+function New-CiRun {
+ param(
+ [long]$Id = 73,
+ [string]$Commit = $candidateCommit,
+ [string]$Branch = 'main',
+ [string]$Event = 'push',
+ [string]$Path = '.github/workflows/ci.yml',
+ [string]$RepositoryName = $repository,
+ [string]$Status = 'completed',
+ [string]$Conclusion = 'success',
+ [int]$Attempt = 1,
+ [string]$UpdatedAt
+ )
+ if (-not $PSBoundParameters.ContainsKey('UpdatedAt')) {
+ $UpdatedAt = [datetime]::new(2026, 1, 1, 0, 0, 0, [DateTimeKind]::Utc).AddSeconds($Id).ToString('yyyy-MM-ddTHH:mm:ssZ', [Globalization.CultureInfo]::InvariantCulture)
+ }
+ return [pscustomobject]@{
+ id = $Id; head_sha = $Commit; head_branch = $Branch; event = $Event
+ path = $Path; head_repository = [pscustomobject]@{ full_name = $RepositoryName }
+ status = $Status; conclusion = $Conclusion; run_attempt = $Attempt; updated_at = $UpdatedAt
+ }
+}
+
+function New-WindowsVersionInfo {
+ param([string]$DisplayVersion = '0.2.1')
+ return [pscustomobject]@{
+ FileVersion = $DisplayVersion
+ FileMajorPart = 0; FileMinorPart = 2; FileBuildPart = 1; FilePrivatePart = 0
+ }
+}
+
+function New-CiJob {
+ param([long]$RunId = 73)
+ return [pscustomobject]@{
+ name = 'ci (windows-latest, stable)'; run_id = $RunId; head_sha = $candidateCommit; status = 'completed'; conclusion = 'success'
+ steps = @('Full local checks', 'Developer tooling tests', 'Smoke safety tests', 'Release guard tests', 'Smoke tests') | ForEach-Object {
+ [pscustomobject]@{ name = $_; status = 'completed'; conclusion = 'success' }
+ }
+ }
+}
+
+function Invoke-CandidateFixture {
+ param([hashtable]$Overrides = @{})
+ $arguments = @{
+ RepoRoot = $repoFixture; Repository = $repository; TagName = $tagName
+ CandidateCommit = $candidateCommit; RemoteTagCommit = $candidateCommit
+ MainContainsCandidate = $true; CiRuns = @((New-CiRun)); CiJobs = @((New-CiJob))
+ ExistingReleases = @()
+ }
+ foreach ($key in $Overrides.Keys) { $arguments[$key] = $Overrides[$key] }
+ return Assert-ReleaseCandidate @arguments
+}
+
+function Write-ArtifactFixture {
+ New-Item -ItemType Directory -Path $packageFixture -Force | Out-Null
+ # Deliberately not an executable. These tests only validate bytes and metadata.
+ [IO.File]::WriteAllBytes((Join-Path $packageFixture 'wardoff.exe'), [Text.Encoding]::ASCII.GetBytes('release guard fixture - never execute'))
+ $hash = (Get-FileHash -LiteralPath (Join-Path $packageFixture 'wardoff.exe') -Algorithm SHA256).Hash
+ $info = [pscustomobject]@{
+ source_commit = $candidateCommit; tag = $tagName; version = '0.2.1'
+ target = 'x86_64-pc-windows-msvc'; unsigned = $true
+ build_run_id = 91; ci_run_id = 73; sha256 = $hash
+ }
+ Write-ArtifactInfo -Info $info
+ Set-Content -LiteralPath (Join-Path $packageFixture 'SHA256SUMS.txt') -Encoding ascii -Value "$hash wardoff.exe"
+ return $info
+}
+
+function Write-ArtifactInfo {
+ param($Info)
+ $Info | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $packageFixture 'build-info.json') -Encoding utf8
+}
+
+function Invoke-ArtifactFixture {
+ param([string]$ExpectedSha256, [hashtable]$Overrides = @{})
+ $arguments = @{
+ PackageDirectory = $packageFixture; CandidateCommit = $candidateCommit; TagName = $tagName
+ ExpectedSha256 = $ExpectedSha256; ExpectedBuildRunId = 91
+ }
+ foreach ($key in $Overrides.Keys) { $arguments[$key] = $Overrides[$key] }
+ Assert-ReleaseArtifact @arguments | Out-Null
+}
+
+try {
+ Invoke-TestCase 'exception assertion rejects a non-throwing action' {
+ $canaryCaught = $false
+ try { Assert-Throws {} } catch { $canaryCaught = $true }
+ Assert-True $canaryCaught 'Assert-Throws accepted an action that did not throw.'
+ }
+ if (-not (Test-Path -LiteralPath $guardPath -PathType Leaf)) {
+ throw 'Release guard implementation is missing: scripts/release-guard.ps1.'
+ }
+ . $guardPath
+ foreach ($functionName in @('Get-ReleaseVersion', 'Resolve-ReleaseTagCommit', 'Select-ReleaseCiRun', 'Assert-ReleaseDraftAvailable', 'Assert-ReleaseCandidate', 'Assert-ReleaseArtifact')) {
+ if (-not (Get-Command -Name $functionName -CommandType Function -ErrorAction SilentlyContinue)) {
+ throw "Release guard function is missing: $functionName."
+ }
+ }
+ New-Item -ItemType Directory -Path $fixtureRoot -Force | Out-Null
+ Write-VersionFixture
+
+ Invoke-TestCase 'matching package lock and namespaced manifest' {
+ Assert-Equal (Get-ReleaseVersion -RepoRoot $repoFixture -TagName $tagName) '0.2.1' 'Matching versions were rejected.'
+ }
+ foreach ($invalidTag in @('', '0.2.1', 'V0.2.1', 'v00.2.1', 'v0.02.1', 'v0.2.01', 'v0.2', 'v0.2.1.0', 'v0.2.1-beta.1', 'v0.2.1+build', ' v0.2.1', 'v0.2.1 ', "v0.2.1`n")) {
+ Invoke-TestCase "strict semantic tag rejects [$invalidTag]" {
+ Assert-Throws { Get-ReleaseVersion -RepoRoot $repoFixture -TagName $invalidTag }
+ }
+ }
+ Invoke-TestCase 'zero components remain valid' {
+ Write-VersionFixture -TomlVersion '0.0.0' -LockVersion '0.0.0' -ManifestVersion '0.0.0.0'
+ Assert-Equal (Get-ReleaseVersion -RepoRoot $repoFixture -TagName 'v0.0.0') '0.0.0' 'Zero components were rejected.'
+ }
+ foreach ($versions in @(
+ @{ TomlVersion = '0.2.0' }, @{ LockVersion = '0.2.0' }, @{ ManifestVersion = '0.2.0.0' },
+ @{ ManifestVersion = '0.2.1.1' }, @{ ManifestVersion = '0.2.1' }, @{ Level = 'requireAdministrator' }, @{ UiAccess = 'true' },
+ @{ PackageName = 'other' }, @{ LockPackageName = 'other' }
+ )) {
+ Invoke-TestCase ('version fixture rejects ' + ($versions.Keys -join ',')) {
+ Write-VersionFixture @versions
+ Assert-Throws { Get-ReleaseVersion -RepoRoot $repoFixture -TagName $tagName }
+ }
+ }
+ foreach ($missingFile in @('Cargo.toml', 'Cargo.lock', 'wardoff.manifest')) {
+ Invoke-TestCase "missing version file $missingFile" {
+ Write-VersionFixture
+ Remove-Item -LiteralPath (Join-Path $repoFixture $missingFile)
+ Assert-Throws { Get-ReleaseVersion -RepoRoot $repoFixture -TagName $tagName }
+ }
+ }
+ Invoke-TestCase 'malformed manifest' {
+ Write-VersionFixture
+ Set-Content -LiteralPath (Join-Path $repoFixture 'wardoff.manifest') -Encoding utf8 -Value ''
+ Assert-Throws { Get-ReleaseVersion -RepoRoot $repoFixture -TagName $tagName }
+ }
+ foreach ($displayVersion in @('0.2.1', '0.2.1.0')) {
+ Invoke-TestCase "numeric Windows version accepts display [$displayVersion]" {
+ $info = New-WindowsVersionInfo -DisplayVersion $displayVersion
+ $numericVersion = Assert-ReleaseWindowsVersion -FileVersionInfo $info -Version '0.2.1'
+ Assert-Equal $numericVersion '0.2.1.0' 'The numeric Windows version was not returned.'
+ }
+ }
+ foreach ($fieldName in @('FileMajorPart', 'FileMinorPart', 'FileBuildPart', 'FilePrivatePart')) {
+ Invoke-TestCase "numeric Windows version rejects mismatched $fieldName" {
+ $info = New-WindowsVersionInfo
+ $info.$fieldName++
+ Assert-Throws { Assert-ReleaseWindowsVersion -FileVersionInfo $info -Version '0.2.1' }
+ }
+ foreach ($invalidPart in @($true, 'correct value as string', -1, 65536)) {
+ Invoke-TestCase "numeric Windows version rejects $fieldName invalid value [$invalidPart]" {
+ $info = New-WindowsVersionInfo
+ if ($invalidPart -is [string] -and $invalidPart -ceq 'correct value as string') {
+ $info.$fieldName = [string]$info.$fieldName
+ } else {
+ $info.$fieldName = $invalidPart
+ }
+ Assert-Throws { Assert-ReleaseWindowsVersion -FileVersionInfo $info -Version '0.2.1' }
+ }
+ }
+ Invoke-TestCase "numeric Windows version rejects missing $fieldName" {
+ $info = New-WindowsVersionInfo
+ $info.PSObject.Properties.Remove($fieldName)
+ Assert-Throws { Assert-ReleaseWindowsVersion -FileVersionInfo $info -Version '0.2.1' }
+ }
+ }
+ Write-VersionFixture
+
+ Invoke-TestCase 'lightweight remote tag' {
+ Assert-Equal (Resolve-ReleaseTagCommit -TagName $tagName -RemoteRefs @("$candidateCommit`trefs/tags/$tagName")) $candidateCommit 'Lightweight tag SHA differs.'
+ }
+ Invoke-TestCase 'annotated remote tag uses peeled commit' {
+ $refs = @("$otherCommit`trefs/tags/$tagName", "$candidateCommit`trefs/tags/$tagName^{}")
+ Assert-Equal (Resolve-ReleaseTagCommit -TagName $tagName -RemoteRefs $refs) $candidateCommit 'Annotated tag was not peeled.'
+ }
+ foreach ($remoteRefs in @(
+ @{ Name = 'missing'; Refs = @() },
+ @{ Name = 'different tag'; Refs = @("$candidateCommit`trefs/tags/v0.2.10") },
+ @{ Name = 'short hash'; Refs = @("aaaa`trefs/tags/$tagName") },
+ @{ Name = 'non hexadecimal hash'; Refs = @('gggggggggggggggggggggggggggggggggggggggg refs/tags/v0.2.1') },
+ @{ Name = 'malformed line'; Refs = @("$candidateCommit refs/tags/$tagName extra") },
+ @{ Name = 'conflicting duplicate'; Refs = @("$candidateCommit`trefs/tags/$tagName", "$otherCommit`trefs/tags/$tagName") }
+ )) {
+ Invoke-TestCase ('remote tag rejects ' + $remoteRefs.Name) {
+ Assert-Throws { Resolve-ReleaseTagCommit -TagName $tagName -RemoteRefs $remoteRefs.Refs }
+ }
+ }
+
+ Invoke-TestCase 'exact successful main push CI' {
+ $run = Select-ReleaseCiRun -CiRuns @((New-CiRun)) -Repository $repository -CandidateCommit $candidateCommit
+ Assert-Equal $run.id 73 'The expected CI run was not selected.'
+ }
+ Invoke-TestCase 'API JSON preserves the UTC update timestamp as a string' {
+ $fixtureRun = New-CiRun
+ $json = [pscustomobject]@{ total_count = 1; workflow_runs = @($fixtureRun) } | ConvertTo-Json -Depth 6
+ $response = ConvertFrom-ReleaseApiJson -Json $json
+ $apiRun = @($response.workflow_runs)[0]
+ Assert-True ($apiRun.updated_at -is [string]) 'API JSON converted the update timestamp to a non-string value.'
+ Assert-Equal $apiRun.updated_at $fixtureRun.updated_at 'API JSON changed the exact UTC update timestamp.'
+ $selected = Select-ReleaseCiRun -CiRuns @($apiRun) -Repository $repository -CandidateCommit $candidateCommit
+ Assert-Equal $selected.id 73 'The parsed API run was rejected by the CI guard.'
+ }
+ Invoke-TestCase 'API JSON rejects malformed input' {
+ Assert-Throws { ConvertFrom-ReleaseApiJson -Json '{"workflow_runs": [broken}' }
+ }
+ Invoke-TestCase 'main workflow path suffix' {
+ $run = Select-ReleaseCiRun -CiRuns @((New-CiRun -Path '.github/workflows/ci.yml@refs/heads/main')) -Repository $repository -CandidateCommit $candidateCommit
+ Assert-Equal $run.id 73 'The authorized workflow suffix was rejected.'
+ }
+ foreach ($runArguments in @(
+ @{ Commit = $otherCommit }, @{ Branch = 'dev' }, @{ Event = 'pull_request' },
+ @{ Path = '.github/workflows/release.yml' }, @{ Path = '.github/workflows/ci.yml@refs/heads/dev' },
+ @{ Path = '.github/workflows/ci.yml@refs/heads/main/extra' }, @{ RepositoryName = 'other/Wardoff' },
+ @{ Attempt = 0 }, @{ Status = 'in_progress'; Conclusion = '' }, @{ Conclusion = 'failure' },
+ @{ Conclusion = 'cancelled' }, @{ Conclusion = 'skipped' }
+ )) {
+ Invoke-TestCase ('CI rejects ' + ($runArguments.Keys -join ',')) {
+ Assert-Throws { Select-ReleaseCiRun -CiRuns @((New-CiRun @runArguments)) -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ }
+ Invoke-TestCase 'CI evidence absent' {
+ Assert-Throws { Select-ReleaseCiRun -CiRuns @() -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ foreach ($invalidRunId in @(0, -1, $true, '73')) {
+ Invoke-TestCase "CI run ID rejects invalid value [$invalidRunId]" {
+ $run = New-CiRun
+ $run.id = $invalidRunId
+ Assert-Throws { Select-ReleaseCiRun -CiRuns @($run) -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ }
+ Invoke-TestCase 'newest eligible run is selected by update timestamp' {
+ $run = Select-ReleaseCiRun -CiRuns @((New-CiRun -Id 9), (New-CiRun -Id 101), (New-CiRun -Id 88)) -Repository $repository -CandidateCommit $candidateCommit
+ Assert-Equal $run.id 101 'The newest CI run was not selected.'
+ }
+ Invoke-TestCase 'recent failed rerun of lower ID invalidates higher ID green' {
+ $runs = @(
+ (New-CiRun -Id 74 -UpdatedAt '2026-10-05T01:00:00Z'),
+ (New-CiRun -Id 70 -Attempt 2 -Conclusion 'failure' -UpdatedAt '2026-10-05T02:00:00Z')
+ )
+ Assert-Throws { Select-ReleaseCiRun -CiRuns $runs -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ Invoke-TestCase 'recent running rerun of lower ID invalidates higher ID green' {
+ $runs = @(
+ (New-CiRun -Id 74 -UpdatedAt '2026-10-05T01:00:00Z'),
+ (New-CiRun -Id 70 -Attempt 2 -Status 'in_progress' -Conclusion '' -UpdatedAt '2026-10-05T02:00:00Z')
+ )
+ Assert-Throws { Select-ReleaseCiRun -CiRuns $runs -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ Invoke-TestCase 'recent successful rerun of lower ID is selected' {
+ $runs = @(
+ (New-CiRun -Id 74 -UpdatedAt '2026-10-05T01:00:00Z'),
+ (New-CiRun -Id 70 -Attempt 2 -UpdatedAt '2026-10-05T02:00:00Z')
+ )
+ $run = Select-ReleaseCiRun -CiRuns $runs -Repository $repository -CandidateCommit $candidateCommit
+ Assert-Equal $run.id 70 'The most recently updated rerun was not selected.'
+ Assert-Equal $run.run_attempt 2 'The expected rerun attempt was not selected.'
+ }
+ Invoke-TestCase 'equal update timestamps use run ID as tie breaker' {
+ $runs = @((New-CiRun -Id 70 -UpdatedAt '2026-10-05T01:00:00Z'), (New-CiRun -Id 74 -UpdatedAt '2026-10-05T01:00:00Z'))
+ $run = Select-ReleaseCiRun -CiRuns $runs -Repository $repository -CandidateCommit $candidateCommit
+ Assert-Equal $run.id 74 'Equal timestamps were not ordered by run ID.'
+ }
+ Invoke-TestCase 'equal update timestamp and ID use attempt as tie breaker' {
+ $runs = @((New-CiRun -Id 74 -Attempt 1 -UpdatedAt '2026-10-05T01:00:00Z'), (New-CiRun -Id 74 -Attempt 2 -UpdatedAt '2026-10-05T01:00:00Z'))
+ $run = Select-ReleaseCiRun -CiRuns $runs -Repository $repository -CandidateCommit $candidateCommit
+ Assert-Equal $run.run_attempt 2 'Equal timestamps and IDs were not ordered by attempt.'
+ }
+ Invoke-TestCase 'CI run without update timestamp is rejected' {
+ $run = New-CiRun
+ $run.PSObject.Properties.Remove('updated_at')
+ Assert-Throws { Select-ReleaseCiRun -CiRuns @($run) -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ foreach ($invalidUpdatedAt in @('', 'not-a-timestamp', '2026-13-05T01:00:00Z', '2026-10-05T01:00:00')) {
+ Invoke-TestCase "CI run rejects malformed update timestamp [$invalidUpdatedAt]" {
+ Assert-Throws { Select-ReleaseCiRun -CiRuns @((New-CiRun -UpdatedAt $invalidUpdatedAt)) -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ }
+ foreach ($latestConclusion in @('failure', 'cancelled', 'skipped')) {
+ Invoke-TestCase "newer $latestConclusion run invalidates old green" {
+ Assert-Throws { Select-ReleaseCiRun -CiRuns @((New-CiRun -Id 70), (New-CiRun -Id 74 -Conclusion $latestConclusion)) -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ }
+ Invoke-TestCase 'newer running CI invalidates old green' {
+ Assert-Throws { Select-ReleaseCiRun -CiRuns @((New-CiRun -Id 70), (New-CiRun -Id 74 -Status 'in_progress' -Conclusion '')) -Repository $repository -CandidateCommit $candidateCommit }
+ }
+ Invoke-TestCase 'unrelated newer commit does not replace exact SHA evidence' {
+ $run = Select-ReleaseCiRun -CiRuns @((New-CiRun -Id 70), (New-CiRun -Id 74 -Commit $otherCommit -Conclusion 'failure')) -Repository $repository -CandidateCommit $candidateCommit
+ Assert-Equal $run.id 70 'Unrelated SHA replaced exact candidate evidence.'
+ }
+
+ Invoke-TestCase 'no existing release' { Assert-ReleaseDraftAvailable -TagName $tagName -Releases @() }
+ foreach ($draftState in @($true, $false)) {
+ Invoke-TestCase "existing release rejected draft=$draftState" {
+ Assert-Throws { Assert-ReleaseDraftAvailable -TagName $tagName -Releases @([pscustomobject]@{ tag_name = $tagName; draft = $draftState; assets = @() }) }
+ }
+ }
+ Invoke-TestCase 'release for other tag allowed' {
+ Assert-ReleaseDraftAvailable -TagName $tagName -Releases @([pscustomobject]@{ tag_name = 'v0.2.0'; draft = $false; assets = @([pscustomobject]@{ name = 'wardoff.exe' }) })
+ }
+
+ Invoke-TestCase 'complete candidate returns bound metadata' {
+ $candidate = Invoke-CandidateFixture
+ Assert-Equal $candidate.Tag $tagName 'Candidate tag differs.'
+ Assert-Equal $candidate.Version '0.2.1' 'Candidate version differs.'
+ Assert-Equal $candidate.Commit $candidateCommit 'Candidate commit differs.'
+ Assert-Equal $candidate.CiRunId 73 'Candidate CI run differs.'
+ }
+ foreach ($overrides in @(
+ @{ Repository = 'other/Wardoff' }, @{ CandidateCommit = 'aaaa' },
+ @{ CandidateCommit = 'gggggggggggggggggggggggggggggggggggggggg' },
+ @{ RemoteTagCommit = 'aaaa' }, @{ RemoteTagCommit = $otherCommit },
+ @{ MainContainsCandidate = $false }, @{ CiRuns = @() }, @{ CiJobs = @() }
+ )) {
+ Invoke-TestCase ('candidate rejects ' + ($overrides.Keys -join ',')) {
+ Assert-Throws { Invoke-CandidateFixture -Overrides $overrides }
+ }
+ }
+ Invoke-TestCase 'moved annotated tag invalidates tested commit' {
+ $movedTag = Resolve-ReleaseTagCommit -TagName $tagName -RemoteRefs @("$candidateCommit`trefs/tags/$tagName", "$otherCommit`trefs/tags/$tagName^{}")
+ Assert-Throws { Invoke-CandidateFixture -Overrides @{ RemoteTagCommit = $movedTag } }
+ }
+ Invoke-TestCase 'candidate rejects CI job for another commit' {
+ $job = New-CiJob
+ $job.head_sha = $otherCommit
+ Assert-Throws { Invoke-CandidateFixture -Overrides @{ CiJobs = @($job) } }
+ }
+ Invoke-TestCase 'candidate rejects CI job without commit SHA' {
+ $job = New-CiJob
+ $job.PSObject.Properties.Remove('head_sha')
+ Assert-Throws { Invoke-CandidateFixture -Overrides @{ CiJobs = @($job) } }
+ }
+ foreach ($jobProblem in @('wrong run', 'wrong job', 'failure', 'running')) {
+ Invoke-TestCase "candidate rejects $jobProblem" {
+ $job = New-CiJob
+ switch ($jobProblem) {
+ 'wrong run' { $job.run_id = 74 }
+ 'wrong job' { $job.name = 'ci (ubuntu-latest, stable)' }
+ 'failure' { $job.conclusion = 'failure' }
+ 'running' { $job.status = 'in_progress' }
+ }
+ Assert-Throws { Invoke-CandidateFixture -Overrides @{ CiJobs = @($job) } }
+ }
+ }
+ foreach ($stepName in @('Full local checks', 'Developer tooling tests', 'Smoke safety tests', 'Release guard tests', 'Smoke tests')) {
+ foreach ($stepProblem in @('missing', 'failure', 'skipped', 'running')) {
+ Invoke-TestCase "candidate rejects $stepName $stepProblem" {
+ $job = New-CiJob
+ if ($stepProblem -eq 'missing') {
+ $job.steps = @($job.steps | Where-Object { $_.name -cne $stepName })
+ } else {
+ $step = $job.steps | Where-Object { $_.name -ceq $stepName }
+ if ($stepProblem -eq 'running') { $step.status = 'in_progress' } else { $step.conclusion = $stepProblem }
+ }
+ Assert-Throws { Invoke-CandidateFixture -Overrides @{ CiJobs = @($job) } }
+ }
+ }
+ }
+ Invoke-TestCase 'other failed CI job invalidates candidate' {
+ $failedJob = [pscustomobject]@{ name = 'additional checks'; run_id = 73; status = 'completed'; conclusion = 'failure'; steps = @() }
+ Assert-Throws { Invoke-CandidateFixture -Overrides @{ CiJobs = @((New-CiJob), $failedJob) } }
+ }
+ Invoke-TestCase 'existing public candidate release cannot be overwritten' {
+ Assert-Throws { Invoke-CandidateFixture -Overrides @{ ExistingReleases = @([pscustomobject]@{ tag_name = $tagName; draft = $false; assets = @([pscustomobject]@{ name = 'wardoff.exe' }) }) } }
+ }
+ Invoke-TestCase 'existing draft candidate release cannot be overwritten' {
+ Assert-Throws { Invoke-CandidateFixture -Overrides @{ ExistingReleases = @([pscustomobject]@{ tag_name = $tagName; draft = $true; assets = @() }) } }
+ }
+ Invoke-TestCase 'candidate enforces the version fixture guard' {
+ Write-VersionFixture -LockVersion '0.2.0'
+ Assert-Throws { Invoke-CandidateFixture }
+ Write-VersionFixture
+ }
+
+ Invoke-TestCase 'exact artifact hash and metadata' {
+ $info = Write-ArtifactFixture
+ Invoke-ArtifactFixture -ExpectedSha256 $info.sha256
+ }
+ foreach ($propertyCase in @(
+ @{ Field = 'source_commit'; Value = $otherCommit }, @{ Field = 'tag'; Value = 'v0.2.0' },
+ @{ Field = 'version'; Value = '0.2.0' }, @{ Field = 'target'; Value = 'x86_64-pc-windows-gnu' },
+ @{ Field = 'unsigned'; Value = $false }, @{ Field = 'unsigned'; Value = 'true' },
+ @{ Field = 'build_run_id'; Value = 92 }, @{ Field = 'build_run_id'; Value = 0 },
+ @{ Field = 'build_run_id'; Value = -1 }, @{ Field = 'build_run_id'; Value = $true },
+ @{ Field = 'build_run_id'; Value = '91' }, @{ Field = 'ci_run_id'; Value = 0 },
+ @{ Field = 'ci_run_id'; Value = -1 }, @{ Field = 'ci_run_id'; Value = $true },
+ @{ Field = 'ci_run_id'; Value = '73' }, @{ Field = 'sha256'; Value = ('0' * 64) }
+ )) {
+ Invoke-TestCase ('artifact rejects ' + $propertyCase.Field + '=' + $propertyCase.Value) {
+ $info = Write-ArtifactFixture
+ $expectedHash = $info.sha256
+ $info.($propertyCase.Field) = $propertyCase.Value
+ Write-ArtifactInfo -Info $info
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $expectedHash }
+ }
+ }
+ foreach ($fieldName in @('source_commit', 'tag', 'version', 'target', 'unsigned', 'build_run_id', 'ci_run_id', 'sha256')) {
+ Invoke-TestCase "artifact rejects missing metadata $fieldName" {
+ $info = Write-ArtifactFixture
+ $expectedHash = $info.sha256
+ $info.PSObject.Properties.Remove($fieldName)
+ Write-ArtifactInfo -Info $info
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $expectedHash }
+ }
+ }
+ Invoke-TestCase 'artifact bytes changed after verification' {
+ $info = Write-ArtifactFixture
+ [IO.File]::WriteAllBytes((Join-Path $packageFixture 'wardoff.exe'), [byte[]](1, 2, 3))
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $info.sha256 }
+ }
+ Invoke-TestCase 'trusted output hash differs from artifact and metadata' {
+ $info = Write-ArtifactFixture
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 ('0' * 64) }
+ }
+ Invoke-TestCase 'expected build run differs' {
+ $info = Write-ArtifactFixture
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $info.sha256 -Overrides @{ ExpectedBuildRunId = 92 } }
+ }
+ Invoke-TestCase 'malformed artifact metadata' {
+ $info = Write-ArtifactFixture
+ Set-Content -LiteralPath (Join-Path $packageFixture 'build-info.json') -Encoding utf8 -Value '{broken'
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $info.sha256 }
+ }
+ foreach ($missingArtifact in @('wardoff.exe', 'build-info.json', 'SHA256SUMS.txt')) {
+ Invoke-TestCase "artifact rejects missing $missingArtifact" {
+ $info = Write-ArtifactFixture
+ Remove-Item -LiteralPath (Join-Path $packageFixture $missingArtifact)
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $info.sha256 }
+ }
+ }
+ Invoke-TestCase 'checksum file hash changed independently' {
+ $info = Write-ArtifactFixture
+ Set-Content -LiteralPath (Join-Path $packageFixture 'SHA256SUMS.txt') -Encoding ascii -Value ((('0' * 64) + ' wardoff.exe'))
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $info.sha256 }
+ }
+ Invoke-TestCase 'checksum file names another asset' {
+ $info = Write-ArtifactFixture
+ Set-Content -LiteralPath (Join-Path $packageFixture 'SHA256SUMS.txt') -Encoding ascii -Value "$($info.sha256) other.exe"
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $info.sha256 }
+ }
+ Invoke-TestCase 'checksum file contains multiple lines' {
+ $info = Write-ArtifactFixture
+ Set-Content -LiteralPath (Join-Path $packageFixture 'SHA256SUMS.txt') -Encoding ascii -Value @("$($info.sha256) wardoff.exe", "$($info.sha256) other.exe")
+ Assert-Throws { Invoke-ArtifactFixture -ExpectedSha256 $info.sha256 }
+ }
+
+ Invoke-TestCase 'valid transfer inputs produce no output' {
+ $result = @(Assert-ReleaseTransferInputs -ArtifactId '123' -Sha256 ('a' * 64))
+ Assert-Equal $result.Count 0 'The transfer input guard produced unexpected output.'
+ }
+ foreach ($invalidArtifactId in @('', '0', '-1', 'not-an-id', '1.5', '1e3', ' 73', '73 ')) {
+ Invoke-TestCase "transfer guard rejects artifact ID [$invalidArtifactId]" {
+ Assert-Throws { Assert-ReleaseTransferInputs -ArtifactId $invalidArtifactId -Sha256 ('a' * 64) }
+ }
+ }
+ foreach ($invalidTransferHash in @('', 'abc', ('0' * 63), ('0' * 65), ('g' * 64))) {
+ Invoke-TestCase "transfer guard rejects malformed hash [$invalidTransferHash]" {
+ Assert-Throws { Assert-ReleaseTransferInputs -ArtifactId '123' -Sha256 $invalidTransferHash }
+ }
+ }
+
+ Invoke-TestCase 'PowerShell parser accepts guard and tests' {
+ foreach ($path in @($guardPath, $PSCommandPath)) {
+ $syntaxErrors = $null
+ [System.Management.Automation.Language.Parser]::ParseFile($path, [ref]$null, [ref]$syntaxErrors) | Out-Null
+ if ($syntaxErrors) { throw (($syntaxErrors | ForEach-Object { $_.Message }) -join [Environment]::NewLine) }
+ }
+ }
+ Write-Output "Release guard tests passed ($script:caseCount cases)."
+} finally {
+ # Remove only this test's generated directory after checking its resolved boundary.
+ if (Test-Path -LiteralPath $fixtureRoot) {
+ $resolvedFixture = (Resolve-Path -LiteralPath $fixtureRoot).Path
+ $tempRoot = [IO.Path]::GetFullPath([IO.Path]::GetTempPath()).TrimEnd('\')
+ $fixtureName = Split-Path -Leaf $resolvedFixture
+ if (-not ($resolvedFixture.StartsWith($tempRoot + '\', [StringComparison]::OrdinalIgnoreCase) -and
+ $fixtureName.StartsWith('wardoff-release-guard-', [StringComparison]::OrdinalIgnoreCase))) {
+ throw 'Refusing to remove a release fixture outside the temporary test boundary.'
+ }
+ Remove-Item -LiteralPath $resolvedFixture -Recurse -Force
+ }
+}
+exit 0
diff --git a/tests/smoke_helpers.ps1 b/tests/smoke_helpers.ps1
new file mode 100644
index 0000000..02fccd9
--- /dev/null
+++ b/tests/smoke_helpers.ps1
@@ -0,0 +1,204 @@
+Set-StrictMode -Version Latest
+
+function Invoke-SmokeReleaseBuild {
+ param([bool] $UseExistingBinary, [string] $BinaryPath, [scriptblock] $BuildAction)
+ if ($UseExistingBinary) {
+ if (-not (Test-Path -LiteralPath $BinaryPath -PathType Leaf)) {
+ throw "Expected an existing release binary at $BinaryPath; compilation is disabled."
+ }
+ return
+ }
+ $result = & $BuildAction
+ if ($result.ExitCode -ne 0) {
+ throw "cargo build --release --locked failed with exit code $($result.ExitCode)."
+ }
+}
+
+function Get-SmokeCurrentSessionId {
+ return [System.Diagnostics.Process]::GetCurrentProcess().SessionId
+}
+
+function Test-SmokeOwnedProcess {
+ param(
+ [Parameter(Mandatory = $true)]
+ [object] $ObservedProcess,
+ [Parameter(Mandatory = $true)]
+ [AllowEmptyCollection()]
+ [object[]] $OwnedProcesses
+ )
+
+ foreach ($ownedProcess in $OwnedProcesses) {
+ if ($null -eq $ownedProcess) {
+ continue
+ }
+ if ($ownedProcess.HasExited) {
+ continue
+ }
+ if ([int]$ObservedProcess.ProcessId -ne [int]$ownedProcess.Id) {
+ continue
+ }
+ # The live Process object owns a kernel handle; an exited object cannot
+ # authorize a reused PID to be treated as the smoke process.
+ return $true
+ }
+ return $false
+}
+
+function Assert-SmokePreconditions {
+ param(
+ [Parameter(Mandatory = $true)]
+ [AllowEmptyCollection()]
+ [object[]] $WardoffProcesses,
+ [Parameter(Mandatory = $true)]
+ [int] $CurrentSessionId,
+ [Parameter(Mandatory = $true)]
+ [string] $BinaryPath,
+ [Parameter(Mandatory = $true)]
+ [scriptblock] $AutostartTaskProbe,
+ [AllowEmptyCollection()]
+ [object[]] $OwnedProcesses = @()
+ )
+
+ $resolvedBinaryPath = [System.IO.Path]::GetFullPath($BinaryPath)
+ $foreignProcess = @(
+ $WardoffProcesses | Where-Object {
+ (([int]$_.SessionId -eq $CurrentSessionId) -or
+ ($_.ExecutablePath -and
+ [string]::Equals(
+ [System.IO.Path]::GetFullPath([string]$_.ExecutablePath),
+ $resolvedBinaryPath,
+ [System.StringComparison]::OrdinalIgnoreCase
+ ))) -and
+ (-not (Test-SmokeOwnedProcess -ObservedProcess $_ -OwnedProcesses $OwnedProcesses))
+ }
+ )
+ if ($foreignProcess.Count -gt 0) {
+ $ids = ($foreignProcess | ForEach-Object { [int]$_.ProcessId }) -join ', '
+ throw "Smoke test refused to start: a conflicting Wardoff runtime process already exists (session $CurrentSessionId or the same release binary in another session; PID(s): $ids). Use an isolated environment without an existing runtime."
+ }
+
+ $taskExists = & $AutostartTaskProbe
+ if ([bool]$taskExists) {
+ throw 'Smoke test refused to start: the \Wardoff autostart task already exists. Use an isolated environment without an existing autostart task.'
+ }
+}
+
+function Stop-SmokeOwnedProcesses {
+ param(
+ [Parameter(Mandatory = $true)]
+ [AllowEmptyCollection()]
+ [object[]] $OwnedProcesses,
+ [Parameter(Mandatory = $true)]
+ [scriptblock] $StopAction,
+ [scriptblock] $WaitAction = $null
+ )
+
+ foreach ($process in $OwnedProcesses) {
+ if ($null -eq $process) {
+ continue
+ }
+ try {
+ if (-not $process.HasExited) {
+ & $StopAction $process
+ if ($null -ne $WaitAction) {
+ & $WaitAction $process
+ }
+ }
+ }
+ catch {
+ if ($_.Exception.Message -notmatch 'cannot find|has exited') {
+ Write-Warning "Could not stop owned Wardoff process $($process.Id): $($_.Exception.Message)"
+ }
+ }
+ }
+}
+
+function Test-SmokeAutostartTaskIdentity {
+ param(
+ [Parameter(Mandatory = $true)][object] $ExpectedIdentity,
+ [Parameter(Mandatory = $true)][object] $ActualIdentity
+ )
+ return [string]::Equals($ExpectedIdentity.Xml, $ActualIdentity.Xml, [System.StringComparison]::Ordinal) -and
+ [string]::Equals($ExpectedIdentity.Path, $ActualIdentity.Path, [System.StringComparison]::OrdinalIgnoreCase) -and
+ [string]::Equals($ExpectedIdentity.WorkingDirectory, $ActualIdentity.WorkingDirectory, [System.StringComparison]::OrdinalIgnoreCase)
+}
+
+function Get-EmbeddedManifestContent {
+ param(
+ [Parameter(Mandatory = $true)]
+ [string] $Path
+ )
+
+ if (-not ('Wardoff.ManifestReader' -as [type])) {
+ Add-Type @"
+using System;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Wardoff {
+ public static class ManifestReader {
+ private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
+ private static readonly IntPtr ManifestResourceId = new IntPtr(1);
+ private static readonly IntPtr ManifestResourceType = new IntPtr(24);
+
+ [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern IntPtr LockResource(IntPtr hResData);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern bool FreeLibrary(IntPtr hModule);
+
+ public static string ReadManifest(string path) {
+ var module = LoadLibraryEx(path, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
+ if (module == IntPtr.Zero) {
+ throw new Win32Exception(Marshal.GetLastWin32Error(), "LoadLibraryEx failed for " + path);
+ }
+
+ try {
+ var manifestInfo = FindResource(module, ManifestResourceId, ManifestResourceType);
+ if (manifestInfo == IntPtr.Zero) {
+ throw new Win32Exception(Marshal.GetLastWin32Error(), "FindResource could not locate the embedded manifest.");
+ }
+
+ var manifestBytesLength = SizeofResource(module, manifestInfo);
+ if (manifestBytesLength == 0) {
+ throw new InvalidOperationException("The embedded manifest resource was empty.");
+ }
+
+ var manifestHandle = LoadResource(module, manifestInfo);
+ if (manifestHandle == IntPtr.Zero) {
+ throw new Win32Exception(Marshal.GetLastWin32Error(), "LoadResource failed for the embedded manifest.");
+ }
+
+ var manifestPointer = LockResource(manifestHandle);
+ if (manifestPointer == IntPtr.Zero) {
+ throw new Win32Exception(Marshal.GetLastWin32Error(), "LockResource failed for the embedded manifest.");
+ }
+
+ var manifestBytes = new byte[(int)manifestBytesLength];
+ Marshal.Copy(manifestPointer, manifestBytes, 0, (int)manifestBytesLength);
+ return Encoding.UTF8.GetString(manifestBytes);
+ }
+ finally {
+ FreeLibrary(module);
+ }
+ }
+ }
+}
+"@
+ }
+
+ return [Wardoff.ManifestReader]::ReadManifest([System.IO.Path]::GetFullPath($Path))
+}
diff --git a/tests/smoke_safety.ps1 b/tests/smoke_safety.ps1
new file mode 100644
index 0000000..afa9f37
--- /dev/null
+++ b/tests/smoke_safety.ps1
@@ -0,0 +1,182 @@
+[CmdletBinding()]
+param()
+
+$ErrorActionPreference = 'Stop'
+$helperPath = Join-Path $PSScriptRoot 'smoke_helpers.ps1'
+. $helperPath
+
+function Assert-True {
+ param([bool]$Condition, [string]$Message)
+ if (-not $Condition) { throw $Message }
+}
+
+function Assert-Throws {
+ param([scriptblock]$Action, [string]$MessageFragment)
+ $caught = $null
+ try {
+ & $Action
+ }
+ catch {
+ $caught = $_.Exception.Message
+ }
+ if ($null -eq $caught) {
+ throw "Expected an exception containing '$MessageFragment'."
+ }
+ if ($caught -notmatch [regex]::Escape($MessageFragment)) {
+ throw "Unexpected exception: $caught"
+ }
+}
+
+try {
+ $binaryPath = Join-Path $env:TEMP 'Wardoff\target\release\wardoff.exe'
+ $canaryCaught = $false
+ try { Assert-Throws {} 'canary' } catch { $canaryCaught = $true }
+ Assert-True $canaryCaught 'Assert-Throws accepted an action that did not throw.'
+
+ & {
+ # Load only these function definitions; never execute the smoke runtime.
+ $smokePath = Join-Path $PSScriptRoot 'smoke_test.ps1'
+ $parseErrors = $null
+ $smokeAst = [System.Management.Automation.Language.Parser]::ParseFile($smokePath, [ref]$null, [ref]$parseErrors)
+ if ($parseErrors) { throw (($parseErrors | ForEach-Object { $_.Message }) -join [Environment]::NewLine) }
+ foreach ($functionName in @('Get-SmokePreflightWardoffProcesses', 'Assert-SmokePreflight')) {
+ $definitions = @($smokeAst.FindAll({
+ param($node)
+ $node -is [System.Management.Automation.Language.FunctionDefinitionAst] -and $node.Name -ceq $functionName
+ }, $true))
+ Assert-True ($definitions.Count -eq 1) "Expected exactly one smoke function named $functionName."
+ . ([scriptblock]::Create($definitions[0].Extent.Text))
+ }
+
+ $preflightState = @{ Processes = @(); ProcessError = $false; TaskExists = $false; TaskError = $false; TaskCalls = 0 }
+ function Get-WardoffProcessesByName {
+ if ($preflightState.ProcessError) { throw 'Fixture process enumeration failed.' }
+ return @($preflightState.Processes)
+ }
+ function Get-SmokeCurrentSessionId { return 7 }
+ function Get-SmokeAutostartTaskExists {
+ $preflightState.TaskCalls++
+ if ($preflightState.TaskError) { throw 'Fixture task query failed.' }
+ return $preflightState.TaskExists
+ }
+ $script:OwnedProcesses = [System.Collections.Generic.List[object]]::new()
+ $script:OwnedProcesses.Add([pscustomobject]@{ Id = 901; HasExited = $false })
+
+ Assert-SmokePreflight
+ Assert-True ($preflightState.TaskCalls -eq 1) 'An empty process inventory did not reach the fake task probe.'
+
+ $preflightState.ProcessError = $true
+ Assert-Throws { Assert-SmokePreflight } 'could not query Wardoff processes before mutation'
+ Assert-True ($preflightState.TaskCalls -eq 1) 'A failed process query reached the task probe.'
+ $preflightState.ProcessError = $false
+
+ $preflightState.Processes = @([pscustomobject]@{ ProcessId = 902; SessionId = 7; ExecutablePath = 'C:\other\wardoff.exe'; CreationDate = $null })
+ Assert-Throws { Assert-SmokePreflight } 'conflicting Wardoff runtime process'
+ Assert-True ($preflightState.TaskCalls -eq 1) 'A conflicting process reached the task probe.'
+
+ $preflightState.Processes = @([pscustomobject]@{ ProcessId = 901; SessionId = 7; ExecutablePath = $binaryPath; CreationDate = $null })
+ Assert-SmokePreflight
+ Assert-True ($preflightState.TaskCalls -eq 2) 'The fake owned process did not pass the real preflight.'
+
+ $preflightState.Processes = @()
+ $preflightState.TaskExists = $true
+ Assert-Throws { Assert-SmokePreflight } 'autostart task already exists'
+ Assert-True ($preflightState.TaskCalls -eq 3) 'The fake existing task was not checked.'
+
+ $preflightState.TaskExists = $false
+ $preflightState.TaskError = $true
+ Assert-Throws { Assert-SmokePreflight } 'Fixture task query failed'
+ Assert-True ($preflightState.TaskCalls -eq 4) 'The fake task failure was not checked.'
+
+ Assert-Throws {
+ Assert-SmokePreconditions -WardoffProcesses $null -CurrentSessionId 7 -BinaryPath $binaryPath -AutostartTaskProbe { return $false }
+ } 'WardoffProcesses'
+ Write-Output 'Smoke preflight fixtures passed (7 cases; no runtime or task access).'
+ }
+
+ $buildFixture = Join-Path ([IO.Path]::GetTempPath()) ('wardoff-smoke-build-' + [Guid]::NewGuid().ToString('N') + '.exe')
+ try {
+ [IO.File]::WriteAllBytes($buildFixture, [byte[]](1, 2, 3))
+ $buildCalls = @{ Count = 0 }
+ $buildAction = { $buildCalls.Count++; return [pscustomobject]@{ ExitCode = 0 } }
+ Invoke-SmokeReleaseBuild -UseExistingBinary $true -BinaryPath $buildFixture -BuildAction $buildAction
+ Assert-True ($buildCalls.Count -eq 0) 'Existing-binary smoke unexpectedly invoked Cargo.'
+ Invoke-SmokeReleaseBuild -UseExistingBinary $false -BinaryPath $buildFixture -BuildAction $buildAction
+ Assert-True ($buildCalls.Count -eq 1) 'Ordinary smoke did not invoke its build action.'
+ Assert-Throws {
+ Invoke-SmokeReleaseBuild -UseExistingBinary $true -BinaryPath ($buildFixture + '.missing') -BuildAction $buildAction
+ } 'existing release binary'
+ Assert-True ($buildCalls.Count -eq 1) 'Missing-binary smoke fell back to compilation.'
+ Assert-Throws {
+ Invoke-SmokeReleaseBuild -UseExistingBinary $false -BinaryPath $buildFixture -BuildAction { return [pscustomobject]@{ ExitCode = 7 } }
+ } 'exit code 7'
+ } finally {
+ if (Test-Path -LiteralPath $buildFixture) { Remove-Item -LiteralPath $buildFixture -Force }
+ }
+
+ $probeState = @{ Calls = 0 }
+ $emptyProbe = { $probeState.Calls++; return $false }
+ Assert-SmokePreconditions -WardoffProcesses @() -CurrentSessionId 7 -BinaryPath $binaryPath -AutostartTaskProbe $emptyProbe
+ Assert-True ($probeState.Calls -eq 1) 'The autostart probe was not called for a clean fixture.'
+
+ $sameSession = [pscustomobject]@{ ProcessId = 101; SessionId = 7; ExecutablePath = 'C:\other\wardoff.exe'; CreationDate = $null }
+ $probeState.Calls = 0
+ Assert-Throws {
+ Assert-SmokePreconditions -WardoffProcesses @($sameSession) -CurrentSessionId 7 -BinaryPath $binaryPath -AutostartTaskProbe { $probeState.Calls++; return $false }
+ } 'conflicting Wardoff runtime process'
+ Assert-True ($probeState.Calls -eq 0) 'The task probe ran after a process guard failure.'
+
+ $otherSession = [pscustomobject]@{ ProcessId = 102; SessionId = 8; ExecutablePath = 'C:\other\wardoff.exe'; CreationDate = $null }
+ Assert-SmokePreconditions -WardoffProcesses @($otherSession) -CurrentSessionId 7 -BinaryPath $binaryPath -AutostartTaskProbe { return $false }
+
+ $sameBinaryOtherSession = [pscustomobject]@{ ProcessId = 103; SessionId = 8; ExecutablePath = $binaryPath; CreationDate = $null }
+ Assert-Throws {
+ Assert-SmokePreconditions -WardoffProcesses @($sameBinaryOtherSession) -CurrentSessionId 7 -BinaryPath $binaryPath -AutostartTaskProbe { return $false }
+ } 'conflicting Wardoff runtime process'
+
+ $exitedOwned = [pscustomobject]@{ Id = 103; HasExited = $true; StartTime = [datetime]::UtcNow }
+ $observedReusedPid = [pscustomobject]@{ ProcessId = 103; SessionId = 7; ExecutablePath = $binaryPath; CreationDate = [datetime]::UtcNow }
+ Assert-Throws {
+ Assert-SmokePreconditions -WardoffProcesses @($observedReusedPid) -CurrentSessionId 7 -BinaryPath $binaryPath -AutostartTaskProbe { return $false } -OwnedProcesses @($exitedOwned)
+ } 'conflicting Wardoff runtime process'
+
+ Assert-Throws {
+ Assert-SmokePreconditions -WardoffProcesses @() -CurrentSessionId 7 -BinaryPath $binaryPath -AutostartTaskProbe { return $true }
+ } 'autostart task already exists'
+
+ Assert-Throws {
+ Assert-SmokePreconditions -WardoffProcesses @() -CurrentSessionId 7 -BinaryPath $binaryPath -AutostartTaskProbe { throw 'Task Scheduler query failed.' }
+ } 'Task Scheduler query failed'
+
+ $taskIdentity = [pscustomobject]@{ Xml = ''; Path = $binaryPath; WorkingDirectory = (Split-Path -Parent $binaryPath) }
+ $sameTaskIdentity = [pscustomobject]@{ Xml = $taskIdentity.Xml; Path = $taskIdentity.Path; WorkingDirectory = $taskIdentity.WorkingDirectory }
+ $changedTaskIdentity = [pscustomobject]@{ Xml = ''; Path = $taskIdentity.Path; WorkingDirectory = $taskIdentity.WorkingDirectory }
+ Assert-True (Test-SmokeAutostartTaskIdentity -ExpectedIdentity $taskIdentity -ActualIdentity $sameTaskIdentity) 'An unchanged smoke-created task was not recognized as owned.'
+ Assert-True (-not (Test-SmokeAutostartTaskIdentity -ExpectedIdentity $taskIdentity -ActualIdentity $changedTaskIdentity)) 'A changed task definition was still recognized as owned.'
+
+ $owned = [pscustomobject]@{ Id = 201; HasExited = $false }
+ $unowned = [pscustomobject]@{ Id = 202; HasExited = $false }
+ $stopped = [System.Collections.Generic.List[int]]::new()
+ Stop-SmokeOwnedProcesses -OwnedProcesses @($owned) -StopAction {
+ param($process)
+ $stopped.Add([int]$process.Id)
+ } -WaitAction {
+ param($process)
+ }
+ Assert-True ($stopped.Count -eq 1 -and $stopped[0] -eq 201) 'Cleanup did not stop exactly the owned process handle.'
+ Assert-True (-not ($stopped -contains $unowned.Id)) 'Cleanup attempted to stop an unowned process.'
+
+ $syntaxErrors = $null
+ foreach ($path in @($helperPath, (Join-Path $PSScriptRoot 'smoke_test.ps1'))) {
+ [System.Management.Automation.Language.Parser]::ParseFile($path, [ref]$null, [ref]$syntaxErrors) | Out-Null
+ if ($syntaxErrors) {
+ throw (($syntaxErrors | ForEach-Object { $_.Message }) -join [Environment]::NewLine)
+ }
+ }
+ Write-Output 'Smoke safety tests passed.'
+ exit 0
+}
+catch {
+ Write-Error $_.Exception.Message
+ exit 1
+}
diff --git a/tests/smoke_test.ps1 b/tests/smoke_test.ps1
index 5ee77b7..36c73dd 100644
--- a/tests/smoke_test.ps1
+++ b/tests/smoke_test.ps1
@@ -1,13 +1,26 @@
+<#
+.SYNOPSIS
+State-changing Windows integration tests; use an isolated test environment.
+.DESCRIPTION
+Refuses to start when a conflicting Wardoff runtime or autostart task already
+exists, then runs Block/Allow using only processes launched by this test. It
+writes real user logs and can change scheduled tasks when elevated. For routine
+development use scripts/check.ps1 instead.
+See docs/MVP_VALIDATION_MATRIX.md for coverage and manual acceptance.
+#>
[CmdletBinding()]
-param()
+param([switch] $UseExistingBinary)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$script:Results = [System.Collections.Generic.List[object]]::new()
+$script:OwnedProcesses = [System.Collections.Generic.List[object]]::new()
$script:BackgroundProcess = $null
$script:InitialLogLineCount = 0
+. (Join-Path $PSScriptRoot 'smoke_helpers.ps1')
+
$repoRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..'))
$logPath = Join-Path (Join-Path $env:LOCALAPPDATA 'Wardoff') 'logs\wardoff.jsonl'
@@ -418,7 +431,7 @@ function Invoke-DirectPowerShellWardoffCommand {
}
function Get-WardoffProcessesByName {
- $processes = Get-CimInstance Win32_Process -Filter "Name='wardoff.exe'" -ErrorAction SilentlyContinue
+ $processes = Get-CimInstance Win32_Process -Filter "Name='wardoff.exe'" -ErrorAction Stop
if ($null -eq $processes) {
return @()
@@ -427,6 +440,107 @@ function Get-WardoffProcessesByName {
return @($processes)
}
+function Get-SmokePreflightWardoffProcesses {
+ try {
+ return @(Get-WardoffProcessesByName)
+ }
+ catch {
+ throw "Smoke test could not query Wardoff processes before mutation: $($_.Exception.Message)"
+ }
+}
+
+function Get-SmokeAutostartTaskExists {
+ $scheduler = $null
+ $rootFolder = $null
+ $task = $null
+ try {
+ $scheduler = New-Object -ComObject 'Schedule.Service'
+ $scheduler.Connect()
+ $rootFolder = $scheduler.GetFolder('\')
+ try {
+ $task = $rootFolder.GetTask('Wardoff')
+ return $true
+ }
+ catch {
+ $hresult = $_.Exception.GetBaseException().HResult
+ if ($hresult -in @(-2147024894, -2147024893, -2147023728)) {
+ return $false
+ }
+ throw
+ }
+ }
+ catch {
+ throw "Smoke test could not query the Wardoff autostart task before mutation: $($_.Exception.Message)"
+ }
+ finally {
+ foreach ($comObject in @($task, $rootFolder, $scheduler)) {
+ if ($null -ne $comObject) {
+ [void][Runtime.InteropServices.Marshal]::ReleaseComObject($comObject)
+ }
+ }
+ }
+}
+
+function Get-SmokeAutostartTaskIdentity {
+ $scheduler = $null
+ $rootFolder = $null
+ $task = $null
+ $definition = $null
+ $actions = $null
+ $action = $null
+ try {
+ $scheduler = New-Object -ComObject 'Schedule.Service'
+ $scheduler.Connect()
+ $rootFolder = $scheduler.GetFolder('\')
+ $task = $rootFolder.GetTask('Wardoff')
+ $definition = $task.Definition
+ $actions = $definition.Actions
+ if ($actions.Count -ne 1) {
+ throw 'Wardoff autostart task has an unexpected number of actions.'
+ }
+ $action = $actions.Item(1)
+ $expectedPath = [System.IO.Path]::GetFullPath($binaryPath)
+ $actualPath = [System.IO.Path]::GetFullPath([string]$action.Path)
+ $expectedWorkingDirectory = [System.IO.Path]::GetFullPath((Split-Path -Parent $binaryPath))
+ $actualWorkingDirectory = [System.IO.Path]::GetFullPath([string]$action.WorkingDirectory)
+ if (-not [string]::Equals($actualPath, $expectedPath, [System.StringComparison]::OrdinalIgnoreCase) -or
+ -not [string]::Equals($actualWorkingDirectory, $expectedWorkingDirectory, [System.StringComparison]::OrdinalIgnoreCase)) {
+ throw 'Refusing to claim an autostart task that does not target the smoke executable and its directory.'
+ }
+ return [pscustomobject]@{
+ Xml = [string]$task.Xml
+ Path = $actualPath
+ WorkingDirectory = $actualWorkingDirectory
+ }
+ }
+ catch {
+ throw "Smoke test could not verify ownership of the Wardoff autostart task: $($_.Exception.Message)"
+ }
+ finally {
+ foreach ($comObject in @($action, $actions, $definition, $task, $rootFolder, $scheduler)) {
+ if ($null -ne $comObject) {
+ [void][Runtime.InteropServices.Marshal]::ReleaseComObject($comObject)
+ }
+ }
+ }
+}
+
+function Test-SmokeOwnedAutostartTask {
+ param([Parameter(Mandatory = $true)][object]$ExpectedIdentity)
+ $actual = Get-SmokeAutostartTaskIdentity
+ return Test-SmokeAutostartTaskIdentity -ExpectedIdentity $ExpectedIdentity -ActualIdentity $actual
+}
+
+function Assert-SmokePreflight {
+ $processes = @(Get-SmokePreflightWardoffProcesses)
+ Assert-SmokePreconditions `
+ -WardoffProcesses $processes `
+ -CurrentSessionId (Get-SmokeCurrentSessionId) `
+ -BinaryPath $binaryPath `
+ -AutostartTaskProbe { Get-SmokeAutostartTaskExists } `
+ -OwnedProcesses @($script:OwnedProcesses.ToArray())
+}
+
function Get-RepoWardoffProcesses {
if (-not (Test-Path $binaryPath)) {
return @()
@@ -447,85 +561,7 @@ function Get-RepoWardoffProcesses {
)
}
-function Get-EmbeddedManifestContent {
- param(
- [Parameter(Mandatory = $true)]
- [string] $Path
- )
-
- if (-not ('Wardoff.ManifestReader' -as [type])) {
- Add-Type @"
-using System;
-using System.ComponentModel;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Wardoff {
- public static class ManifestReader {
- private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
- private static readonly IntPtr ManifestResourceId = new IntPtr(1);
- private static readonly IntPtr ManifestResourceType = new IntPtr(24);
-
- [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
- private static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern IntPtr LockResource(IntPtr hResData);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
-
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern bool FreeLibrary(IntPtr hModule);
-
- public static string ReadManifest(string path) {
- var module = LoadLibraryEx(path, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
- if (module == IntPtr.Zero) {
- throw new Win32Exception(Marshal.GetLastWin32Error(), "LoadLibraryEx failed for " + path);
- }
-
- try {
- var manifestInfo = FindResource(module, ManifestResourceId, ManifestResourceType);
- if (manifestInfo == IntPtr.Zero) {
- throw new Win32Exception(Marshal.GetLastWin32Error(), "FindResource could not locate the embedded manifest.");
- }
-
- var manifestBytesLength = SizeofResource(module, manifestInfo);
- if (manifestBytesLength == 0) {
- throw new InvalidOperationException("The embedded manifest resource was empty.");
- }
-
- var manifestHandle = LoadResource(module, manifestInfo);
- if (manifestHandle == IntPtr.Zero) {
- throw new Win32Exception(Marshal.GetLastWin32Error(), "LoadResource failed for the embedded manifest.");
- }
-
- var manifestPointer = LockResource(manifestHandle);
- if (manifestPointer == IntPtr.Zero) {
- throw new Win32Exception(Marshal.GetLastWin32Error(), "LockResource failed for the embedded manifest.");
- }
-
- var manifestBytes = new byte[(int)manifestBytesLength];
- Marshal.Copy(manifestPointer, manifestBytes, 0, (int)manifestBytesLength);
- return Encoding.UTF8.GetString(manifestBytes);
- }
- finally {
- FreeLibrary(module);
- }
- }
- }
-}
-"@
- }
- return [Wardoff.ManifestReader]::ReadManifest([System.IO.Path]::GetFullPath($Path))
-}
function Wait-ForBinaryUnlock {
param(
@@ -572,33 +608,15 @@ function Wait-ForBinaryUnlock {
}
function Stop-RepoWardoffProcesses {
- $processes = @(Get-RepoWardoffProcesses)
-
- if ($processes.Count -gt 0 -and (Test-Path $binaryPath)) {
- try {
- $null = Invoke-ExternalCommand -FilePath $binaryPath -Arguments @('--allow')
- Start-Sleep -Seconds 1
- }
- catch {
- }
- }
-
- foreach ($process in $processes) {
- try {
- Stop-Process -Id $process.ProcessId -Force -ErrorAction Stop
- }
- catch {
- if ($_.Exception.Message -notmatch 'cannot find') {
- Write-Warning "Could not stop Wardoff process $($process.ProcessId): $($_.Exception.Message)"
- }
- }
- }
-
- foreach ($process in $processes) {
- try {
- Wait-Process -Id $process.ProcessId -Timeout 5 -ErrorAction Stop
- }
- catch {
+ $processes = @($script:OwnedProcesses.ToArray())
+
+ Stop-SmokeOwnedProcesses -OwnedProcesses $processes -StopAction {
+ param($process)
+ Stop-Process -InputObject $process -Force -ErrorAction Stop
+ } -WaitAction {
+ param($process)
+ if (-not $process.WaitForExit(5000)) {
+ throw "Owned Wardoff process $($process.Id) did not exit within five seconds."
}
}
@@ -731,12 +749,15 @@ function Resolve-PowercfgRequestsCheck {
}
}
+Assert-SmokePreflight
+
try {
Stop-RepoWardoffProcesses
- Invoke-TestCase 'cargo build --release succeeds' {
- $result = Invoke-ExternalCommand -FilePath 'cargo' -Arguments @('build', '--release')
- Assert-Condition ($result.ExitCode -eq 0) "cargo build --release failed with exit code $($result.ExitCode)."
+ Invoke-TestCase 'release binary preparation succeeds' {
+ Invoke-SmokeReleaseBuild -UseExistingBinary $UseExistingBinary.IsPresent -BinaryPath $binaryPath -BuildAction {
+ Invoke-ExternalCommand -FilePath 'cargo' -Arguments @('build', '--release', '--locked')
+ }
}
Invoke-TestCase 'target\release\wardoff.exe exists after the release build' {
@@ -826,8 +847,10 @@ try {
Invoke-TestCase 'Start-Process launches wardoff --block --hide in the background' {
Stop-RepoWardoffProcesses
+ Assert-SmokePreflight
$script:InitialLogLineCount = @(Get-StructuredLogLines).Count
$script:BackgroundProcess = Start-Process -FilePath $binaryPath -ArgumentList @('--block', '--hide') -WorkingDirectory $repoRoot -WindowStyle Hidden -PassThru
+ $script:OwnedProcesses.Add($script:BackgroundProcess)
Start-Sleep -Seconds 2
$script:BackgroundProcess.Refresh()
Assert-Condition (-not $script:BackgroundProcess.HasExited) "Wardoff exited early with code $($script:BackgroundProcess.ExitCode)."
@@ -951,38 +974,38 @@ try {
}
else {
Invoke-TestCase $autostartDescription {
- $taskOriginallyPresent = (Invoke-ExternalCommand -FilePath 'schtasks' -Arguments @('/query', '/tn', 'Wardoff')).ExitCode -eq 0
-
+ Assert-SmokePreflight
+ $taskCreatedBySmoke = $false
+ $taskIdentity = $null
try {
$enableResult = Invoke-ExternalCommand -FilePath $binaryPath -Arguments @('--autostart', 'on')
if ($enableResult.ExitCode -eq 0) {
+ $taskIdentity = Get-SmokeAutostartTaskIdentity
+ $taskCreatedBySmoke = $true
$queryEnabled = Invoke-ExternalCommand -FilePath 'schtasks' -Arguments @('/query', '/tn', 'Wardoff')
Assert-Condition ($queryEnabled.ExitCode -eq 0) 'schtasks /query /tn "Wardoff" did not find the task after --autostart on.'
+ Assert-Condition (Test-SmokeOwnedAutostartTask -ExpectedIdentity $taskIdentity) 'Refusing to remove the Wardoff task because its definition changed after creation.'
$disableResult = Invoke-ExternalCommand -FilePath $binaryPath -Arguments @('--autostart', 'off')
Assert-Condition ($disableResult.ExitCode -eq 0) "wardoff --autostart off exited with code $($disableResult.ExitCode)."
-
- $queryDisabled = Invoke-ExternalCommand -FilePath 'schtasks' -Arguments @('/query', '/tn', 'Wardoff')
- Assert-Condition ($queryDisabled.ExitCode -ne 0) 'schtasks /query /tn "Wardoff" still found the task after --autostart off.'
+ Assert-Condition (-not (Get-SmokeAutostartTaskExists)) 'The Wardoff task still exists after --autostart off.'
+ $taskCreatedBySmoke = $false
+ $taskIdentity = $null
}
else {
Assert-Condition ($enableResult.Output -match 'untrusted location') "wardoff --autostart on failed without the expected trusted-location refusal. Output: $($enableResult.Output)"
- $queryAfterRefusal = Invoke-ExternalCommand -FilePath 'schtasks' -Arguments @('/query', '/tn', 'Wardoff')
- Assert-Condition (($queryAfterRefusal.ExitCode -eq 0) -eq $taskOriginallyPresent) 'wardoff --autostart on changed the Wardoff task state even though it refused an untrusted executable location.'
+ Assert-Condition (-not (Get-SmokeAutostartTaskExists)) 'wardoff --autostart on changed the absent Wardoff task even though it refused an untrusted executable location.'
}
}
finally {
- try {
- $taskPresentAfterTest = (Invoke-ExternalCommand -FilePath 'schtasks' -Arguments @('/query', '/tn', 'Wardoff')).ExitCode -eq 0
- if ($taskOriginallyPresent -and -not $taskPresentAfterTest) {
- $null = Invoke-ExternalCommand -FilePath $binaryPath -Arguments @('--autostart', 'on')
- }
- elseif (-not $taskOriginallyPresent -and $taskPresentAfterTest) {
- $null = Invoke-ExternalCommand -FilePath $binaryPath -Arguments @('--autostart', 'off')
- }
- }
- catch {
+ if ($taskCreatedBySmoke -and (Get-SmokeAutostartTaskExists)) {
+ Assert-Condition (Test-SmokeOwnedAutostartTask -ExpectedIdentity $taskIdentity) 'Refusing to remove the Wardoff task because its definition changed after creation.'
+ $cleanupResult = Invoke-ExternalCommand -FilePath $binaryPath -Arguments @('--autostart', 'off')
+ Assert-Condition ($cleanupResult.ExitCode -eq 0) "wardoff --autostart off cleanup failed with exit code $($cleanupResult.ExitCode)."
+ Assert-Condition (-not (Get-SmokeAutostartTaskExists)) 'Smoke cleanup left the Wardoff task present.'
+ $taskCreatedBySmoke = $false
+ $taskIdentity = $null
}
}
}
@@ -998,6 +1021,8 @@ try {
}
Invoke-TestCase 'Allow releases idle-power requests without stopping the runtime' {
+ Assert-SmokePreflight
+ Assert-Condition ($null -ne $script:BackgroundProcess -and -not $script:BackgroundProcess.HasExited) 'The smoke-owned runtime is no longer alive.'
$repoProcesses = @(Get-RepoWardoffProcesses)
Assert-Condition ($repoProcesses.Count -eq 1) 'Expected one background Wardoff process.'
$allowResult = Invoke-ExternalCommand -FilePath $binaryPath -Arguments @('--allow')
@@ -1025,15 +1050,16 @@ try {
Invoke-TestCase 'Repeated Block reacquires idle-power requests before abrupt process termination' {
foreach ($iteration in 1..2) {
+ Assert-SmokePreflight
+ Assert-Condition ($null -ne $script:BackgroundProcess -and -not $script:BackgroundProcess.HasExited) 'The smoke-owned runtime is no longer alive.'
$blockResult = Invoke-ExternalCommand -FilePath $binaryPath -Arguments @('--block')
Assert-Condition ($blockResult.ExitCode -eq 0) 'Block failed after Allow.'
$activeStatus = Wait-ForActiveWardoffStatus
Assert-Condition ($activeStatus.Status.layers.sleep -eq $true) 'Block did not reacquire idle-power requests.'
}
- # Deliberately do not call the normal cleanup helper: it sends --allow first.
- $repoProcesses = @(Get-RepoWardoffProcesses)
- Assert-Condition ($repoProcesses.Count -eq 1) 'Expected one owned runtime to terminate.'
- $ownedProcess = Get-Process -Id $repoProcesses[0].ProcessId -ErrorAction Stop
+ # Deliberately terminate the owned runtime directly while it is blocked.
+ $ownedProcess = $script:BackgroundProcess
+ Assert-Condition ($null -ne $ownedProcess -and -not $ownedProcess.HasExited) 'Expected the smoke-owned runtime to remain alive before termination.'
Stop-Process -InputObject $ownedProcess -Force -ErrorAction Stop
Assert-Condition ($ownedProcess.WaitForExit(5000)) 'The terminated runtime did not exit within five seconds.'
Assert-Condition (@(Get-RepoWardoffProcesses).Count -eq 0) 'Wardoff was still running after cleanup.'
diff --git a/wardoff.manifest b/wardoff.manifest
index be6fa88..4a8cab7 100644
--- a/wardoff.manifest
+++ b/wardoff.manifest
@@ -1,7 +1,7 @@