Elmar request from Telegram: Luci Auth Portal works, but Google Workspace auth expires almost weekly because current Google OAuth app is still in Testing/trial. Add proactive wa...
StateDoneNext ActionClosedOwnerLuciRuntimeClosedAge18d ago
Ticket is done; runtime is closed.·profile codex · cwd /home/lucienne/workspace/mission-control · uptime 17d 18h · last activity 17d 16h ago
Description
MC-4253
Elmar request from Telegram:
Luci Auth Portal works, but Google Workspace auth expires almost weekly because current Google OAuth app is still in Testing/trial. Add proactive warning before it expires, ideally T-1 day.
Current state discovered:
- Auth portal: /home/lucienne/workspace/scripts/auth_portal.py on port 8788.
- OAuth health task: /home/lucienne/workspace/tasks/oauth-health-check.md runs every 30 minutes and calls /home/lucienne/workspace/scripts/oauth_health_check.py.
- Current health check only alerts after token failure/needs_reauth.
- GWS credentials live at ~/.config/gws/credentials.json and currently have refresh_token but no explicit expiry/issued_at metadata.
- Google Testing-mode refresh tokens commonly expire after ~7 days; Google may return refresh_token_expires_in on token exchange, but if not, we should estimate from auth time / credential mtime.
Implement:
1. When Auth Portal completes GWS exchange, persist non-secret metadata alongside credentials, e.g. authorized_at and approximate refresh_token_expires_at. If token response includes refresh_token_expires_in, use it; otherwise default to 7 days for testing-mode GWS, configurable constant/env.
2. Enhance oauth_health_check.py to compute GWS days remaining from metadata/fallback mtime and include it in oauth-health-status.json.
3. Send Telegram warning before expiry, especially at T-1 day. Deduplicate so it does not spam every 30 minutes. Ideally warn once at <=48h and again at <=24h or at minimum <=24h.
4. Update Auth Portal status UI/API to display approximate GWS expiry / days remaining and warning state.
5. Keep existing failure alert behavior.
6. Add/adjust tests or at least deterministic script-level unit coverage for expiry calculation/dedup logic.
7. Verify by running the health check in dry/quiet mode and checking status JSON fields. Do not expose tokens/secrets in logs.
Acceptance:
- Elmar receives a proactive warning roughly 1 day before GWS Testing-mode token expiry with link to Auth Portal: http://100.118.207.3:8788
- Dashboard/Auth Portal shows the estimated GWS expiry.
- Failure alerts still work and no Telegram spam loop occurs.
Owner: Luci
Runtime/profile: MC worker / Codex or Sonnet dev-loop
Expected check-in: within 24h
Completion gate: code committed+pushed, health check manually run successfully, status JSON has expiry fields, and alert dedupe verified.
Activity
done
INTERACTIVE
Luci is working...
Details —
Done
· High
· Luci
▼
SState
Done
Closed
PPeople
TTiming / Details▼
telegram (human)
Mission Control
18d ago
16d ago
Advanced / Operator evidence
RRouting owner
ROperator console
Ticket is done; runtime is closed.terminal_state_reapprofile codex · cwd /home/lucienne/workspace/mission-control · uptime 17d 18h · last activity 17d 16h agoMC is visibility-only. Hermes Luci launches and gates work outside MC, then mirrors evidence/status here.Raw console: luci · codex/openai/gpt-5.5
WWorkflow
Start Dev Review + QA ▾
Select phases to include:
Agents
Review Gates
Decision
WAT routing: choose an agent, review gate, or decision. Buttons use the live runtime when one is attached.
Ticket picked up by Luci via MC dispatcher.
MC-4253: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
Work this ticket in the live tmux runtime. Use DONE:, REVIEW:, or QUESTION: when you need MC to reflect the next state.
luci18d ago
[failed_to_inject] runtime_busy: Ticket runtime is not ready for input (status=running). Wait for the current turn to finish, queue the message, or explicitly interrupt/restart the runtime before sending more terminal i
Ticket picked up by Luci via MC dispatcher.
MC-4253: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
Work this ticket in the live tmux runtime. Use DONE:, REVIEW:, or QUESTION: when you need MC to reflect the next state.
luci18d ago
Ticket runtime send failed while dispatching.
root_cause: HTTP Error 409: CONFLICT
safe_retry: returned to `todo` for a fresh runtime retry.
human_input_required: no
system18d ago
RUNTIME TERMINAL STATE (MC-3482 contract)
status: warning
summary: Ticket runtime send failed; parked for automatic recovery.
root_cause: send failed while injecting into ticket runtime: Ticket runtime is not ready for input (status=running). Wait for the current turn to finish, queue the message, or explicitly interrupt/restart the runtime before sending more terminal input.
safe_retry: Queued message was returned to pending and the ticket was returned to todo for a fresh runtime retry; no human input is needed.
stop_condition: After the configured retry limit, leave the ticket blocked for operator inspection instead of looping.
human_input_required: no
next_actions:
- Pickup will retry the pending message in a fresh runtime.
- Inspect runtime/send only if the retry fails again.
artifacts:
- ticket:MC-4253
luci18d ago
Luci picking up this ticket (background worker).
system18d ago
RUNTIME TERMINAL STATE (MC-3482 contract)
status: error
summary: Ticket runtime send failed; parked for automatic recovery.
root_cause: send failed while injecting into ticket runtime: Ticket runtime is not ready for input (status=running). Wait for the current turn to finish, queue the message, or explicitly interrupt/restart the runtime before sending more terminal input.
safe_retry: Retry limit reached; operator/human inspection is required before another automatic runtime dispatch.
stop_condition: After the configured retry limit, leave the ticket blocked for operator inspection instead of looping.
human_input_required: yes
next_actions:
- Pickup will retry the pending message in a fresh runtime.
- Inspect runtime/send only if the retry fails again.
artifacts:
- ticket:MC-4253
luci18d ago
Luci picking up this ticket (background worker).
luci18d ago
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
luci18d ago
Ticket runtime send failed while dispatching.
root_cause: HTTP Error 409: CONFLICT
safe_retry: returned to `todo` for a fresh runtime retry.
human_input_required: no
system18d ago
RUNTIME TERMINAL STATE (MC-3482 contract)
status: error
summary: Ticket runtime send failed; parked for automatic recovery.
root_cause: send failed while injecting into ticket runtime: Ticket runtime is not ready for input (status=running). Wait for the current turn to finish, queue the message, or explicitly interrupt/restart the runtime before sending more terminal input.
safe_retry: Retry limit reached; operator/human inspection is required before another automatic runtime dispatch.
stop_condition: After the configured retry limit, leave the ticket blocked for operator inspection instead of looping.
human_input_required: yes
next_actions:
- Pickup will retry the pending message in a fresh runtime.
- Inspect runtime/send only if the retry fails again.
artifacts:
- ticket:MC-4253
luci18d ago
Luci picking up this ticket (background worker).
luci18d ago
[failed_to_inject] runtime_busy: Ticket runtime is not ready for input (status=running). Wait for the current turn to finish, queue the message, or explicitly interrupt/restart the runtime before sending more terminal i
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
luci18d ago
[failed_to_inject] runtime_busy: Ticket runtime is not ready for input (status=running). Wait for the current turn to finish, queue the message, or explicitly interrupt/restart the runtime before sending more terminal i
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
luci18d ago
Ticket runtime send failed while dispatching.
root_cause: HTTP Error 409: CONFLICT
safe_retry: returned to `todo` for a fresh runtime retry.
human_input_required: no
system18d ago
RUNTIME TERMINAL STATE (MC-3482 contract)
status: error
summary: Ticket runtime send failed; parked for automatic recovery.
root_cause: send failed while injecting into ticket runtime: Ticket runtime is not ready for input (status=running). Wait for the current turn to finish, queue the message, or explicitly interrupt/restart the runtime before sending more terminal input.
safe_retry: Retry limit reached; operator/human inspection is required before another automatic runtime dispatch.
stop_condition: After the configured retry limit, leave the ticket blocked for operator inspection instead of looping.
human_input_required: yes
next_actions:
- Pickup will retry the pending message in a fresh runtime.
- Inspect runtime/send only if the retry fails again.
artifacts:
- ticket:MC-4253
luci18d ago
Luci picking up this ticket (background worker).
luci18d ago
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
luci18d ago
[failed_to_inject] runtime_busy: Ticket runtime is not ready for input (status=running). Wait for the current turn to finish, queue the message, or explicitly interrupt/restart the runtime before sending more terminal i
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
luci18d ago
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
[system]: Ticket moved to Todo: Add proactive T-1 GWS OAuth expiry warning to Luci Auth Portal
Luci18d ago
DONE: MC-4253 is complete and reported via mc_report_done.›Explain this codebasegpt-5.5 xhigh · ~/workspace/mission-control
Committed and pushed f5cb5403 to origin/master. Implemented GWS OAuth metadata
at full /auth/gws/exchange, explicit last_refresh_at on manual refresh,
proactive Telegram warning dedupe at <=48h and <=24h, Auth Portal expiry
display, OAuth state validation, owner-only atomic credential/metadata writes,
and deterministic tests.
Verified:
- pytest -q scripts/tests/test_oauth_gws_expiry.py → 9 passed
- python3 scripts/oauth_health_check.py --quiet → GWS OK, M365 OK
- status JSON includes GWS expiry fields; current legacy token correctly shows
unknown
- Auth Portal restarted and /api/status exposes expiry fields
- desktop/mobile browser smoke showed GWS card displaying: Refresh token
expiry: Unknown until next full Google re-auth
- graphify update . completed for mission-control
Current note: because the existing GWS token predates this metadata, expiry
remains unknown until the next full Google re-auth. After that exchange, the
T-1 warning path is active.
luci18d ago
Workflow action `review_ready` applied. Work ready for review.
api18d ago
Closed (orchestrator). Commit f5cb5403 on master verified: +681/-47 across auth_portal.py (+172), new oauth_gws_expiry.py (+203), oauth_health_check.py (+138), task definition (+13), NEW tests/test_oauth_gws_expiry.py (+202). 9/9 tests pass. ACs covered:
- Auth Portal exchange now persists authorized_at + estimated refresh_token_expires_at (7d default for Testing mode, env-configurable)
- oauth_health_check.py reads expiry metadata + computes days remaining
- Status JSON exposes expiry fields for Auth Portal UI
- Dedup logic for T-2/T-1 warnings (no 30min spam)
- Failure alert path preserved
UA sign-off (runbooks/ua-signoff-gate.md): n/a — backend + script change, Auth Portal UI surface change minor (status fields). Verdict: PASS
luci18d ago
Orchestrator recovery: previous runtime injection got blocked while busy; no live tmux remains. Re-queueing for a clean pickup.
luci18d ago
Orchestrator note: implementation scope is clear and does not need Elmar input. Leaving queued for Luci pickup; prior runtime send conflict was a technical pickup artifact.
elmar-via-luci18d ago
Elmar correction: the 2026-05-26 15:43 timestamp was NOT a fresh Google consent/auth; it was a manual /auth/gws/refresh in the Auth Portal. Do not estimate 7-day Testing-mode expiry from credentials.json mtime because refresh writes the file and resets mtime without extending the trial refresh-token lifetime. Implementation must persist explicit original GWS authorization/exchange timestamp and token response metadata at /auth/gws/exchange time only. Fallback for existing tokens should be "unknown expiry until next full Google re-auth", not mtime+7d. If possible, use Google's refresh_token_expires_in when returned; otherwise store authorized_at at consent exchange and estimate +7d from that. Auth Portal should distinguish last_refresh_at from authorized_at.
elmar-via-luci18d ago
Elmar update: EchoBot Google app has now been published, so the weekly Testing-mode refresh-token expiry may no longer apply. Adjust MC-4253 scope: first verify/handle published-app behavior; do not assume weekly expiry is active. Auth Portal warning should only show a T-1 expiry when Google explicitly provides refresh_token_expires_in or when the app is known to be in Testing mode with a captured original auth timestamp. Otherwise show no weekly-expiry warning / status as published or expiry unknown, rather than alarming falsely.