pushframe 5.0.0__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.
Files changed (375) hide show
  1. pushframe-5.0.0/.env.sample +12 -0
  2. pushframe-5.0.0/.freebuff/project-id +1 -0
  3. pushframe-5.0.0/.github/workflows/release.yml +130 -0
  4. pushframe-5.0.0/.github/workflows/tests.yml +20 -0
  5. pushframe-5.0.0/.gitignore +207 -0
  6. pushframe-5.0.0/.gsd/dispatch-isolation-sentinel.json +1 -0
  7. pushframe-5.0.0/.planning/MILESTONES.md +106 -0
  8. pushframe-5.0.0/.planning/PROJECT.md +366 -0
  9. pushframe-5.0.0/.planning/REQUIREMENTS.md +105 -0
  10. pushframe-5.0.0/.planning/RETROSPECTIVE.md +151 -0
  11. pushframe-5.0.0/.planning/ROADMAP.md +139 -0
  12. pushframe-5.0.0/.planning/STATE.md +168 -0
  13. pushframe-5.0.0/.planning/WINDOWS.md +35 -0
  14. pushframe-5.0.0/.planning/codebase/ARCHITECTURE.md +271 -0
  15. pushframe-5.0.0/.planning/codebase/CONCERNS.md +211 -0
  16. pushframe-5.0.0/.planning/codebase/CONVENTIONS.md +173 -0
  17. pushframe-5.0.0/.planning/codebase/INTEGRATIONS.md +150 -0
  18. pushframe-5.0.0/.planning/codebase/STACK.md +81 -0
  19. pushframe-5.0.0/.planning/codebase/STRUCTURE.md +161 -0
  20. pushframe-5.0.0/.planning/codebase/TESTING.md +146 -0
  21. pushframe-5.0.0/.planning/config.json +88 -0
  22. pushframe-5.0.0/.planning/debug/knowledge-base.md +37 -0
  23. pushframe-5.0.0/.planning/debug/login-475-null-creds.md +58 -0
  24. pushframe-5.0.0/.planning/debug/resolved/cli-status-verbose-logging.md +117 -0
  25. pushframe-5.0.0/.planning/debug/resolved/inspect-asset-null-fields.md +109 -0
  26. pushframe-5.0.0/.planning/debug/resolved/select-asset-401-unauthorized.md +306 -0
  27. pushframe-5.0.0/.planning/milestones/v1.0-REQUIREMENTS.md +96 -0
  28. pushframe-5.0.0/.planning/milestones/v1.0-ROADMAP.md +104 -0
  29. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-01-PLAN.md +186 -0
  30. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-01-SUMMARY.md +110 -0
  31. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-02-PLAN.md +281 -0
  32. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-02-SUMMARY.md +114 -0
  33. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-CONTEXT.md +161 -0
  34. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-DISCUSSION-LOG.md +75 -0
  35. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-PATTERNS.md +167 -0
  36. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-RESEARCH.md +458 -0
  37. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-REVIEW.md +138 -0
  38. pushframe-5.0.0/.planning/milestones/v1.0-phases/01-toolchain-revival/01-VERIFICATION.md +135 -0
  39. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-01-PLAN.md +210 -0
  40. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-01-SUMMARY.md +120 -0
  41. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-02-PLAN.md +181 -0
  42. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-02-SUMMARY.md +121 -0
  43. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-CONTEXT.md +223 -0
  44. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-DISCUSSION-LOG.md +148 -0
  45. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-LIVE-EVIDENCE.md +75 -0
  46. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-PATTERNS.md +265 -0
  47. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-RESEARCH.md +432 -0
  48. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-REVIEW.md +152 -0
  49. pushframe-5.0.0/.planning/milestones/v1.0-phases/02-live-read-path-verification/02-VERIFICATION.md +156 -0
  50. pushframe-5.0.0/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-01-PLAN.md +320 -0
  51. pushframe-5.0.0/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-01-SUMMARY.md +99 -0
  52. pushframe-5.0.0/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-CONTEXT.md +202 -0
  53. pushframe-5.0.0/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-DISCUSSION-LOG.md +117 -0
  54. pushframe-5.0.0/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-PATTERNS.md +166 -0
  55. pushframe-5.0.0/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-RESEARCH.md +365 -0
  56. pushframe-5.0.0/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-REVIEW.md +143 -0
  57. pushframe-5.0.0/.planning/milestones/v1.0-phases/03-run-docs-verification-report/03-VERIFICATION.md +136 -0
  58. pushframe-5.0.0/.planning/milestones/v1.1-ROADMAP.md +79 -0
  59. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/.gitkeep +1 -0
  60. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-01-PLAN.md +159 -0
  61. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-01-SUMMARY.md +123 -0
  62. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-02-PLAN.md +222 -0
  63. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-02-SUMMARY.md +143 -0
  64. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-03-PLAN.md +225 -0
  65. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-03-SUMMARY.md +130 -0
  66. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-PATTERNS.md +321 -0
  67. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-RESEARCH.md +404 -0
  68. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-REVIEW.md +109 -0
  69. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-SECURITY.md +76 -0
  70. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-UAT.md +89 -0
  71. pushframe-5.0.0/.planning/milestones/v1.1-phases/04-client-transport-seam-for-offline-testability/04-VERIFICATION.md +108 -0
  72. pushframe-5.0.0/.planning/milestones/v2.0-REQUIREMENTS.md +148 -0
  73. pushframe-5.0.0/.planning/milestones/v2.0-ROADMAP.md +200 -0
  74. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-01-PLAN.md +206 -0
  75. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-01-SUMMARY.md +161 -0
  76. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-02-PLAN.md +180 -0
  77. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-02-SUMMARY.md +140 -0
  78. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-CONTEXT.md +183 -0
  79. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-DISCUSSION-LOG.md +97 -0
  80. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-PATTERNS.md +251 -0
  81. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-REVIEW.md +147 -0
  82. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-SECURITY.md +68 -0
  83. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-UAT.md +30 -0
  84. pushframe-5.0.0/.planning/milestones/v2.0-phases/05-cli-skeleton-status/05-VERIFICATION.md +128 -0
  85. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-01-PLAN.md +200 -0
  86. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-01-SUMMARY.md +160 -0
  87. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-02-PLAN.md +129 -0
  88. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-02-SUMMARY.md +126 -0
  89. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-CONTEXT.md +219 -0
  90. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-DISCUSSION-LOG.md +139 -0
  91. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-PATTERNS.md +294 -0
  92. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-RESEARCH.md +473 -0
  93. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-REVIEW.md +197 -0
  94. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-SECURITY.md +71 -0
  95. pushframe-5.0.0/.planning/milestones/v2.0-phases/06-inspect-frame-resolution/06-VERIFICATION.md +96 -0
  96. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-01-PLAN.md +247 -0
  97. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-01-SUMMARY.md +165 -0
  98. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-02-PLAN.md +246 -0
  99. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-02-SUMMARY.md +168 -0
  100. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-03-PLAN.md +196 -0
  101. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-03-SUMMARY.md +104 -0
  102. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-CONTEXT.md +219 -0
  103. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-DISCUSSION-LOG.md +97 -0
  104. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-PATTERNS.md +231 -0
  105. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-REVIEW-FIX.md +63 -0
  106. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-REVIEW.md +190 -0
  107. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-SECURITY.md +75 -0
  108. pushframe-5.0.0/.planning/milestones/v2.0-phases/07-sync-diffing-engine-dry-run-only/07-VERIFICATION.md +95 -0
  109. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-01-PLAN.md +188 -0
  110. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-01-SUMMARY.md +198 -0
  111. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-02-PLAN.md +166 -0
  112. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-02-SUMMARY.md +187 -0
  113. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-03-PLAN.md +161 -0
  114. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-03-SUMMARY.md +188 -0
  115. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-04-PLAN.md +209 -0
  116. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-04-SUMMARY.md +141 -0
  117. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-CONTEXT.md +270 -0
  118. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-DISCUSSION-LOG.md +153 -0
  119. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-LIVE-FINDINGS.md +53 -0
  120. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-PATTERNS.md +377 -0
  121. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-RESEARCH.md +494 -0
  122. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-REVIEW-FIX.md +81 -0
  123. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-REVIEW.md +210 -0
  124. pushframe-5.0.0/.planning/milestones/v2.0-phases/08-destructive-execution-upload-delete-verification/08-VERIFICATION.md +128 -0
  125. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/.gitkeep +1 -0
  126. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-01-PLAN.md +272 -0
  127. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-01-SUMMARY.md +230 -0
  128. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-02-PLAN.md +363 -0
  129. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-02-SUMMARY.md +273 -0
  130. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-CONTEXT.md +177 -0
  131. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-RESEARCH.md +1012 -0
  132. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-REVIEW-FIX.md +108 -0
  133. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-REVIEW.md +211 -0
  134. pushframe-5.0.0/.planning/milestones/v2.0-phases/09-proactive-write-rate-limiter-geo-guard/09-VERIFICATION.md +161 -0
  135. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/.gitkeep +1 -0
  136. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-01-PLAN.md +158 -0
  137. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-01-SUMMARY.md +146 -0
  138. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-02-PLAN.md +164 -0
  139. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-02-SUMMARY.md +122 -0
  140. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-03-PLAN.md +167 -0
  141. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-03-SUMMARY.md +125 -0
  142. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-04-PLAN.md +160 -0
  143. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-04-SUMMARY.md +146 -0
  144. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-CONTEXT.md +220 -0
  145. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-DISCUSSION-LOG.md +123 -0
  146. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-LIVE-FINDINGS.md +208 -0
  147. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-PATTERNS.md +322 -0
  148. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-RESEARCH.md +617 -0
  149. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-SECURITY.md +58 -0
  150. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-UAT.md +206 -0
  151. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/10-VERIFICATION.md +129 -0
  152. pushframe-5.0.0/.planning/milestones/v2.0-phases/10-hide-instead-of-delete-sync-mode/COVERAGE.md +70 -0
  153. pushframe-5.0.0/.planning/milestones/v2.0-quick/260630-qs8-make-main-py-load-a-local-env-file-at-st/260630-qs8-PLAN.md +172 -0
  154. pushframe-5.0.0/.planning/milestones/v2.0-quick/260630-qs8-make-main-py-load-a-local-env-file-at-st/260630-qs8-SUMMARY.md +140 -0
  155. pushframe-5.0.0/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/260708-dt9-PLAN.md +171 -0
  156. pushframe-5.0.0/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/260708-dt9-SUMMARY.md +116 -0
  157. pushframe-5.0.0/.planning/milestones/v2.0-quick/260708-dt9-add-progress-feedback-to-aura-cli-sync-a/deferred-items.md +29 -0
  158. pushframe-5.0.0/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-PLAN.md +353 -0
  159. pushframe-5.0.0/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-SUMMARY.md +197 -0
  160. pushframe-5.0.0/.planning/milestones/v2.0-quick/260708-fyr-batch-refactor-of-sync-apply-write-path-/260708-fyr-VERIFICATION.md +87 -0
  161. pushframe-5.0.0/.planning/milestones/v2.0-quick/README.md +5 -0
  162. pushframe-5.0.0/.planning/milestones/v3.0-REQUIREMENTS.md +235 -0
  163. pushframe-5.0.0/.planning/milestones/v3.0-ROADMAP.md +251 -0
  164. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-01-PLAN.md +493 -0
  165. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-01-SUMMARY.md +233 -0
  166. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-02-PLAN.md +403 -0
  167. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-02-SUMMARY.md +220 -0
  168. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-03-PLAN.md +495 -0
  169. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-03-SUMMARY.md +241 -0
  170. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-04-PLAN.md +364 -0
  171. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-04-SUMMARY.md +198 -0
  172. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-05-PLAN.md +427 -0
  173. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-05-SUMMARY.md +206 -0
  174. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-06-PLAN.md +198 -0
  175. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-06-SUMMARY.md +184 -0
  176. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-CONTEXT.md +417 -0
  177. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-DISCUSSION-LOG.md +228 -0
  178. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-LIVE-FINDINGS.md +449 -0
  179. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-PATTERNS.md +308 -0
  180. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-REVIEW.md +257 -0
  181. pushframe-5.0.0/.planning/milestones/v3.0-phases/11-write-path-reliability-format-support/11-VERIFICATION.md +171 -0
  182. pushframe-5.0.0/.planning/milestones/v4.0-REQUIREMENTS.md +144 -0
  183. pushframe-5.0.0/.planning/milestones/v4.0-ROADMAP.md +202 -0
  184. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-01-PLAN.md +187 -0
  185. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-01-SUMMARY.md +36 -0
  186. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-02-PLAN.md +181 -0
  187. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-02-SUMMARY.md +43 -0
  188. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-03-PLAN.md +162 -0
  189. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-03-SUMMARY.md +35 -0
  190. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-CONTEXT.md +194 -0
  191. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-DECISION-RECORD.md +132 -0
  192. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-DISCUSSION-LOG.md +124 -0
  193. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/16-LIVE-FINDINGS.md +234 -0
  194. pushframe-5.0.0/.planning/milestones/v4.0-phases/16-local-mechanism-spike-decision/COVERAGE.md +24 -0
  195. pushframe-5.0.0/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-01-PLAN.md +233 -0
  196. pushframe-5.0.0/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-01-SUMMARY.md +86 -0
  197. pushframe-5.0.0/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-02-PLAN.md +213 -0
  198. pushframe-5.0.0/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-02-SUMMARY.md +76 -0
  199. pushframe-5.0.0/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-CONTEXT.md +164 -0
  200. pushframe-5.0.0/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-DISCUSS-CHECKPOINT.json +35 -0
  201. pushframe-5.0.0/.planning/milestones/v4.0-phases/17-google-link-album-selection/17-VERIFICATION.md +119 -0
  202. pushframe-5.0.0/.planning/milestones/v4.0-phases/17-google-link-album-selection/COVERAGE.md +23 -0
  203. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-01-PLAN.md +162 -0
  204. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-01-SUMMARY.md +117 -0
  205. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-02-PLAN.md +156 -0
  206. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-02-SUMMARY.md +101 -0
  207. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-03-PLAN.md +172 -0
  208. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-03-SUMMARY.md +120 -0
  209. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-CONTEXT.md +189 -0
  210. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-RESEARCH.md +141 -0
  211. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-UAT.md +83 -0
  212. pushframe-5.0.0/.planning/milestones/v4.0-phases/18-album-frame-mirror-sync-single-pair/18-VERIFICATION.md +101 -0
  213. pushframe-5.0.0/.planning/milestones/v4.0-phases/19-debt-closeout/19-01-PLAN.md +146 -0
  214. pushframe-5.0.0/.planning/milestones/v4.0-phases/19-debt-closeout/19-01-SUMMARY.md +61 -0
  215. pushframe-5.0.0/.planning/milestones/v4.0-phases/19-debt-closeout/19-02-PLAN.md +171 -0
  216. pushframe-5.0.0/.planning/milestones/v4.0-phases/19-debt-closeout/19-02-SUMMARY.md +81 -0
  217. pushframe-5.0.0/.planning/milestones/v4.0-phases/19-debt-closeout/19-CONTEXT.md +197 -0
  218. pushframe-5.0.0/.planning/milestones/v4.0-phases/19-debt-closeout/19-RESEARCH.md +147 -0
  219. pushframe-5.0.0/.planning/milestones/v4.0-phases/19-debt-closeout/19-VERIFICATION.md +63 -0
  220. pushframe-5.0.0/.planning/phases/20-pushframe-rename-migration-repo-switch/20-SUMMARY.md +84 -0
  221. pushframe-5.0.0/.planning/phases/21-debian-package-apt-repo/21-01-PLAN.md +189 -0
  222. pushframe-5.0.0/.planning/phases/21-debian-package-apt-repo/21-01-SUMMARY.md +73 -0
  223. pushframe-5.0.0/.planning/phases/21-debian-package-apt-repo/21-02-PLAN.md +144 -0
  224. pushframe-5.0.0/.planning/phases/21-debian-package-apt-repo/21-02-SUMMARY.md +65 -0
  225. pushframe-5.0.0/.planning/phases/21-debian-package-apt-repo/21-CONTEXT.md +173 -0
  226. pushframe-5.0.0/.planning/phases/21-debian-package-apt-repo/21-RESEARCH.md +103 -0
  227. pushframe-5.0.0/.planning/phases/21-debian-package-apt-repo/21-VERIFICATION.md +64 -0
  228. pushframe-5.0.0/.planning/phases/22-pypi-release-engineering/22-01-PLAN.md +169 -0
  229. pushframe-5.0.0/.planning/phases/22-pypi-release-engineering/22-01-SUMMARY.md +59 -0
  230. pushframe-5.0.0/.planning/phases/22-pypi-release-engineering/22-02-PLAN.md +115 -0
  231. pushframe-5.0.0/.planning/phases/22-pypi-release-engineering/22-02-SUMMARY.md +45 -0
  232. pushframe-5.0.0/.planning/phases/22-pypi-release-engineering/22-CONTEXT.md +57 -0
  233. pushframe-5.0.0/.planning/phases/22-pypi-release-engineering/22-RESEARCH.md +70 -0
  234. pushframe-5.0.0/.planning/phases/22-pypi-release-engineering/22-VERIFICATION.md +59 -0
  235. pushframe-5.0.0/.planning/phases/22-pypi-release-engineering/OPERATOR-STEPS.md +119 -0
  236. pushframe-5.0.0/.planning/research/ALBUM-ACCESS-V4-ADDENDUM.md +90 -0
  237. pushframe-5.0.0/.planning/research/ALBUM-ACCESS.md +491 -0
  238. pushframe-5.0.0/.planning/research/ARCHITECTURE.md +849 -0
  239. pushframe-5.0.0/.planning/research/BROWSER-AUTOMATION.md +508 -0
  240. pushframe-5.0.0/.planning/research/FEATURES.md +249 -0
  241. pushframe-5.0.0/.planning/research/PITFALLS.md +556 -0
  242. pushframe-5.0.0/.planning/research/STACK.md +145 -0
  243. pushframe-5.0.0/.planning/research/SUMMARY.md +178 -0
  244. pushframe-5.0.0/.planning/state.json +28 -0
  245. pushframe-5.0.0/.planning/todos/completed/2026-07-06-promote-debug-flag-to-a-global-cli-convention.md +30 -0
  246. pushframe-5.0.0/.python-version +1 -0
  247. pushframe-5.0.0/CLAUDE.md +305 -0
  248. pushframe-5.0.0/LICENSE +31 -0
  249. pushframe-5.0.0/PKG-INFO +53 -0
  250. pushframe-5.0.0/README.md +570 -0
  251. pushframe-5.0.0/VERIFICATION-REPORT.md +124 -0
  252. pushframe-5.0.0/docs/CLI.md +648 -0
  253. pushframe-5.0.0/docs/agents/domain.md +37 -0
  254. pushframe-5.0.0/docs/agents/issue-tracker.md +34 -0
  255. pushframe-5.0.0/docs/agents/triage-labels.md +15 -0
  256. pushframe-5.0.0/docs/superpowers/specs/2026-07-09-write-rate-limiter-design.md +131 -0
  257. pushframe-5.0.0/main.py +74 -0
  258. pushframe-5.0.0/packaging/control-template +21 -0
  259. pushframe-5.0.0/packaging/lintian-overrides +46 -0
  260. pushframe-5.0.0/packaging/postinst +10 -0
  261. pushframe-5.0.0/packaging/pushframe.copyright +27 -0
  262. pushframe-5.0.0/probes/.gitignore +8 -0
  263. pushframe-5.0.0/probes/README.md +59 -0
  264. pushframe-5.0.0/probes/browser_bootstrap.py +341 -0
  265. pushframe-5.0.0/probes/common.py +42 -0
  266. pushframe-5.0.0/probes/cookie_vault.py +15 -0
  267. pushframe-5.0.0/probes/fidelity_check.py +77 -0
  268. pushframe-5.0.0/probes/rpc_capture.py +81 -0
  269. pushframe-5.0.0/probes/shared_link_probe.py +152 -0
  270. pushframe-5.0.0/pushframe/__init__.py +4 -0
  271. pushframe-5.0.0/pushframe/api/__init__.py +0 -0
  272. pushframe-5.0.0/pushframe/api/accountApi.py +72 -0
  273. pushframe-5.0.0/pushframe/api/activityApi.py +87 -0
  274. pushframe-5.0.0/pushframe/api/assetApi.py +194 -0
  275. pushframe-5.0.0/pushframe/api/baseApi.py +6 -0
  276. pushframe-5.0.0/pushframe/api/frameApi.py +271 -0
  277. pushframe-5.0.0/pushframe/api/notificationApi.py +15 -0
  278. pushframe-5.0.0/pushframe/api/peopleApi.py +25 -0
  279. pushframe-5.0.0/pushframe/api/playlistApi.py +9 -0
  280. pushframe-5.0.0/pushframe/aura.py +182 -0
  281. pushframe-5.0.0/pushframe/aws/__init__.py +0 -0
  282. pushframe-5.0.0/pushframe/aws/awsclient.py +23 -0
  283. pushframe-5.0.0/pushframe/aws/s3client.py +40 -0
  284. pushframe-5.0.0/pushframe/aws/sqsclient.py +33 -0
  285. pushframe-5.0.0/pushframe/cache.py +50 -0
  286. pushframe-5.0.0/pushframe/cli.py +1134 -0
  287. pushframe-5.0.0/pushframe/client.py +267 -0
  288. pushframe-5.0.0/pushframe/exif.py +147 -0
  289. pushframe-5.0.0/pushframe/export.py +53 -0
  290. pushframe-5.0.0/pushframe/google/__init__.py +43 -0
  291. pushframe-5.0.0/pushframe/google/bootstrap.py +134 -0
  292. pushframe-5.0.0/pushframe/google/cache.py +167 -0
  293. pushframe-5.0.0/pushframe/google/client.py +140 -0
  294. pushframe-5.0.0/pushframe/google/enumerate.py +270 -0
  295. pushframe-5.0.0/pushframe/google/manifest.py +111 -0
  296. pushframe-5.0.0/pushframe/google/parsers.py +345 -0
  297. pushframe-5.0.0/pushframe/google/redaction.py +33 -0
  298. pushframe-5.0.0/pushframe/google/vault.py +126 -0
  299. pushframe-5.0.0/pushframe/gsync.py +463 -0
  300. pushframe-5.0.0/pushframe/migration.py +86 -0
  301. pushframe-5.0.0/pushframe/models/__init__.py +0 -0
  302. pushframe-5.0.0/pushframe/models/activity.py +79 -0
  303. pushframe-5.0.0/pushframe/models/asset.py +159 -0
  304. pushframe-5.0.0/pushframe/models/frame.py +105 -0
  305. pushframe-5.0.0/pushframe/models/meta.py +11 -0
  306. pushframe-5.0.0/pushframe/models/person.py +24 -0
  307. pushframe-5.0.0/pushframe/models/user.py +22 -0
  308. pushframe-5.0.0/pushframe/ratelimit.py +222 -0
  309. pushframe-5.0.0/pushframe/reconcile.py +384 -0
  310. pushframe-5.0.0/pushframe/sync.py +1105 -0
  311. pushframe-5.0.0/pushframe/utils/dt.py +15 -0
  312. pushframe-5.0.0/pushframe/utils/io.py +23 -0
  313. pushframe-5.0.0/pushframe/utils/settings.py +59 -0
  314. pushframe-5.0.0/pyproject.toml +47 -0
  315. pushframe-5.0.0/scripts/build-deb.sh +157 -0
  316. pushframe-5.0.0/scripts/make-apt-key.sh +64 -0
  317. pushframe-5.0.0/scripts/publish-apt-repo.sh +149 -0
  318. pushframe-5.0.0/scripts/test-apt-journey-container.sh +66 -0
  319. pushframe-5.0.0/scripts/test-deb-container.sh +58 -0
  320. pushframe-5.0.0/scripts/test-install-journey-container.sh +62 -0
  321. pushframe-5.0.0/tests/conftest.py +32 -0
  322. pushframe-5.0.0/tests/fixtures/asset_unprocessed.json +83 -0
  323. pushframe-5.0.0/tests/fixtures/assets_page1.json +37 -0
  324. pushframe-5.0.0/tests/fixtures/assets_page2.json +37 -0
  325. pushframe-5.0.0/tests/fixtures/assets_placeholders.json +204 -0
  326. pushframe-5.0.0/tests/fixtures/error_envelope.json +4 -0
  327. pushframe-5.0.0/tests/fixtures/frame_detail.json +67 -0
  328. pushframe-5.0.0/tests/fixtures/frames.json +58 -0
  329. pushframe-5.0.0/tests/fixtures/google_rpc_snackc_page.json +3 -0
  330. pushframe-5.0.0/tests/fixtures/google_share_page_sample.html +38 -0
  331. pushframe-5.0.0/tests/fixtures/login.json +13 -0
  332. pushframe-5.0.0/tests/fixtures/probe_af_initdata_sample.html +31 -0
  333. pushframe-5.0.0/tests/offline.py +78 -0
  334. pushframe-5.0.0/tests/test_asset_partial.py +126 -0
  335. pushframe-5.0.0/tests/test_asset_unprocessed.py +76 -0
  336. pushframe-5.0.0/tests/test_aura_logger.py +95 -0
  337. pushframe-5.0.0/tests/test_batch_update_contract.py +130 -0
  338. pushframe-5.0.0/tests/test_cli_apply.py +543 -0
  339. pushframe-5.0.0/tests/test_cli_google_album.py +228 -0
  340. pushframe-5.0.0/tests/test_cli_google_link.py +85 -0
  341. pushframe-5.0.0/tests/test_cli_inspect.py +191 -0
  342. pushframe-5.0.0/tests/test_cli_push_budget_geo.py +304 -0
  343. pushframe-5.0.0/tests/test_cli_reconcile.py +310 -0
  344. pushframe-5.0.0/tests/test_cli_status.py +103 -0
  345. pushframe-5.0.0/tests/test_cli_status_google.py +96 -0
  346. pushframe-5.0.0/tests/test_cli_sync.py +225 -0
  347. pushframe-5.0.0/tests/test_client_rate_limit.py +142 -0
  348. pushframe-5.0.0/tests/test_execute_plan.py +486 -0
  349. pushframe-5.0.0/tests/test_execute_plan_budget_geo.py +359 -0
  350. pushframe-5.0.0/tests/test_fixtures_validity.py +35 -0
  351. pushframe-5.0.0/tests/test_google_cache.py +216 -0
  352. pushframe-5.0.0/tests/test_google_client.py +115 -0
  353. pushframe-5.0.0/tests/test_google_enumerate.py +292 -0
  354. pushframe-5.0.0/tests/test_google_manifest.py +119 -0
  355. pushframe-5.0.0/tests/test_google_parsers.py +103 -0
  356. pushframe-5.0.0/tests/test_google_vault.py +130 -0
  357. pushframe-5.0.0/tests/test_gsync_engine.py +217 -0
  358. pushframe-5.0.0/tests/test_gsync_execute.py +315 -0
  359. pushframe-5.0.0/tests/test_imports.py +55 -0
  360. pushframe-5.0.0/tests/test_migration.py +129 -0
  361. pushframe-5.0.0/tests/test_offline_read_path.py +214 -0
  362. pushframe-5.0.0/tests/test_prep_upload_formats.py +168 -0
  363. pushframe-5.0.0/tests/test_probe_browser.py +83 -0
  364. pushframe-5.0.0/tests/test_probe_shared_link.py +81 -0
  365. pushframe-5.0.0/tests/test_ratelimit.py +265 -0
  366. pushframe-5.0.0/tests/test_read_path.py +170 -0
  367. pushframe-5.0.0/tests/test_reconcile.py +444 -0
  368. pushframe-5.0.0/tests/test_retry_401.py +598 -0
  369. pushframe-5.0.0/tests/test_settings_budget.py +170 -0
  370. pushframe-5.0.0/tests/test_sync_engine.py +231 -0
  371. pushframe-5.0.0/tests/test_version.py +38 -0
  372. pushframe-5.0.0/tests/test_write_endpoints_failloud.py +236 -0
  373. pushframe-5.0.0/tests/test_write_formats_live.py +95 -0
  374. pushframe-5.0.0/tests/test_write_throttling.py +580 -0
  375. pushframe-5.0.0/uv.lock +663 -0
@@ -0,0 +1,12 @@
1
+ # pushframe configuration sample — copy to .env and fill in.
2
+ # PUSHFRAME_* is the primary spelling; legacy AURA_* is still read (one release of grace).
3
+
4
+ PUSHFRAME_PASSWORD=your_password
5
+ PUSHFRAME_EMAIL=your_email
6
+
7
+ # Optional — write budget & geo guard (see README):
8
+ # PUSHFRAME_COUNTRY=FR
9
+ # PUSHFRAME_WRITE_BUDGET_CAPACITY=30
10
+
11
+ # Optional — Google album sync (google-link needs the dedicated Chrome profile):
12
+ # PUSHFRAME_PROBE_CHROME_PROFILE=~/.config/pushframe/chrome-profile
@@ -0,0 +1 @@
1
+ e53d318b-2d71-4a81-a586-ed7cd8bfb4c0
@@ -0,0 +1,130 @@
1
+ # Release engineering (phase 22, REL-01/02, PYI-01/02).
2
+ #
3
+ # One action = push a tag `vX.Y.Z`. The workflow:
4
+ # check — the tag MUST equal pyproject's version AND pushframe.__version__
5
+ # (the release builds nothing on mismatch; version lives in
6
+ # exactly one place, the tag only names the release)
7
+ # pypi-test — upload to TestPyPI via TRUSTED PUBLISHING (OIDC; no PyPI
8
+ # token exists anywhere). Requires the one-time TestPyPI
9
+ # "trusted publisher" declaration — see
10
+ # .planning/phases/22-pypi-release-engineering/OPERATOR-STEPS.md
11
+ # deb — build the hermetic .deb (PUSHFRAME_DEB_OUT_DIR keeps dist/
12
+ # intact), attach to the GitHub Release
13
+ # apt — republish the signed APT repo to gh-pages (signing key from
14
+ # the PUSHFRAME_APT_SIGNING_KEY secret; assembled by the same
15
+ # scripts/publish-apt-repo.sh used locally)
16
+ # pypi — upload to real PyPI, same OIDC recipe (gated on pypi-test)
17
+ #
18
+ # Trusted publishing rules (D-01): `permissions: id-token: write` on every
19
+ # publishing job, `uv publish --trusted-publishing automatic`, publisher
20
+ # declarations must name THIS workflow file (release.yml) and the
21
+ # `release` environment.
22
+ name: release
23
+
24
+ on:
25
+ push:
26
+ tags: ["v*"]
27
+ workflow_dispatch:
28
+
29
+ permissions:
30
+ contents: write # create the GitHub Release, push gh-pages (apt job)
31
+ id-token: write # PyPI/TestPyPI trusted publishing (OIDC)
32
+
33
+ jobs:
34
+ check:
35
+ runs-on: ubuntu-latest
36
+ outputs:
37
+ version: ${{ steps.version.outputs.version }}
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ - name: Assert tag == pyproject == pushframe.__version__
41
+ id: version
42
+ run: |
43
+ set -euo pipefail
44
+ TAG="${GITHUB_REF_NAME#v}"
45
+ PYPROJECT_V=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
46
+ INIT_V=$(python3 -c "import re; print(re.search(r'__version__\s*=\s*\"([^\"]+)\"', open('pushframe/__init__.py').read()).group(1))")
47
+ echo "tag=$TAG pyproject=$PYPROJECT_V __init__=$INIT_V"
48
+ if [ "$TAG" != "$PYPROJECT_V" ] || [ "$TAG" != "$INIT_V" ]; then
49
+ echo "::error::version mismatch — tag v$TAG vs pyproject $PYPROJECT_V vs __init__ $INIT_V"
50
+ exit 1
51
+ fi
52
+ echo "version=$TAG" >> "$GITHUB_OUTPUT"
53
+
54
+ pypi-test:
55
+ needs: check
56
+ runs-on: ubuntu-latest
57
+ environment: release
58
+ steps:
59
+ - uses: actions/checkout@v4
60
+ - uses: astral-sh/setup-uv@v5
61
+ with:
62
+ enable-cache: true
63
+ - name: Build sdist + wheel
64
+ run: uv build
65
+ - name: Upload to TestPyPI (trusted publishing — rehearsal)
66
+ run: uv publish --trusted-publishing automatic
67
+ --publish-url https://test.pypi.org/legacy/ dist/*
68
+
69
+ deb:
70
+ needs: check
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - uses: actions/checkout@v4
74
+ - uses: astral-sh/setup-uv@v5
75
+ with:
76
+ enable-cache: true
77
+ - name: Install uv-managed standalone python (the deb's runtime)
78
+ run: uv python install 3.14
79
+ - name: Build the hermetic .deb
80
+ run: PUSHFRAME_DEB_OUT_DIR=build/release/deb ./scripts/build-deb.sh
81
+ - name: Create the GitHub Release with the .deb asset
82
+ env:
83
+ GH_TOKEN: ${{ github.token }}
84
+ VERSION: ${{ needs.check.outputs.version }}
85
+ run: |
86
+ gh release create "v${VERSION}" \
87
+ --title "pushframe v${VERSION}" \
88
+ --notes "Unofficial community CLI for Aura Frames (not affiliated). \
89
+ Install: see the README (deb / APT / uv tool install)." \
90
+ "build/release/deb/pushframe_${VERSION}_amd64.deb"
91
+
92
+ apt:
93
+ needs: deb
94
+ runs-on: ubuntu-latest
95
+ environment: release
96
+ steps:
97
+ - uses: actions/checkout@v4
98
+ - uses: astral-sh/setup-uv@v5
99
+ - name: Restore the APT signing key from the secret
100
+ env:
101
+ PUSHFRAME_APT_SIGNING_KEY: ${{ secrets.PUSHFRAME_APT_SIGNING_KEY }}
102
+ run: |
103
+ set -euo pipefail
104
+ KEYDIR="$HOME/.config/pushframe-apt-key"
105
+ install -d -m 700 "$KEYDIR"
106
+ printf '%s\n' "$PUSHFRAME_APT_SIGNING_KEY" > "$KEYDIR/signing-key.asc"
107
+ chmod 600 "$KEYDIR/signing-key.asc"
108
+ FP=$(grep -m1 -oE '[A-F0-9]{40}' "$KEYDIR/signing-key.asc")
109
+ printf '%s\n' "$FP" > "$KEYDIR/fingerprint"
110
+ echo "signing key restored: $FP"
111
+ # publish-apt-repo.sh needs gpg + the standalone python for uv pip
112
+ sudo apt-get update -qq && sudo apt-get install -y -qq gnupg >/dev/null
113
+ - name: Rebuild + republish the APT repository (gh-pages)
114
+ run: |
115
+ uv python install 3.14
116
+ ./scripts/publish-apt-repo.sh
117
+
118
+ pypi:
119
+ needs: [pypi-test, deb]
120
+ runs-on: ubuntu-latest
121
+ environment: release
122
+ steps:
123
+ - uses: actions/checkout@v4
124
+ - uses: astral-sh/setup-uv@v5
125
+ with:
126
+ enable-cache: true
127
+ - name: Build sdist + wheel
128
+ run: uv build
129
+ - name: Upload to PyPI (trusted publishing)
130
+ run: uv publish --trusted-publishing automatic dist/*
@@ -0,0 +1,20 @@
1
+ name: tests
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+
8
+ jobs:
9
+ offline-suite:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Install uv
15
+ uses: astral-sh/setup-uv@v5
16
+ with:
17
+ enable-cache: true
18
+
19
+ - name: Run the offline test suite (no credentials, no network)
20
+ run: uv run --extra dev pytest -q -m "not live"
@@ -0,0 +1,207 @@
1
+ .idea/
2
+ flow/
3
+ images/
4
+ mitmproxy/
5
+ images/
6
+ mod_images/
7
+
8
+ # Created by .ignore support plugin (hsz.mobi)
9
+ ### Python template
10
+ # Byte-compiled / optimized / DLL files
11
+ __pycache__/
12
+ *.py[cod]
13
+ *$py.class
14
+
15
+ # C extensions
16
+ *.so
17
+
18
+ # Distribution / packaging
19
+ .Python
20
+ env/
21
+ build/
22
+ develop-eggs/
23
+ dist/
24
+ downloads/
25
+ eggs/
26
+ .eggs/
27
+ lib/
28
+ lib64/
29
+ parts/
30
+ sdist/
31
+ var/
32
+ *.egg-info/
33
+ .installed.cfg
34
+ *.egg
35
+
36
+ # PyInstaller
37
+ # Usually these files are written by a python script from a template
38
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
39
+ *.manifest
40
+ *.spec
41
+
42
+ # Installer logs
43
+ pip-log.txt
44
+ pip-delete-this-directory.txt
45
+
46
+ # Unit test / coverage reports
47
+ htmlcov/
48
+ .tox/
49
+ .coverage
50
+ .coverage.*
51
+ .cache
52
+ nosetests.xml
53
+ coverage.xml
54
+ *,cover
55
+ .hypothesis/
56
+
57
+ # Translations
58
+ *.mo
59
+ *.pot
60
+
61
+ # Django stuff:
62
+ *.log
63
+ local_settings.py
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ target/
77
+
78
+ # IPython Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # pyenv
82
+ # .python-version is committed for uv interpreter pinning (reproducibility, D-02)
83
+ !.python-version
84
+
85
+ # celery beat schedule file
86
+ celerybeat-schedule
87
+
88
+ # dotenv
89
+ .env
90
+
91
+ # Aura runtime output (logs, JSON cache, downloaded images) — D-08
92
+ logs/
93
+ cache/
94
+ asset_images/
95
+
96
+ # virtualenv
97
+ venv/
98
+ ENV/
99
+
100
+ # Spyder project settings
101
+ .spyderproject
102
+
103
+ # Rope project settings
104
+ .ropeproject
105
+ ### VirtualEnv template
106
+ # Virtualenv
107
+ # http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
108
+ [Bb]in
109
+ [Ii]nclude
110
+ [Ll]ib
111
+ [Ll]ib64
112
+ [Ll]ocal
113
+ [Ss]cripts
114
+ pyvenv.cfg
115
+ .venv
116
+ pip-selfcheck.json
117
+
118
+ ### JetBrains template
119
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
120
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
121
+
122
+ # User-specific stuff
123
+ .idea/**/workspace.xml
124
+ .idea/**/tasks.xml
125
+ .idea/**/usage.statistics.xml
126
+ .idea/**/dictionaries
127
+ .idea/**/shelf
128
+
129
+ # AWS User-specific
130
+ .idea/**/aws.xml
131
+
132
+ # Generated files
133
+ .idea/**/contentModel.xml
134
+
135
+ # Sensitive or high-churn files
136
+ .idea/**/dataSources/
137
+ .idea/**/dataSources.ids
138
+ .idea/**/dataSources.local.xml
139
+ .idea/**/sqlDataSources.xml
140
+ .idea/**/dynamic.xml
141
+ .idea/**/uiDesigner.xml
142
+ .idea/**/dbnavigator.xml
143
+
144
+ # Gradle
145
+ .idea/**/gradle.xml
146
+ .idea/**/libraries
147
+
148
+ # Gradle and Maven with auto-import
149
+ # When using Gradle or Maven with auto-import, you should exclude module files,
150
+ # since they will be recreated, and may cause churn. Uncomment if using
151
+ # auto-import.
152
+ # .idea/artifacts
153
+ # .idea/compiler.xml
154
+ # .idea/jarRepositories.xml
155
+ # .idea/modules.xml
156
+ # .idea/*.iml
157
+ # .idea/modules
158
+ # *.iml
159
+ # *.ipr
160
+
161
+ # CMake
162
+ cmake-build-*/
163
+
164
+ # Mongo Explorer plugin
165
+ .idea/**/mongoSettings.xml
166
+
167
+ # File-based project format
168
+ *.iws
169
+
170
+ # IntelliJ
171
+ out/
172
+
173
+ # mpeltonen/sbt-idea plugin
174
+ .idea_modules/
175
+
176
+ # JIRA plugin
177
+ atlassian-ide-plugin.xml
178
+
179
+ # Cursive Clojure plugin
180
+ .idea/replstate.xml
181
+
182
+ # SonarLint plugin
183
+ .idea/sonarlint/
184
+
185
+ # Crashlytics plugin (for Android Studio and IntelliJ)
186
+ com_crashlytics_export_strings.xml
187
+ crashlytics.properties
188
+ crashlytics-build.properties
189
+ fabric.properties
190
+
191
+ # Editor-based Rest Client
192
+ .idea/httpRequests
193
+
194
+ # Android studio 3.1+ serialized cache file
195
+ .idea/caches/build_file_checksums.ser
196
+
197
+ # idea folder, uncomment if you don't need it
198
+ # .idea
199
+
200
+ # Data
201
+ data/
202
+ buffet/
203
+ .planning/milestone.lock
204
+
205
+ # pushframe packaging (phase 21): the upstream template pattern [Ss]cripts
206
+ # (meant for IDE dot-dirs) ignores our real repo scripts/ — re-include it.
207
+ !scripts/
@@ -0,0 +1 @@
1
+ {"isolation":"none","harness_flag":null,"phase":"11","plan":null,"written_at":1788464048467}
@@ -0,0 +1,106 @@
1
+ # Milestones
2
+
3
+ ## v4.0 Local Google Photos Album Sync (Shipped: 2026-09-29)
4
+
5
+ **Phases completed:** 4 phases (16-19), 10 plans, offline suite 349 → **401 tests**
6
+
7
+ **What the milestone delivers:** `aura-cli google-link` / `google-album` / `google-sync` —
8
+ a Google Photos album is mirrored onto an Aura frame through the project's **own** local
9
+ pipeline (no Aura server-side mechanism, no browser at sync time), with a pruned cache +
10
+ persistent manifest keeping steady-state disk proportional to new photos, hide-by-default
11
+ mirror semantics, and the proven v2.0 write path underneath.
12
+
13
+ **Key accomplishments (per phase):**
14
+
15
+ - **Phase 16 — Local Mechanism Spike & Decision (3 plans):** both surviving mechanisms
16
+ probed live against the real albums; byte fidelity settled (a frame photo downloaded back
17
+ through the candidate mechanism base64-MD5-matched the frame's `md5_hash` — MATCH); the
18
+ written decision record selected the browser-cookie-harvest + internal-`batchexecute` RPC
19
+ path (shared link suspected ~500-item ceiling; the authenticated RPC walk has none).
20
+ - **Phase 17 — Google Link & Album Selection (2 plans):** one-time cookie harvest into a
21
+ 0600 vault outside the repo (re-link = same command); `google-album` resolves by
22
+ name/link/id and walks an album completely (300/page `snAcKc` continuation RPC),
23
+ count-matched to the UI and byte-weighted via 1-byte Range requests. 59 Google tests
24
+ offline over injected transports (TEST-02); a live transient (null-payload response)
25
+ hardened into a single bounded retry after execution.
26
+ - **Phase 18 — Album → Frame Mirror Sync, single pair (3 plans):** concurrent `=d`
27
+ downloads into a prunable cache (concurrency never crosses the frame-write seam); a
28
+ demand model rebuilt from listing + manifest — never a cache walk — makes the second run
29
+ zero-upload even after pruning; SAFE-01 aborts on empty/truncated listings; the
30
+ `google-sync` verb is structurally dry-run by default with `--apply`/`--yes` fail-closed
31
+ and hide-only removal (SAFE-02 threshold gate at 20 %). Proven live end-to-end on the
32
+ real pair: 24 uploads, steady-state zero-download/zero-upload, remove→hide (log-evidenced
33
+ `exclude_asset`), re-add→re-show without re-uploading a byte (`18-UAT.md`).
34
+ - **Phase 19 — Debt Closeout (2 plans):** the v1.1-carried debts closed — AWS bucket/pool
35
+ IDs config-ized with unchanged defaults (MOD-02), the loguru sink leak killed with a
36
+ module-level guard, one log file per process (MOD-04), and the two lift-tests-off-network
37
+ candidates closed by exact-value offline assertions (TEST-01 #2/#4).
38
+
39
+ **Live-proven in this milestone:** mechanism decision + fidelity MATCH (16), 24/24 + 1094
40
+ photos enumerated with exact disk weights (17), the full mirror over two real runs with
41
+ log evidence for every write (18). The Google session's null-payload transient (17) became
42
+ the bounded-retry hardening (commit `96ebe50`).
43
+
44
+ **Known limitations carried forward:** Google session expiry is an accepted operational
45
+ cost (re-link is the same command); videos are skipped with a counted line (frame reports
46
+ null md5 for videos — content-hash diffing cannot see them); `google-sync` never deletes
47
+ (hide-only; the gated delete tiers stay with `sync`); single album↔frame pair — many-to-many
48
+ mapping is future requirement GSF-01.
49
+
50
+ ---
51
+
52
+ ## v2.0 Directory-to-Frame Sync (Shipped: 2026-09-02)
53
+
54
+ **Phases completed:** 6 phases, 17 plans, 43 tasks
55
+
56
+ **Key accomplishments:**
57
+
58
+ - Packaged `aura-cli` console script with an argparse subcommand skeleton and a `status` command that reports config health, logs in via the existing Aura facade, and lists account frames as name + id, all covered by an offline test suite driven through the v1.1 `Client`/`Aura` DI seam.
59
+ - Added a `--debug` flag to `aura-cli status` and a CLI-side loguru re-initialization helper that suppresses the two overlapping stderr sinks `Aura._init_logger()` accumulates, closing the only diagnosed UAT gap for Phase 5 without touching the frozen `aura.py`/`main.py`.
60
+ - `aura-cli inspect --frame <name|id>` resolving frames by case-insensitive name substring with exact-id fallback, displaying owner/contributor/asset-count metadata and the first 10 photos, fully proven offline via the existing `Aura(client=...)` DI seam.
61
+ - Confirmed live that `md5_hash` is populated for all 101 pre-existing photo assets but null for all 5 video assets on a real frame — content-hash diffing is viable for Phase 7's photo sync with no fallback needed, but videos would need a local-manifest fallback if they ever enter scope.
62
+ - Pure offline dry-run diff engine (`auraframes/sync.py`): recursive image scanner with base64-MD5 dedup, plus a `compute_plan()` diff function that classifies frame assets into upload/delete/unchanged/frame_no_hash by content hash alone.
63
+ - `aura-cli sync <dir> --frame <name|id>` prints a full, untruncated upload/delete/unchanged dry-run report by wiring Phase 6's frame resolution to Phase 7-01's compute_plan() engine — no apply/execute path exists.
64
+ - Confirmed live that local `S3Client.get_md5` and the frame's reported `md5_hash` use byte-identical base64-MD5 encoding, closing out the last open risk before the dry-run diff engine is trusted.
65
+ - Added AssetPartial model, made all four write/delete endpoints raise RuntimeError on API error/nonzero number_failed, and parameterized Aura.get_sqs(frame_id) to remove the hardcoded test-frame queue id — all offline-tested, no live API calls.
66
+ - Added `execute_plan()` and `ExecutionResult` to `auraframes/sync.py` — the sole mutating counterpart to `compute_plan()`, performing the real upload round-trip and `remove_asset` disassociation with uploads-before-deletes ordering and per-item continue-past-failure, proven entirely offline with injected S3/SQS fakes.
67
+ - Added `--apply`/`--yes` flags and a D-01..D-04 confirmation gate to `aura-cli sync`, wiring Plan 02's `execute_plan()` behind it with real `S3Client()`/`SQSClient()` construction, a D-10 separated success/failure summary, and non-zero exit on any failure — all proven offline with monkeypatched AWS clients and `execute_plan`.
68
+ - Proved the write path live for the first time in this codebase's history: the upload round-trip, `remove_asset`, and `delete_asset`'s blast radius were all confirmed against a real Aura account and frame, with `remove_asset` reaffirmed as `--apply`'s safe default and `delete_asset` confirmed broader-scoped and correctly left unwired.
69
+ - New standalone `auraframes/ratelimit.py` module — injected-clock `WriteBudget` token bucket with JSON persistence, and a fail-open `check_geo` pre-flight guard — fully offline-tested (19 new tests), zero existing source touched.
70
+ - `WriteBudget`/`check_geo` (from Plan 09-01) wired into `execute_plan` and the CLI as the default protection for both `push --apply` and `sync --apply` — env config, four `push` override flags, and two new clean-message exception branches, with the whole 120+ test pre-existing suite staying green.
71
+ - The hide mechanism is confirmed live and non-destructive — but the visibility flag lives in `asset_settings`, not on `Asset.selected`, which corrects the read signal Plan 10-02 was going to build on.
72
+ - The diff engine can now see visibility: hidden assets stay in the listing, `asset.selected` finally means what it says, and every frame asset is classified re-show / unchanged / removal-candidate / already-hidden.
73
+ - `execute_plan` now hides by default, re-shows restored photos under every mode, and can only reach the irreversible primitive if a caller names it.
74
+ - `sync` now hides by default, names the verb it will actually run, and makes irreversible deletion something you have to read a number to do.
75
+
76
+ ---
77
+
78
+ ## v1.0 Revive & Verify (Shipped: 2026-06-30)
79
+
80
+ **Phases completed:** 3 phases, 5 plans, 13 tasks
81
+
82
+ **Key accomplishments:**
83
+
84
+ - Migrated the broken UTF-16 requirements.txt to a uv-managed pyproject.toml, resolved 37 packages on Python 3.14 (all cp314 wheels, no sdist builds), and committed uv.lock for reproducible installs.
85
+ - Migrated the entire `auraframes` model layer to pydantic v2 — AllOptional metaclass replaced by a `make_partial` create_model factory, `pydantic_encoder` replaced by a `model_dump(mode=json)` serializer, `@validator` ported to `@field_validator` — with a committed pytest import smoke test guarding it.
86
+ - Credential-gated pytest harness with fail-loud transport (raise_for_status) and on-disk secret redaction, plus READ-01 login and READ-02 frame-listing live tests that skip cleanly without credentials.
87
+ - Parametrized the real get_all_assets cursor helper and hardened the asset-error/EXIF-write/geocoder trust edges, then added READ-03 (multi-page drain proven by len==total) and READ-04 (download one image, read DateTimeOriginal back from disk) as credential-gated live tests that skip cleanly without creds.
88
+ - Facade-only read-path demo (main.py), README reconciled to verified reality with uv commands + correct env vars, and a repo-root VERIFICATION-REPORT.md backed by a fresh 2026-06-29 live run (4 passed, 9 deselected).
89
+
90
+ ---
91
+
92
+ ## v1.1 Client Transport Seam (Shipped: 2026-07-05)
93
+
94
+ **Phases completed:** 1 phase, 3 plans, 6 tasks
95
+
96
+ **Key accomplishments:**
97
+
98
+ - Added an additive `Client(transport=...)` / `Aura(client=...)` dependency-injection seam so the whole `*Api`/`Aura` read-path stack can be driven through a fake transport — zero-arg callers (`main.py`, existing tests) stay unaffected — and closed the long-standing `# TODO: Can probably use DI` in `aura.py`.
99
+ - Authored 5 sanitized, entirely synthetic fixture JSON files (login, frames, 2-page assets, error envelope) plus a dedicated pytest that hydrates every fixture against `User`/`Frame`/`Asset` to guard against future field-trim regressions.
100
+ - Built a reusable offline test harness (`tests/offline.py`) — an `httpx.MockTransport` router keyed by resolved path with a per-test overrides mechanism — plus a 5-test offline mirror of `test_read_path.py` covering login headers, frame hydration, pagination drain, and both error-raise paths.
101
+ - Lifted most of `test_read_path.py`'s assertions off the live network: default `pytest` now exercises login, listing, pagination, and error handling with zero credentials/network, while the `@live` suite stays byte-identical and remains the drift oracle.
102
+ - Verified: 7/7 must-haves passed, UAT 8/8 passed with 0 issues.
103
+
104
+ **Known gaps carried to v2.0:** Architecture-review candidates #2 (authenticated value) and #4 (injected config) — the remaining "lift tests off the live network" slice; pre-existing `Aura._init_logger()` loguru sink leak on repeated construction (flagged by code review, not fixed). *(Both closed in v4.0's Phase 19 — 2026-09-29.)*
105
+
106
+ ---