pushframe 5.1.1__tar.gz → 5.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pushframe-5.1.1 → pushframe-5.1.2}/CHANGELOG.md +22 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/PKG-INFO +1 -1
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/__init__.py +1 -1
- {pushframe-5.1.1 → pushframe-5.1.2}/pyproject.toml +1 -1
- pushframe-5.1.2/tests/conftest.py +100 -0
- pushframe-5.1.2/tests/test_network_guard.py +41 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_retry_401.py +6 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_version.py +1 -1
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_write_throttling.py +23 -15
- {pushframe-5.1.1 → pushframe-5.1.2}/uv.lock +1 -1
- pushframe-5.1.1/tests/conftest.py +0 -32
- {pushframe-5.1.1 → pushframe-5.1.2}/.env.sample +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.freebuff/project-id +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.github/workflows/release.yml +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.github/workflows/tests.yml +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.gitignore +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.gsd/dispatch-isolation-sentinel.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/MILESTONES.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/PROJECT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/REQUIREMENTS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/RETROSPECTIVE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/ROADMAP.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/STATE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/WINDOWS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/codebase/ARCHITECTURE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/codebase/CONCERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/codebase/CONVENTIONS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/codebase/INTEGRATIONS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/codebase/STACK.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/codebase/STRUCTURE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/codebase/TESTING.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/config.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/debug/knowledge-base.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/debug/login-475-null-creds.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/debug/resolved/cli-status-verbose-logging.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/debug/resolved/inspect-asset-null-fields.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/debug/resolved/select-asset-401-unauthorized.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-REQUIREMENTS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-ROADMAP.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/01-toolchain-revival/01-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-LIVE-EVIDENCE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-ROADMAP.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/.gitkeep +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-03-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-03-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-SECURITY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-UAT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-REQUIREMENTS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-ROADMAP.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-SECURITY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-UAT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-SECURITY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-03-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-03-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-REVIEW-FIX.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-SECURITY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-03-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-03-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-04-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-04-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-LIVE-FINDINGS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-REVIEW-FIX.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/.gitkeep +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-REVIEW-FIX.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/.gitkeep +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-03-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-03-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-04-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-04-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-LIVE-FINDINGS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-SECURITY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-UAT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/COVERAGE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/260630-qs8-make-main-py-load-a-local-env-file-at-st/260630-qs8-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/260630-qs8-make-main-py-load-a-local-env-file-at-st/260630-qs8-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/260708-dt9-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/260708-dt9-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/deferred-items.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v2.0-quick/README.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-REQUIREMENTS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-ROADMAP.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-03-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-03-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-04-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-04-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-05-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-05-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-06-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-06-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-LIVE-FINDINGS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-PATTERNS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-REVIEW.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-REQUIREMENTS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-ROADMAP.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-03-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-03-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-DECISION-RECORD.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-DISCUSSION-LOG.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-LIVE-FINDINGS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/COVERAGE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-DISCUSS-CHECKPOINT.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/17-google-link-album-selection/COVERAGE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-03-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-03-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-UAT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/19-debt-closeout/19-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/19-debt-closeout/19-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/19-debt-closeout/19-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/19-debt-closeout/19-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/19-debt-closeout/19-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/19-debt-closeout/19-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v4.0-phases/19-debt-closeout/19-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-REQUIREMENTS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-ROADMAP.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/20-pushframe-rename-migration-repo-switch/20-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/21-debian-package-apt-repo/21-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/21-debian-package-apt-repo/21-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/21-debian-package-apt-repo/21-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/21-debian-package-apt-repo/21-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/21-debian-package-apt-repo/21-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/21-debian-package-apt-repo/21-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/21-debian-package-apt-repo/21-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/22-pypi-release-engineering/22-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/22-pypi-release-engineering/22-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/22-pypi-release-engineering/22-02-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/22-pypi-release-engineering/22-02-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/22-pypi-release-engineering/22-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/22-pypi-release-engineering/22-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/22-pypi-release-engineering/22-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/milestones/v5.0-phases/22-pypi-release-engineering/OPERATOR-STEPS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/23-config-wizard-precedence/23-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/23-config-wizard-precedence/23-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/23-config-wizard-precedence/23-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/23-config-wizard-precedence/23-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/23-config-wizard-precedence/23-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/24-token-first-sessions-preflight-sweep-sec-01-03-prf-01-02/24-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/24-token-first-sessions-preflight-sweep-sec-01-03-prf-01-02/24-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/24-token-first-sessions-preflight-sweep-sec-01-03-prf-01-02/24-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/24-token-first-sessions-preflight-sweep-sec-01-03-prf-01-02/24-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/24-token-first-sessions-preflight-sweep-sec-01-03-prf-01-02/24-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/25-multi-frame-mappings-systemd-user-scheduling-mtf-01-03-tmr-01-03/25-01-PLAN.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/25-multi-frame-mappings-systemd-user-scheduling-mtf-01-03-tmr-01-03/25-01-SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/25-multi-frame-mappings-systemd-user-scheduling-mtf-01-03-tmr-01-03/25-CONTEXT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/25-multi-frame-mappings-systemd-user-scheduling-mtf-01-03-tmr-01-03/25-RESEARCH.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/phases/25-multi-frame-mappings-systemd-user-scheduling-mtf-01-03-tmr-01-03/25-VERIFICATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/research/ALBUM-ACCESS-V4-ADDENDUM.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/research/ALBUM-ACCESS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/research/ARCHITECTURE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/research/BROWSER-AUTOMATION.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/research/FEATURES.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/research/PITFALLS.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/research/STACK.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/research/SUMMARY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/state.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.planning/todos/completed/2026-07-06-promote-debug-flag-to-a-global-cli-convention.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/.python-version +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/CLAUDE.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/LICENSE +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/README.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/SECURITY.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/VERIFICATION-REPORT.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/docs/CLI.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/docs/agents/domain.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/docs/agents/issue-tracker.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/docs/agents/triage-labels.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/docs/superpowers/specs/2026-07-09-write-rate-limiter-design.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/main.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/packaging/control-template +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/packaging/lintian-overrides +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/packaging/postinst +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/packaging/pushframe.copyright +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/probes/.gitignore +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/probes/README.md +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/probes/browser_bootstrap.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/probes/common.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/probes/cookie_vault.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/probes/fidelity_check.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/probes/rpc_capture.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/probes/shared_link_probe.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/__init__.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/accountApi.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/activityApi.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/assetApi.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/baseApi.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/frameApi.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/notificationApi.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/peopleApi.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/api/playlistApi.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/aura.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/aws/__init__.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/aws/awsclient.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/aws/s3client.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/aws/sqsclient.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/cache.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/cli.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/client.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/config_store.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/doctor.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/exif.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/export.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/__init__.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/bootstrap.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/cache.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/client.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/enumerate.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/manifest.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/parsers.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/redaction.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/google/vault.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/gsync.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/migration.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/models/__init__.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/models/activity.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/models/asset.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/models/frame.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/models/meta.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/models/person.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/models/user.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/pairs.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/preflight.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/ratelimit.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/reconcile.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/schedule.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/session.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/sync.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/utils/dt.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/utils/io.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/pushframe/utils/settings.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/scripts/build-deb.sh +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/scripts/make-apt-key.sh +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/scripts/publish-apt-repo.sh +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/scripts/test-apt-journey-container.sh +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/scripts/test-config-journey-container.sh +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/scripts/test-deb-container.sh +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/scripts/test-install-journey-container.sh +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/scripts/test-multipair-journey-container.sh +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/asset_unprocessed.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/assets_page1.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/assets_page2.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/assets_placeholders.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/error_envelope.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/frame_detail.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/frames.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/google_rpc_snackc_page.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/google_share_page_sample.html +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/login.json +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/fixtures/probe_af_initdata_sample.html +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/offline.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_asset_partial.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_asset_unprocessed.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_aura_logger.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_batch_update_contract.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_apply.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_google_album.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_google_link.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_inspect.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_push_budget_geo.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_reconcile.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_status.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_status_google.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_cli_sync.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_client_rate_limit.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_config_wizard.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_doctor.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_execute_plan.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_execute_plan_budget_geo.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_fixtures_validity.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_google_cache.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_google_client.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_google_enumerate.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_google_manifest.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_google_parsers.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_google_vault.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_gsync_all.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_gsync_engine.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_gsync_execute.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_imports.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_logout.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_migration.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_offline_read_path.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_pairs.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_preflight_sweep.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_prep_upload_formats.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_probe_browser.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_probe_shared_link.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_ratelimit.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_read_path.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_reconcile.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_schedule.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_session.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_settings_budget.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_settings_resolution.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_sync_engine.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_write_endpoints_failloud.py +0 -0
- {pushframe-5.1.1 → pushframe-5.1.2}/tests/test_write_formats_live.py +0 -0
|
@@ -14,6 +14,28 @@ frames; it is not affiliated with Aura Frames Inc.
|
|
|
14
14
|
|
|
15
15
|
## [Unreleased]
|
|
16
16
|
|
|
17
|
+
## [5.1.2] — 2026-09-30
|
|
18
|
+
|
|
19
|
+
### Changed (tests)
|
|
20
|
+
|
|
21
|
+
- **Network guard**: `httpx.Client` is patched for the whole test session
|
|
22
|
+
so any client built WITHOUT an explicit transport gets a blocking one —
|
|
23
|
+
except when built inside a live-marked test (the only legitimate
|
|
24
|
+
real-network shape). An offline test that reaches the real network now
|
|
25
|
+
fails loudly instead of silently depending on a local .env (the relogin
|
|
26
|
+
masking that kept the tests workflow red from v5.1.0 to 5.1.1), and a
|
|
27
|
+
local .env can no longer masquerade as a live posture.
|
|
28
|
+
|
|
29
|
+
### Fixed (tests)
|
|
30
|
+
|
|
31
|
+
- **The `tests` workflow is green again** (red on master since v5.1.0 —
|
|
32
|
+
not a 5.1.1 regression): the 9 offline tests of the 401-retry and
|
|
33
|
+
write-throttling suites relied on the pre-phase-24 re-login default
|
|
34
|
+
(`aura.login`); phase 24 made the default token-aware, which fails
|
|
35
|
+
named off-TTY without env credentials — exactly the CI case. A local
|
|
36
|
+
`.env` with real credentials masked it locally. All 9 `execute_plan`
|
|
37
|
+
call sites now pin `relogin=aura.login`; zero product code changed.
|
|
38
|
+
|
|
17
39
|
## [5.1.1] — 2026-09-30
|
|
18
40
|
|
|
19
41
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pushframe
|
|
3
|
-
Version: 5.1.
|
|
3
|
+
Version: 5.1.2
|
|
4
4
|
Summary: Unofficial community CLI for Aura Frames digital photo frames (sync a local folder or a Google Photos album; not affiliated with Aura Frames Inc.)
|
|
5
5
|
Project-URL: Homepage, https://github.com/coredmp95/pushframe
|
|
6
6
|
Project-URL: Repository, https://github.com/coredmp95/pushframe
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
# pushframe — unofficial community CLI for Aura Frames (not affiliated).
|
|
2
2
|
# Version single source for the CLI surface (REL-02); pyproject keeps the
|
|
3
3
|
# packaging metadata version and tests/test_version.py enforces lockstep.
|
|
4
|
-
__version__ = "5.1.
|
|
4
|
+
__version__ = "5.1.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pushframe"
|
|
3
|
-
version = "5.1.
|
|
3
|
+
version = "5.1.2"
|
|
4
4
|
description = "Unofficial community CLI for Aura Frames digital photo frames (sync a local folder or a Google Photos album; not affiliated with Aura Frames Inc.)"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
|
|
6
|
+
# Load AURA_EMAIL / AURA_PASSWORD from a local .env so the live read-path tests
|
|
7
|
+
# can run without exporting shell vars. Shell-exported vars still win (override
|
|
8
|
+
# defaults to False), and a missing .env is a no-op — so a credential-less
|
|
9
|
+
# checkout still skips the live suite cleanly (D-02).
|
|
10
|
+
load_dotenv()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# ---------------------------------------------------------------------------
|
|
14
|
+
# Network guard (CI hardening, 2026-09-30). An OFFLINE test must never reach
|
|
15
|
+
# the real pushd API. Phase 24's token-aware relogin default let 9 offline
|
|
16
|
+
# tests silently depend on a local .env (the env-password branch) and fail in
|
|
17
|
+
# CI — the mock was bypassed because nothing blocked the DEFAULT transport.
|
|
18
|
+
# While no live test is actually going to run, patch httpx.Client so any
|
|
19
|
+
# client built WITHOUT an explicit transport (the real-network shape) gets a
|
|
20
|
+
# blocking one: every request fails loudly. offline_aura-style tests are
|
|
21
|
+
# unaffected (they pass transport= explicitly); `live` runs opt out.
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
_NETWORK_GUARD_ACTIVE = False
|
|
24
|
+
_CURRENT_ITEM = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def pytest_runtest_setup(item):
|
|
28
|
+
"""Track the current item so the guard can allow live-marked tests."""
|
|
29
|
+
global _CURRENT_ITEM
|
|
30
|
+
_CURRENT_ITEM = item
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def pytest_runtest_teardown(item):
|
|
34
|
+
global _CURRENT_ITEM
|
|
35
|
+
_CURRENT_ITEM = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _blocking_transport():
|
|
39
|
+
import httpx
|
|
40
|
+
|
|
41
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
42
|
+
raise RuntimeError(
|
|
43
|
+
'NETWORK GUARD: an offline test reached the real network at '
|
|
44
|
+
f'{request.url}. Offline tests must go through '
|
|
45
|
+
'tests.offline.offline_aura (explicit transport) or an injected '
|
|
46
|
+
'seam. If a product default now escapes the seam, fix the TEST '
|
|
47
|
+
'(e.g. pin relogin=aura.login), not the product.'
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return httpx.MockTransport(handler)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def pytest_collection_modifyitems(config, items):
|
|
54
|
+
"""Install the network guard for the whole session. It is ALWAYS active:
|
|
55
|
+
every transport-less httpx.Client gets a blocking transport, EXCEPT when
|
|
56
|
+
built DURING a live-marked test (the only legitimate real-network shape:
|
|
57
|
+
the session `aura` fixture constructs the client inside the live test,
|
|
58
|
+
so the marker is checked at construction time — not at collection, which
|
|
59
|
+
would let a local .env masquerade as a live posture for offline tests)."""
|
|
60
|
+
global _NETWORK_GUARD_ACTIVE
|
|
61
|
+
import httpx
|
|
62
|
+
|
|
63
|
+
original = httpx.Client.__init__
|
|
64
|
+
|
|
65
|
+
def guarded(self, *args, **kwargs):
|
|
66
|
+
live_running = _CURRENT_ITEM is not None and \
|
|
67
|
+
_CURRENT_ITEM.get_closest_marker('live') is not None
|
|
68
|
+
# httpx.Client's signature is keyword-only; `app` implies transport.
|
|
69
|
+
if not live_running and 'transport' not in kwargs and 'app' not in kwargs:
|
|
70
|
+
kwargs['transport'] = _blocking_transport()
|
|
71
|
+
return original(self, *args, **kwargs)
|
|
72
|
+
|
|
73
|
+
# Detection lives ON the patched __init__ (NOT an importable conftest
|
|
74
|
+
# flag): pytest registers conftest under its own module name, so a test
|
|
75
|
+
# importing tests.conftest would see a second, never-mutated copy.
|
|
76
|
+
guarded._network_guard = True
|
|
77
|
+
httpx.Client.__init__ = guarded
|
|
78
|
+
_NETWORK_GUARD_ACTIVE = True
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@pytest.fixture(scope="session")
|
|
82
|
+
def aura():
|
|
83
|
+
"""Authenticated Aura session shared by all live read-path tests.
|
|
84
|
+
|
|
85
|
+
Reads AURA_EMAIL/AURA_PASSWORD from the environment and skips the whole
|
|
86
|
+
live suite cleanly when either is unset (D-02), so a credential-less
|
|
87
|
+
checkout stays green. When credentials are present it instantiates Aura()
|
|
88
|
+
and performs the login (READ-01's act, D-03), returning the authenticated
|
|
89
|
+
instance so all live tests reuse one session.
|
|
90
|
+
"""
|
|
91
|
+
email = os.getenv("AURA_EMAIL")
|
|
92
|
+
password = os.getenv("AURA_PASSWORD")
|
|
93
|
+
if not email or not password:
|
|
94
|
+
pytest.skip("AURA_EMAIL/AURA_PASSWORD not set; skipping live Aura API tests")
|
|
95
|
+
|
|
96
|
+
from pushframe.aura import Aura
|
|
97
|
+
|
|
98
|
+
instance = Aura()
|
|
99
|
+
instance.login()
|
|
100
|
+
return instance
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""The network guard itself (2026-09-30 CI hardening).
|
|
2
|
+
|
|
3
|
+
Meta-test: when the guard is installed, a client built WITHOUT an explicit
|
|
4
|
+
transport — the real-network shape — must fail loudly instead of reaching
|
|
5
|
+
pushd. When it is not installed (a genuine live posture), there is nothing
|
|
6
|
+
to assert and the test skips.
|
|
7
|
+
"""
|
|
8
|
+
import httpx
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _guard_installed() -> bool:
|
|
13
|
+
"""True when conftest's blocking transport is patched onto httpx.Client.
|
|
14
|
+
|
|
15
|
+
Detection reads the attribute the hook sets on the patched __init__
|
|
16
|
+
itself — importing the flag from conftest would read a second module
|
|
17
|
+
copy (pytest registers conftest under its own name).
|
|
18
|
+
"""
|
|
19
|
+
return getattr(httpx.Client.__init__, '_network_guard', False)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_guard_blocks_transportless_clients_in_offline_posture():
|
|
23
|
+
if not _guard_installed():
|
|
24
|
+
pytest.skip('guard not installed — a genuine live posture is selected')
|
|
25
|
+
client = httpx.Client(base_url='https://api.pushd.com/v5')
|
|
26
|
+
with pytest.raises(RuntimeError, match='NETWORK GUARD'):
|
|
27
|
+
client.get('/frames.json') # any request: the transport itself blocks
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_guard_never_blocks_explicit_transports():
|
|
31
|
+
"""offline_aura's shape: transport= passes through untouched."""
|
|
32
|
+
calls = []
|
|
33
|
+
|
|
34
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
35
|
+
calls.append(request.url.path)
|
|
36
|
+
return httpx.Response(200, json={'ok': True})
|
|
37
|
+
|
|
38
|
+
client = httpx.Client(transport=httpx.MockTransport(handler))
|
|
39
|
+
r = client.get('https://api.pushd.com/v5/frames.json')
|
|
40
|
+
assert r.status_code == 200
|
|
41
|
+
assert calls == ['/v5/frames.json']
|
|
@@ -169,6 +169,7 @@ def test_401_on_select_asset_recovers_after_relogin_and_resend(tmp_path):
|
|
|
169
169
|
plan, aura, FRAME_ID, s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
170
170
|
sleep=lambda *_: None, throttle_seconds=0, chunk_delay_seconds=0,
|
|
171
171
|
asset_probe=_ordered_probe(['absent']),
|
|
172
|
+
relogin=aura.login, # pinned: this test encodes the PRE-phase-24 password default
|
|
172
173
|
)
|
|
173
174
|
|
|
174
175
|
assert result.upload_succeeded == 1
|
|
@@ -197,6 +198,7 @@ def test_two_item_chunk_401_resends_only_the_genuinely_absent_item(tmp_path):
|
|
|
197
198
|
plan, aura, FRAME_ID, s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
198
199
|
sleep=lambda *_: None, throttle_seconds=0, chunk_delay_seconds=0,
|
|
199
200
|
asset_probe=_ordered_probe(['landed', 'absent']),
|
|
201
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
200
202
|
)
|
|
201
203
|
|
|
202
204
|
assert result.items_already_landed == 1
|
|
@@ -364,6 +366,7 @@ def test_retried_upload_chunk_consumes_5_budget_tokens_total(tmp_path):
|
|
|
364
366
|
plan, aura, FRAME_ID, s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
365
367
|
sleep=lambda *_: None, throttle_seconds=0, chunk_delay_seconds=0,
|
|
366
368
|
asset_probe=_ordered_probe(['absent']),
|
|
369
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
367
370
|
budget=budget, clock=lambda: T0, wait_on_budget=False,
|
|
368
371
|
)
|
|
369
372
|
|
|
@@ -391,6 +394,7 @@ def test_all_items_already_landed_consumes_3_tokens_no_resend_charge(tmp_path):
|
|
|
391
394
|
plan, aura, FRAME_ID, s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
392
395
|
sleep=lambda *_: None, throttle_seconds=0, chunk_delay_seconds=0,
|
|
393
396
|
asset_probe=_ordered_probe(['landed', 'landed']),
|
|
397
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
394
398
|
budget=budget, clock=lambda: T0, wait_on_budget=False,
|
|
395
399
|
)
|
|
396
400
|
|
|
@@ -419,6 +423,7 @@ def test_probe_itself_never_charges_budget_regardless_of_chunk_size(tmp_path):
|
|
|
419
423
|
plan, aura, FRAME_ID, s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
420
424
|
sleep=lambda *_: None, throttle_seconds=0, chunk_delay_seconds=0,
|
|
421
425
|
asset_probe=_ordered_probe(['landed', 'landed', 'landed']),
|
|
426
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
422
427
|
budget=budget, clock=lambda: T0, wait_on_budget=False,
|
|
423
428
|
)
|
|
424
429
|
|
|
@@ -453,6 +458,7 @@ def test_budget_exhausted_propagates_from_retry_acquire_with_no_bypass(tmp_path)
|
|
|
453
458
|
plan, aura, FRAME_ID, s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
454
459
|
sleep=lambda *_: None, throttle_seconds=0, chunk_delay_seconds=0,
|
|
455
460
|
asset_probe=_ordered_probe(['absent']),
|
|
461
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
456
462
|
budget=budget, clock=lambda: T0, wait_on_budget=False,
|
|
457
463
|
)
|
|
458
464
|
|
|
@@ -19,7 +19,7 @@ PYPROJECT = Path(__file__).resolve().parent.parent / "pyproject.toml"
|
|
|
19
19
|
def test_version_is_first_distribution_release():
|
|
20
20
|
"""The current distribution release (moved off 0.1.0 at 5.0.0; page
|
|
21
21
|
metadata fix shipped in 5.0.4)."""
|
|
22
|
-
assert __version__ == "5.1.
|
|
22
|
+
assert __version__ == "5.1.2"
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
def test_version_matches_pyproject_single_source():
|
|
@@ -304,11 +304,13 @@ def test_run_of_plain_401_write_failures_aborts_batch(tmp_path):
|
|
|
304
304
|
overrides[SELECT_ASSET_PATH] = httpx.Response(401, json={'error': 'unauthorized'})
|
|
305
305
|
s3 = _FakeS3Client()
|
|
306
306
|
|
|
307
|
+
aura = offline_aura(overrides=overrides)
|
|
307
308
|
with pytest.raises(ConsecutiveWriteFailureError) as exc_info:
|
|
308
309
|
execute_plan(
|
|
309
|
-
plan,
|
|
310
|
+
plan, aura, FRAME_ID,
|
|
310
311
|
s3_client=s3, sqs_client=_FakeSQSClient(),
|
|
311
312
|
throttle_seconds=0, sleep=lambda *_: None,
|
|
313
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
312
314
|
)
|
|
313
315
|
|
|
314
316
|
err = exc_info.value
|
|
@@ -351,12 +353,13 @@ def test_interspersed_failures_do_not_trip_the_backstop(tmp_path, monkeypatch):
|
|
|
351
353
|
|
|
352
354
|
monkeypatch.setattr(aura.asset_api, 'batch_update', _flaky_batch_update)
|
|
353
355
|
|
|
354
|
-
result =
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
356
|
+
result = execute_plan(
|
|
357
|
+
plan, aura, FRAME_ID,
|
|
358
|
+
s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
359
|
+
throttle_seconds=0, sleep=lambda *_: None,
|
|
360
|
+
batch_size=1,
|
|
361
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
362
|
+
)
|
|
360
363
|
|
|
361
364
|
# No abort: all 8 attempted, 4 succeeded, 4 recorded per-item (D-08 intact).
|
|
362
365
|
assert result.upload_succeeded == 4
|
|
@@ -390,12 +393,13 @@ def test_a_success_resets_the_consecutive_run(tmp_path, monkeypatch):
|
|
|
390
393
|
|
|
391
394
|
monkeypatch.setattr(aura.asset_api, 'batch_update', _flaky_batch_update)
|
|
392
395
|
|
|
393
|
-
result =
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
396
|
+
result = execute_plan(
|
|
397
|
+
plan, aura, FRAME_ID,
|
|
398
|
+
s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
399
|
+
throttle_seconds=0, sleep=lambda *_: None,
|
|
400
|
+
batch_size=1,
|
|
401
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
402
|
+
)
|
|
399
403
|
|
|
400
404
|
assert result.upload_succeeded == 1
|
|
401
405
|
assert len(result.upload_failures) == 8
|
|
@@ -444,11 +448,13 @@ def test_max_consecutive_failures_zero_disables_the_backstop(tmp_path):
|
|
|
444
448
|
overrides = _ok_overrides()
|
|
445
449
|
overrides[SELECT_ASSET_PATH] = httpx.Response(401, json={'error': 'unauthorized'})
|
|
446
450
|
|
|
451
|
+
aura = offline_aura(overrides=overrides)
|
|
447
452
|
result = execute_plan(
|
|
448
|
-
plan,
|
|
453
|
+
plan, aura, FRAME_ID,
|
|
449
454
|
s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
450
455
|
throttle_seconds=0, sleep=lambda *_: None,
|
|
451
456
|
max_consecutive_failures=0,
|
|
457
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
452
458
|
)
|
|
453
459
|
|
|
454
460
|
assert result.upload_succeeded == 0
|
|
@@ -469,12 +475,14 @@ def test_consecutive_run_spans_upload_and_delete_phases(tmp_path):
|
|
|
469
475
|
overrides[SELECT_ASSET_PATH] = httpx.Response(401, json={'error': 'unauthorized'})
|
|
470
476
|
overrides[REMOVE_ASSET_PATH] = httpx.Response(401, json={'error': 'unauthorized'})
|
|
471
477
|
|
|
478
|
+
aura = offline_aura(overrides=overrides)
|
|
472
479
|
with pytest.raises(ConsecutiveWriteFailureError) as exc_info:
|
|
473
480
|
execute_plan(
|
|
474
|
-
plan,
|
|
481
|
+
plan, aura, FRAME_ID,
|
|
475
482
|
s3_client=_FakeS3Client(), sqs_client=_FakeSQSClient(),
|
|
476
483
|
throttle_seconds=0, sleep=lambda *_: None,
|
|
477
484
|
batch_size=1,
|
|
485
|
+
relogin=aura.login, # pinned: pre-phase-24 password default
|
|
478
486
|
)
|
|
479
487
|
|
|
480
488
|
err = exc_info.value
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
from dotenv import load_dotenv
|
|
5
|
-
|
|
6
|
-
# Load AURA_EMAIL / AURA_PASSWORD from a local .env so the live read-path tests
|
|
7
|
-
# can run without exporting shell vars. Shell-exported vars still win (override
|
|
8
|
-
# defaults to False), and a missing .env is a no-op — so a credential-less
|
|
9
|
-
# checkout still skips the live suite cleanly (D-02).
|
|
10
|
-
load_dotenv()
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@pytest.fixture(scope="session")
|
|
14
|
-
def aura():
|
|
15
|
-
"""Authenticated Aura session shared by all live read-path tests.
|
|
16
|
-
|
|
17
|
-
Reads AURA_EMAIL/AURA_PASSWORD from the environment and skips the whole
|
|
18
|
-
live suite cleanly when either is unset (D-02), so a credential-less
|
|
19
|
-
checkout stays green. When credentials are present it instantiates Aura()
|
|
20
|
-
and performs the login (READ-01's act, D-03), returning the authenticated
|
|
21
|
-
instance so all live tests reuse one session.
|
|
22
|
-
"""
|
|
23
|
-
email = os.getenv("AURA_EMAIL")
|
|
24
|
-
password = os.getenv("AURA_PASSWORD")
|
|
25
|
-
if not email or not password:
|
|
26
|
-
pytest.skip("AURA_EMAIL/AURA_PASSWORD not set; skipping live Aura API tests")
|
|
27
|
-
|
|
28
|
-
from pushframe.aura import Aura
|
|
29
|
-
|
|
30
|
-
instance = Aura()
|
|
31
|
-
instance.login()
|
|
32
|
-
return instance
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pushframe-5.1.1 → pushframe-5.1.2}/.planning/debug/resolved/select-asset-401-unauthorized.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|