jleechanorg-pr-automation 0.1.1__py3-none-any.whl → 0.2.45__py3-none-any.whl

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 (46) hide show
  1. jleechanorg_pr_automation/STORAGE_STATE_TESTING_PROTOCOL.md +326 -0
  2. jleechanorg_pr_automation/__init__.py +64 -9
  3. jleechanorg_pr_automation/automation_safety_manager.py +306 -95
  4. jleechanorg_pr_automation/automation_safety_wrapper.py +13 -19
  5. jleechanorg_pr_automation/automation_utils.py +87 -65
  6. jleechanorg_pr_automation/check_codex_comment.py +7 -1
  7. jleechanorg_pr_automation/codex_branch_updater.py +21 -9
  8. jleechanorg_pr_automation/codex_config.py +70 -3
  9. jleechanorg_pr_automation/jleechanorg_pr_monitor.py +1954 -234
  10. jleechanorg_pr_automation/logging_utils.py +86 -0
  11. jleechanorg_pr_automation/openai_automation/__init__.py +3 -0
  12. jleechanorg_pr_automation/openai_automation/codex_github_mentions.py +1111 -0
  13. jleechanorg_pr_automation/openai_automation/debug_page_content.py +88 -0
  14. jleechanorg_pr_automation/openai_automation/oracle_cli.py +364 -0
  15. jleechanorg_pr_automation/openai_automation/test_auth_restoration.py +244 -0
  16. jleechanorg_pr_automation/openai_automation/test_codex_comprehensive.py +355 -0
  17. jleechanorg_pr_automation/openai_automation/test_codex_integration.py +254 -0
  18. jleechanorg_pr_automation/orchestrated_pr_runner.py +516 -0
  19. jleechanorg_pr_automation/tests/__init__.py +0 -0
  20. jleechanorg_pr_automation/tests/test_actionable_counting_matrix.py +84 -86
  21. jleechanorg_pr_automation/tests/test_attempt_limit_logic.py +124 -0
  22. jleechanorg_pr_automation/tests/test_automation_marker_functions.py +175 -0
  23. jleechanorg_pr_automation/tests/test_automation_over_running_reproduction.py +9 -11
  24. jleechanorg_pr_automation/tests/test_automation_safety_limits.py +91 -79
  25. jleechanorg_pr_automation/tests/test_automation_safety_manager_comprehensive.py +53 -53
  26. jleechanorg_pr_automation/tests/test_codex_actor_matching.py +1 -1
  27. jleechanorg_pr_automation/tests/test_fixpr_prompt.py +54 -0
  28. jleechanorg_pr_automation/tests/test_fixpr_return_value.py +140 -0
  29. jleechanorg_pr_automation/tests/test_graphql_error_handling.py +26 -26
  30. jleechanorg_pr_automation/tests/test_model_parameter.py +317 -0
  31. jleechanorg_pr_automation/tests/test_orchestrated_pr_runner.py +697 -0
  32. jleechanorg_pr_automation/tests/test_packaging_integration.py +127 -0
  33. jleechanorg_pr_automation/tests/test_pr_filtering_matrix.py +246 -193
  34. jleechanorg_pr_automation/tests/test_pr_monitor_eligibility.py +354 -0
  35. jleechanorg_pr_automation/tests/test_pr_targeting.py +102 -7
  36. jleechanorg_pr_automation/tests/test_version_consistency.py +51 -0
  37. jleechanorg_pr_automation/tests/test_workflow_specific_limits.py +202 -0
  38. jleechanorg_pr_automation/tests/test_workspace_dispatch_missing_dir.py +119 -0
  39. jleechanorg_pr_automation/utils.py +81 -56
  40. jleechanorg_pr_automation-0.2.45.dist-info/METADATA +864 -0
  41. jleechanorg_pr_automation-0.2.45.dist-info/RECORD +45 -0
  42. jleechanorg_pr_automation-0.1.1.dist-info/METADATA +0 -222
  43. jleechanorg_pr_automation-0.1.1.dist-info/RECORD +0 -23
  44. {jleechanorg_pr_automation-0.1.1.dist-info → jleechanorg_pr_automation-0.2.45.dist-info}/WHEEL +0 -0
  45. {jleechanorg_pr_automation-0.1.1.dist-info → jleechanorg_pr_automation-0.2.45.dist-info}/entry_points.txt +0 -0
  46. {jleechanorg_pr_automation-0.1.1.dist-info → jleechanorg_pr_automation-0.2.45.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,326 @@
1
+ # Storage State Testing Protocol
2
+ ## Codex Branch Updater - Production Readiness Validation
3
+
4
+ **AI Consensus Recommendation:** Storage State API with self-healing login flow (Gemini Pro, Gemini Flash, Perplexity consulted)
5
+
6
+ **Decision Date:** 2025-12-10
7
+ **Target Production:** Cron job every 4 hours
8
+
9
+ ---
10
+
11
+ ## Implementation Summary
12
+
13
+ ### What Changed
14
+ 1. **Immediate auth state save after re-authentication** (line 104-105)
15
+ 2. **Clear logging for session validation** (lines 89, 92)
16
+ 3. **BrowserContext passed to ensure_logged_in()** (line 263)
17
+ 4. **Dual save strategy**: Immediate save after re-auth + final save after tasks
18
+
19
+ ### Self-Healing Flow
20
+ ```
21
+ 1. Load storage_state.json (if exists)
22
+ 2. Navigate to chatgpt.com/codex
23
+ 3. Check if task list visible (implicit session check)
24
+ 4. IF NOT LOGGED IN:
25
+ a. Execute manual login flow
26
+ b. IMMEDIATELY save new auth state
27
+ c. Log success
28
+ 5. Execute task processing
29
+ 6. Save final auth state (redundant but safe)
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Testing Phase 1: Local Validation (Days 1-2)
35
+
36
+ ### Pre-Test Setup
37
+ ```bash
38
+ # Delete existing auth state to start fresh
39
+ rm ~/.chatgpt_codex_auth_state.json
40
+
41
+ # Run first time (will require manual login)
42
+ python automation/jleechanorg_pr_automation/codex_branch_updater.py
43
+ ```
44
+
45
+ **Expected Output:**
46
+ ```
47
+ ℹ️ No saved authentication state found. Fresh login required.
48
+ 🔐 ChatGPT Codex credentials not found...
49
+ ✅ Credentials saved locally (chmod 600).
50
+ [Login flow executes]
51
+ 💾 New authentication state saved immediately to ~/.chatgpt_codex_auth_state.json.
52
+ [Tasks processed]
53
+ 💾 Final authentication state saved to ~/.chatgpt_codex_auth_state.json.
54
+ ```
55
+
56
+ ### Test Cases
57
+
58
+ #### TC1: Fresh Auth State Persistence
59
+ ```bash
60
+ # Run 1: Manual login
61
+ python automation/jleechanorg_pr_automation/codex_branch_updater.py
62
+
63
+ # Run 2: Should use saved state
64
+ python automation/jleechanorg_pr_automation/codex_branch_updater.py
65
+ ```
66
+
67
+ **Expected:**
68
+ - Run 1: Creates `~/.chatgpt_codex_auth_state.json`
69
+ - Run 2: Loads state, logs "✅ Session still valid"
70
+
71
+ **Failure Mode:** If Run 2 requires login, OAuth session didn't persist (critical issue).
72
+
73
+ #### TC2: Session Expiration Handling
74
+ ```bash
75
+ # Manually corrupt the auth state to simulate expiration
76
+ echo '{"cookies": [], "origins": []}' > ~/.chatgpt_codex_auth_state.json
77
+
78
+ # Run automation
79
+ python automation/jleechanorg_pr_automation/codex_branch_updater.py
80
+ ```
81
+
82
+ **Expected:**
83
+ ```
84
+ 🔄 Loading saved authentication state from ~/.chatgpt_codex_auth_state.json
85
+ ⚠️ Session expired. Re-authenticating...
86
+ [Login flow executes]
87
+ 💾 New authentication state saved immediately to ~/.chatgpt_codex_auth_state.json.
88
+ ```
89
+
90
+ **Failure Mode:** If automation crashes instead of re-authenticating, self-healing failed.
91
+
92
+ #### TC3: Browser Crash Recovery
93
+ ```bash
94
+ # Run automation, kill browser mid-process
95
+ python automation/jleechanorg_pr_automation/codex_branch_updater.py &
96
+ PID=$!
97
+ sleep 10
98
+ kill -9 $PID
99
+
100
+ # Verify auth state wasn't corrupted
101
+ ls -la ~/.chatgpt_codex_auth_state.json
102
+ cat ~/.chatgpt_codex_auth_state.json | jq .
103
+
104
+ # Re-run automation
105
+ python automation/jleechanorg_pr_automation/codex_branch_updater.py
106
+ ```
107
+
108
+ **Expected:** Auth state remains valid from last successful save.
109
+
110
+ ---
111
+
112
+ ## Testing Phase 2: Cron Simulation (Days 3-9)
113
+
114
+ ### Setup 4-Hour Cron Job
115
+ ```bash
116
+ # Create test cron script
117
+ cat > /tmp/test_codex_automation.sh << 'EOF'
118
+ #!/bin/bash
119
+ # Define PROJECT_ROOT - adjust to your project location
120
+ PROJECT_ROOT="${PROJECT_ROOT:-$HOME/projects/your-project}"
121
+ LOG_DIR="$HOME/tmp/automation_tests"
122
+ mkdir -p "$LOG_DIR"
123
+ TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
124
+ LOG_FILE="$LOG_DIR/codex_run_${TIMESTAMP}.log"
125
+
126
+ cd "$PROJECT_ROOT"
127
+ python automation/jleechanorg_pr_automation/codex_branch_updater.py > "$LOG_FILE" 2>&1
128
+ EXIT_CODE=$?
129
+
130
+ echo "Exit Code: $EXIT_CODE" >> "$LOG_FILE"
131
+ echo "Timestamp: $(date)" >> "$LOG_FILE"
132
+ EOF
133
+
134
+ chmod +x /tmp/test_codex_automation.sh
135
+
136
+ # Add to crontab (every 4 hours)
137
+ crontab -l > /tmp/current_cron
138
+ echo "0 */4 * * * /tmp/test_codex_automation.sh" >> /tmp/current_cron
139
+ crontab /tmp/current_cron
140
+ ```
141
+
142
+ ### Monitoring Script
143
+ ```bash
144
+ #!/bin/bash
145
+ # monitor_auth_state.sh - Track session persistence
146
+
147
+ LOG_DIR="$HOME/tmp/automation_tests"
148
+ REPORT_FILE="$LOG_DIR/session_health_report.txt"
149
+
150
+ echo "=== Session Health Report - $(date) ===" > "$REPORT_FILE"
151
+ echo "" >> "$REPORT_FILE"
152
+
153
+ # Count total runs
154
+ TOTAL_RUNS=$(ls -1 "$LOG_DIR"/codex_run_*.log 2>/dev/null | wc -l)
155
+ echo "Total Runs: $TOTAL_RUNS" >> "$REPORT_FILE"
156
+
157
+ # Count re-authentications
158
+ REAUTH_COUNT=$(grep -l "Session expired. Re-authenticating" "$LOG_DIR"/codex_run_*.log 2>/dev/null | wc -l)
159
+ echo "Re-authentications: $REAUTH_COUNT" >> "$REPORT_FILE"
160
+
161
+ # Calculate success rate
162
+ if [ "$TOTAL_RUNS" -gt 0 ]; then
163
+ REAUTH_RATE=$(awk "BEGIN {printf \"%.2f\", ($REAUTH_COUNT / $TOTAL_RUNS) * 100}")
164
+ echo "Re-authentication Rate: ${REAUTH_RATE}%" >> "$REPORT_FILE"
165
+ fi
166
+
167
+ # Count failures
168
+ FAILURE_COUNT=$(grep -l "Exit Code: [^0]" "$LOG_DIR"/codex_run_*.log 2>/dev/null | wc -l)
169
+ echo "Failures: $FAILURE_COUNT" >> "$REPORT_FILE"
170
+
171
+ # Find last successful run
172
+ LAST_SUCCESS=$(grep -l "Exit Code: 0" "$LOG_DIR"/codex_run_*.log 2>/dev/null | tail -1)
173
+ if [ -n "$LAST_SUCCESS" ]; then
174
+ echo "Last Success: $(basename "$LAST_SUCCESS")" >> "$REPORT_FILE"
175
+ fi
176
+
177
+ cat "$REPORT_FILE"
178
+ ```
179
+
180
+ ### Acceptance Criteria (7-Day Test)
181
+ - **Minimum runs:** 42 (7 days × 6 runs/day)
182
+ - **Re-authentication rate:** <5% (≤2 re-auths in 42 runs)
183
+ - **Failure rate:** 0% (all runs complete successfully)
184
+ - **Auth state file size:** >500 bytes (indicates real session data)
185
+
186
+ **Success Threshold:**
187
+ ```bash
188
+ # Run after 7 days
189
+ bash monitor_auth_state.sh
190
+
191
+ # Expected output:
192
+ # Total Runs: 42
193
+ # Re-authentications: 0-2
194
+ # Re-authentication Rate: 0.00-4.76%
195
+ # Failures: 0
196
+ ```
197
+
198
+ **Failure Trigger (implement daemon mode if any occur):**
199
+ - Re-authentication rate >20% within 7 days
200
+ - Any hard failures (non-zero exit codes)
201
+ - Session persistence <24 hours consistently
202
+
203
+ ---
204
+
205
+ ## Testing Phase 3: Edge Cases (Day 10)
206
+
207
+ ### EC1: Network Interruption
208
+ ```bash
209
+ # Disconnect Wi-Fi mid-run, reconnect after 30s
210
+ # Automation should fail gracefully with clear error
211
+ ```
212
+
213
+ ### EC2: ChatGPT Service Degradation
214
+ ```bash
215
+ # Monitor behavior during Cloudflare rate limiting
216
+ # Should log clear error, not corrupt auth state
217
+ ```
218
+
219
+ ### EC3: Multi-Day Session Persistence
220
+ ```bash
221
+ # Wait 72 hours without running automation
222
+ # Next run should use saved state OR gracefully re-auth
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Production Deployment Checklist
228
+
229
+ ### Pre-Deployment
230
+ - [ ] All Phase 1 test cases pass
231
+ - [ ] 7-day cron simulation shows <5% re-auth rate
232
+ - [ ] Auth state file permissions verified (600)
233
+ - [ ] Logs directory exists with proper permissions
234
+ - [ ] Credentials file exists at `~/.chatgpt_codex_credentials.json`
235
+
236
+ ### Deployment
237
+ ```bash
238
+ # Production cron entry
239
+ crontab -e
240
+
241
+ # Add (runs at :00 of every 4th hour: 00:00, 04:00, 08:00, 12:00, 16:00, 20:00)
242
+ # NOTE: Replace $PROJECT_ROOT with your actual project path
243
+ 0 */4 * * * cd $PROJECT_ROOT && python automation/jleechanorg_pr_automation/codex_branch_updater.py >> ~/tmp/automation/codex_automation.log 2>&1
244
+ ```
245
+
246
+ ### Post-Deployment Monitoring (First 7 Days)
247
+ ```bash
248
+ # Daily health check
249
+ tail -n 100 ~/tmp/automation/codex_automation.log
250
+
251
+ # Look for:
252
+ # ✅ "Session still valid" (good - using saved state)
253
+ # ⚠️ "Session expired" (acceptable if <20% of runs)
254
+ # ❌ Python tracebacks (critical - investigate immediately)
255
+ ```
256
+
257
+ ### Alerting Setup
258
+ ```bash
259
+ # Add to cron script for email alerts on failure
260
+ if [ $EXIT_CODE -ne 0 ]; then
261
+ echo "Codex automation failed. Check log: $LOG_FILE" | mail -s "Codex Automation Failure" your@email.com
262
+ fi
263
+ ```
264
+
265
+ ---
266
+
267
+ ## Rollback Plan
268
+
269
+ ### If Storage State Fails (>20% re-auth rate)
270
+ 1. Document exact failure pattern from logs
271
+ 2. Implement daemon mode architecture:
272
+ - Chrome process managed by systemd/launchd
273
+ - CDP reconnection logic
274
+ - Health check endpoint
275
+ 3. Preserve this implementation as fallback
276
+
277
+ ### If OAuth Fundamentally Incompatible
278
+ ```bash
279
+ # Option: Use Google OAuth2 token refresh
280
+ # Requires ChatGPT API key instead of web automation
281
+ # Research ChatGPT Codex API availability
282
+ ```
283
+
284
+ ---
285
+
286
+ ## Success Metrics (Production - First 30 Days)
287
+
288
+ | Metric | Target | Actual | Status |
289
+ |--------|--------|--------|--------|
290
+ | Uptime | >95% | TBD | 🟡 |
291
+ | Re-auth Rate | <5% | TBD | 🟡 |
292
+ | False Positives | 0 | TBD | 🟡 |
293
+ | Manual Intervention | <1/week | TBD | 🟡 |
294
+ | Auth State File Corruption | 0 | TBD | 🟡 |
295
+
296
+ **Green Light for Production:** All targets met after 30 days
297
+ **Yellow Light (Monitor):** Uptime 90-95%, re-auth 5-10%
298
+ **Red Light (Implement Daemon):** Uptime <90%, re-auth >10%
299
+
300
+ ---
301
+
302
+ ## Multi-Model AI Recommendations Summary
303
+
304
+ ### Gemini Pro
305
+ - **Stance:** Storage State API is "standard, idiomatic way"
306
+ - **Key Insight:** Self-healing flow with immediate auth state save
307
+ - **Daemon Mode:** Only if Storage State "completely unworkable"
308
+
309
+ ### Gemini Flash
310
+ - **Stance:** Test Storage State first (most elegant)
311
+ - **Critical Warning:** Google OAuth may not persist via cookies alone
312
+ - **Recommendation:** Rigorous testing required
313
+
314
+ ### Perplexity
315
+ - **Stance:** Ship manual login now, defer complexity
316
+ - **Concern:** Solo dev maintenance burden
317
+ - **Pragmatic View:** Occasional manual login cheaper than daemon infrastructure
318
+
319
+ ### Our Decision
320
+ **Implement Storage State API NOW** (Gemini Pro's approach), validate over 7 days, implement daemon mode only if re-auth rate exceeds 20%.
321
+
322
+ **Rationale:**
323
+ - Low risk (graceful degradation)
324
+ - High reward (fully autonomous if successful)
325
+ - Data-driven decision point (7-day test)
326
+ - Incremental path to daemon mode if needed
@@ -5,28 +5,83 @@ This package provides comprehensive PR monitoring and automation capabilities wi
5
5
  safety features, intelligent filtering, and cross-process synchronization.
6
6
  """
7
7
 
8
- from .jleechanorg_pr_monitor import JleechanorgPRMonitor
8
+ import re
9
+ from importlib.metadata import PackageNotFoundError, version as dist_version
10
+ from pathlib import Path
11
+ from typing import Optional
12
+
9
13
  from .automation_safety_manager import AutomationSafetyManager
14
+ from .jleechanorg_pr_monitor import JleechanorgPRMonitor
10
15
  from .utils import (
11
16
  SafeJSONManager,
12
- setup_logging,
13
- get_email_config,
14
- validate_email_config,
15
17
  get_automation_limits,
18
+ get_email_config,
16
19
  json_manager,
20
+ setup_logging,
21
+ validate_email_config,
17
22
  )
18
23
 
19
- __version__ = "0.1.1"
24
+ _PROJECT_SECTION_RE = re.compile(r"^\s*\[project\]\s*$")
25
+ _SECTION_RE = re.compile(r"^\s*\[[^\]]+\]\s*$")
26
+ _VERSION_RE = re.compile(r'^\s*version\s*=\s*"([^"]+)"\s*$')
27
+
28
+
29
+ def _version_from_pyproject(pyproject_path: Path) -> Optional[str]:
30
+ if not pyproject_path.exists():
31
+ return None
32
+
33
+ in_project_section = False
34
+ for line in pyproject_path.read_text(encoding="utf-8").splitlines():
35
+ if _PROJECT_SECTION_RE.match(line):
36
+ in_project_section = True
37
+ continue
38
+ if in_project_section and _SECTION_RE.match(line):
39
+ in_project_section = False
40
+ continue
41
+ if not in_project_section:
42
+ continue
43
+
44
+ match = _VERSION_RE.match(line)
45
+ if match:
46
+ version = match.group(1).strip()
47
+ return version or None
48
+
49
+ return None
50
+
51
+
52
+ def _resolve_version() -> str:
53
+ # Prefer the source-tree pyproject.toml when present (avoids mismatches with any
54
+ # separately-installed distribution on the machine).
55
+ try:
56
+ # __file__ = automation/jleechanorg_pr_automation/__init__.py
57
+ # parents[0] = automation/jleechanorg_pr_automation
58
+ # parents[1] = automation
59
+ pyproject_path = Path(__file__).resolve().parents[1] / "pyproject.toml"
60
+ version = _version_from_pyproject(pyproject_path)
61
+ if version is not None:
62
+ return version
63
+ except Exception:
64
+ pass
65
+
66
+ try:
67
+ return dist_version("jleechanorg-pr-automation")
68
+ except PackageNotFoundError:
69
+ return "0.2.39"
70
+ except Exception:
71
+ return "0.2.39"
72
+
73
+
74
+ __version__ = _resolve_version()
20
75
  __author__ = "jleechan"
21
76
  __email__ = "jlee@jleechan.org"
22
77
 
23
78
  __all__ = [
24
- "JleechanorgPRMonitor",
25
79
  "AutomationSafetyManager",
80
+ "JleechanorgPRMonitor",
26
81
  "SafeJSONManager",
27
- "setup_logging",
28
- "get_email_config",
29
- "validate_email_config",
30
82
  "get_automation_limits",
83
+ "get_email_config",
31
84
  "json_manager",
85
+ "setup_logging",
86
+ "validate_email_config",
32
87
  ]