Skip to content

feat(auth): add Spotify OAuth PKCE - #57

Open
VACInc wants to merge 6 commits into
openclaw:mainfrom
VACInc:feat/oauth-web-api
Open

feat(auth): add Spotify OAuth PKCE#57
VACInc wants to merge 6 commits into
openclaw:mainfrom
VACInc:feat/oauth-web-api

Conversation

@VACInc

@VACInc VACInc commented Aug 28, 2026

Copy link
Copy Markdown
Member

Summary

High Level TLDR

Add Spotify Authorization Code with PKCE as an optional, local OAuth path for official Web API commands, while keeping cookies as the default and preserving Connect behavior. This version includes the lifecycle-safety repairs from #61, rebases onto current main, and adds config-wide serialization so concurrent updates to different profiles cannot overwrite each other.

  • add spogo auth oauth login|status|clear and per-profile OAuth settings
  • refresh and securely persist per-profile OAuth tokens with cross-process locking
  • serialize OAuth login and clear as one profile-scoped lifecycle transition
  • reload persisted profile state after lifecycle-lock acquisition
  • make OAuth clearing failure-safe by persisting the cookie fallback before deleting the token cache
  • serialize shared config load-modify-save transactions across profiles to prevent lost updates
  • preserve cookie authentication as the default and keep Spotify Connect cookie-backed
  • use OAuth for the existing official Web API surface and Connect Web API fallbacks
  • include documentation, changelog entries, focused regressions, and built-CLI proof

Product decision

Maintainer direction on September 2, 2026 accepted this bounded OAuth mode for spogo's purpose: it is optional, local-only, limited to the existing Web API surface, and does not change the cookie-first default or make Connect depend on a hosted credential service. This satisfies the explicit product-decision requirement for new persistent credential flows in VISION.md.

Security and consistency

  • use PKCE with a cryptographically random verifier and state
  • bind callbacks only to explicit IPv4 or IPv6 loopback addresses and validate callback host, method, path, and state
  • never accept or store a Spotify client secret
  • store token caches and lifecycle locks in a 0700 directory with 0600 files on POSIX systems
  • derive token and lock filenames from contained, collision-safe profile segments; traversal, separators, Windows-reserved names, and case variants are encoded as lowercase byte-hex
  • coordinate concurrent token readers and refreshes with a per-profile cache lock
  • coordinate login token/profile commits and clear profile/token commits with a shared per-profile lifecycle lock
  • reload the persisted profile while holding the lifecycle lock so stale command contexts cannot recreate an inconsistent state
  • coordinate all profile config writes with a config-file lock and reload before mutation, preventing cross-profile lost updates
  • use same-directory atomic token replacement on POSIX and MoveFileEx replacement with write-through on Windows
  • never emit access or refresh token values in status output
  • do not follow redirects from Spotify's token endpoint

Compatibility

Cookie authentication remains the default. OAuth selects the token provider for public Web API operations; Spotify Connect and internal endpoints still require browser cookies. Existing command names, output formats, and cookie-auth profiles remain unchanged.

Verification

Validated on exact head 62f34e8:

  • rebased onto upstream e89c46f (September 4, 2026)

  • go test ./...

  • go test -race ./...

  • go run golang.org/x/tools/cmd/deadcode@v0.49.0 -test ./...

  • go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.13.2 run (0 issues)

  • ./scripts/check-coverage.sh 90 (90.1%)

  • focused OAuth lifecycle and config-lock regressions repeated 20 times under the race detector

  • profile-derived OAuth path containment and collision regressions cover traversal, Unix/Windows separators, reserved names, mixed-case aliases, and encoded-name collisions

  • node scripts/build-docs-site.mjs

  • VCS-stamped go build ./cmd/spogo

  • Windows amd64 test-binary cross-compilation for cmd/spogo and internal/spotify

  • built CLI against an isolated config:

    • missing OAuth status reported false cookies false
    • clear succeeded and preserved cookie selection
    • invalid loopback port 0 was rejected before browser or token exchange
  • mock end-to-end OAuth login covered callback state handling, authorization-code exchange, token persistence, profile persistence, and subsequent clear behavior

  • final review found and fixed a cross-profile config lost-update race; final rereview found no actionable defects

Redacted end-to-end proof

The exact final head was exercised with synthetic credentials and isolated temporary state. Callback URLs, authorization state, token values, client identifiers, filesystem paths, and local environment details are intentionally omitted. No real credentials were printed or committed.

$ go test -count=1 -run '<OAuth lifecycle tests>' -v ./internal/cli
=== RUN   TestAuthOAuthLoginCmd
--- PASS: TestAuthOAuthLoginCmd
=== RUN   TestAuthOAuthLoginAndClearSerializeLifecycle
--- PASS: TestAuthOAuthLoginAndClearSerializeLifecycle
=== RUN   TestAuthOAuthClearKeepsTokenWhenProfileUpdateFails
--- PASS: TestAuthOAuthClearKeepsTokenWhenProfileUpdateFails
=== RUN   TestAuthOAuthClearResetsStoredOAuthSelectionDespiteRuntimeOverride
--- PASS: TestAuthOAuthClearResetsStoredOAuthSelectionDespiteRuntimeOverride
PASS

$ go test -count=1 -run '<token exchange and locking tests>' -v ./internal/spotify
=== RUN   TestOAuthExchangeAndRefresh
--- PASS: TestOAuthExchangeAndRefresh
=== RUN   TestOAuthRefreshIsLockedAcrossProviders
--- PASS: TestOAuthRefreshIsLockedAcrossProviders
=== RUN   TestOAuthLifecycleLockSerializesAndPropagates
--- PASS: TestOAuthLifecycleLockSerializesAndPropagates
PASS

$ go test -count=1 -run '<cross-profile config locking tests>' -v ./internal/config
=== RUN   TestUpdateHonorsLockCancellation
--- PASS: TestUpdateHonorsLockCancellation
=== RUN   TestUpdateSerializesDifferentProfileWrites
--- PASS: TestUpdateSerializesDifferentProfileWrites
PASS

This proves the complete local OAuth lifecycle: loopback callback handling, state validation, authorization-code exchange, secure token persistence, refresh, profile persistence, failure-safe clearing, same-profile lifecycle serialization, and cross-profile config serialization. The repository CI build also passed on the exact final commit.

Inherited live endpoint proof from #61

The incorporated #61 head exercised the built CLI against its normal loopback callback and Spotify's real accounts token endpoint using dummy public values only. Invalid state was rejected without exchange; valid state reached Spotify's endpoint and received the expected rejection for dummy values. No credential or real token was used, printed, or persisted.

Redacted real-account end-to-end proof

On September 4, 2026, the exact final head 62f34e8 was installed as the active spogo CLI and run using an existing real Spotify OAuth authorization. The persisted access token was expired before the run, so the first authenticated request exercised automatic refresh. Account identity, client identifier, token values, callback details, item names, library totals, device details, filesystem paths, and token hashes are omitted.

$ spogo --profile <redacted> --engine web --auth oauth <read-only commands>
installed_head=62f34e8
preexisting_token_expired=true
token_cache_refreshed=true
oauth_authenticated=true
oauth_expired=false
oauth_has_refresh=true
oauth_file_mode=0600
search_items=1
library_items=1
devices_items_positive=true
playback_status_read=true
top_tracks_items=1
history_items=1
stderr_bytes=0

$ spogo --profile <redacted> --engine auto --auth oauth search track <redacted> --limit 1
auto_web_fallback_items=1
stderr_bytes=0

$ spogo --profile <redacted> --engine connect --auth cookies status
exit=3
stderr="no cookies found"

Observed result: the installed exact-head binary refreshed the expired real-account token, atomically persisted the refreshed cache with owner-only permissions, and completed authenticated search, saved-library, device, playback-status, affinity-ranking, and listening-history reads without diagnostics. auto also completed through the OAuth Web API path when browser cookies were unavailable. Cookie-backed Connect correctly reported missing cookies with the documented exit code 3; live Connect behavior therefore remains credential-blocked rather than falsely claimed as tested. No playback mutation was performed, and no credential or private account content was printed or added to the repository.

Worked on by

@clawsweeper

clawsweeper Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 28, 2026
@clawsweeper

clawsweeper Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: blocked before merge. Reviewed September 4, 2026, 9:17 PM ET / September 5, 2026, 01:17 UTC.

ClawSweeper review

What this changes

Adds optional Spotify OAuth with PKCE, per-profile credential storage and refresh, and OAuth-backed Web API requests while retaining cookie authentication and Connect.

Merge readiness

Blocked before merge - 8 items remain

This member-authored PR remains useful: OAuth is absent from current main and the latest release, and neither related PR supersedes this work. The previous fallback defect remains, and two additional source-backed profile-consistency defects prevent approval.

Priority: P2
Reviewed head: 62f34e81700bb1d705dc1e56735aa24af319605a
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) Strong real-account proof supports the feature, but the unresolved engine-contract and profile-consistency defects keep the implementation below merge-ready quality.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (terminal): The captured exact-head installed CLI exercised the new OAuth provider against a real Spotify account: an expired token refreshed, the owner-only cache updated, and authenticated Web API reads succeeded. Inherited callback evidence shows invalid state rejected before exchange; lifecycle tests remain supplemental. This does not establish live cookie-backed Connect compatibility or exclude the identified config races.
Patch quality 🦐 gold shrimp (3/6) 3 actionable review findings remain.

Verification

Check Result Evidence
Real behavior Verified Sufficient (terminal): The captured exact-head installed CLI exercised the new OAuth provider against a real Spotify account: an expired token refreshed, the owner-only cache updated, and authenticated Web API reads succeeded. Inherited callback evidence shows invalid state rejected before exchange; lifecycle tests remain supplemental. This does not establish live cookie-backed Connect compatibility or exclude the identified config races.
Evidence reviewed 14 items Pinned introduction and merge identity: The verified origin is openclaw/spogo and HEAD is the pinned PR head. The test merge records main e89c46f followed by the exact PR head; its resulting tree equals HEAD. The reviewed defects therefore survive the supplied three-way merge rather than arising from base drift.
OAuth remains absent from main: Current main constructs Web API clients with CookieTokenProvider, and its profile model has no OAuth fields. Searching main's implementation and documentation found no OAuth or PKCE implementation.
Latest-release check: The supplied latest release, v0.10.7, exposes only cookie status, import, paste, and clear commands; it does not contain the proposed OAuth command group.
Findings 3 actionable findings [P1] Preserve missing-cookie failures before OAuth fallbacks
[P2] Preserve OAuth fields when committing cookie-profile changes
[P2] Protect lifecycle reloads from in-progress config writes
Security None None.

How this fits together

spogo selects a Spotify client from the active profile and engine settings. The new OAuth provider supplies credentials to the existing public Web API client, while Connect continues using browser cookies for internal Spotify requests.

flowchart TD
  A[Commands and profile settings] --> B[Engine selection]
  C[Browser cookies] --> D[Connect internal requests]
  B --> D
  B --> E[Public Web API client]
  D -->|Supported fallbacks| E
  C --> E
  F[OAuth login and token cache] --> E
  D --> G[Command results]
  E --> G
Loading

Decision needed

Question Recommendation
Does steipete confirm acceptance of this optional local OAuth credential flow and persistent cache format under VISION.md, while retaining the documented Connect authentication contract? Confirm the bounded OAuth direction: Confirm the reported acceptance, with landing still contingent on the concrete correctness repairs and existing-profile compatibility validation.

Why: The body reports prior acceptance, but the subsequent author comment still requests it; the supplied record does not resolve that discrepancy.

Before merge

  • Preserve missing-cookie failures before OAuth fallbacks (P1) - With valid OAuth but no usable cookie session, Connect search receives an authentication error from graphQL and then reaches this newly injected Web API client, which can succeed. Both connect and auto use this path; the supplied real-account trace confirms cookie-free auto success. This hides the authentication failure that VISION.md and docs/engines.md require these engines to expose. Preserve the missing-cookie error before these fallbacks, while retaining cookie-free operation for explicit web selection. This prior blocker remains unchanged.
  • Preserve OAuth fields when committing cookie-profile changes (P2) - The shared lock reloads the config, but this assignment then replaces the profile with a stale caller snapshot. For example, start auth paste on an OAuth profile, complete auth oauth clear in another process, then finish the paste: saveCookies submits the old auth=oauth profile and restores OAuth selection after its token was deleted. The inverse ordering can overwrite a completed OAuth login. Update only each command's owned fields against the profile loaded under the lock. This is a late finding on code unchanged since the previous reviewed head.
  • Protect lifecycle reloads from in-progress config writes (P2) - This new reload bypasses the config-file lock, and config.Save still uses an in-place os.WriteFile. While another profile's update has truncated config.toml but not finished writing it, clear can read an empty config and treat its profile as cookie-authenticated. It then skips persisting the cookie selection and deletes the OAuth token; the other writer subsequently leaves auth=oauth on disk. Make the lifecycle read/decision participate in the shared transaction, or provide atomic config replacement with appropriate mutation locking. This is a late finding on the unchanged reviewed head.
  • Resolve merge risk (P2) - Automation may interpret OAuth-fallback success as healthy Connect authentication even when the required browser credentials are missing.
  • Resolve merge risk (P1) - Concurrent cookie and OAuth operations can leave credential selection inconsistent with the token cache despite the new locking.
  • Resolve merge risk (P1) - The real-account trace does not exercise an authenticated existing cookie profile, so preservation of that upgrade path remains unverified.
  • Complete next step (P2) - Resolve the three findings, validate preservation of an existing cookie profile, and reconcile the recorded OAuth acceptance with steipete before merge.
  • Resolve maintainer decision - Resolve the maintainer decision shown above before merge.

Findings

  • [P1] Preserve missing-cookie failures before OAuth fallbacks — internal/spotify/connect_web.go:8-12
  • [P2] Preserve OAuth fields when committing cookie-profile changes — internal/app/context.go:60-64
  • [P2] Protect lifecycle reloads from in-progress config writes — internal/cli/auth_oauth.go:262-268
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Production and test growth Production Go +1140/-124, net +1016; tests +1745/-25, net +1720 The stated justification is a new OAuth lifecycle and credential provider, with substantial regression coverage alongside the production growth.

Merge-risk options

Maintainer options:

  1. Repair the existing contracts (recommended)
    Preserve missing-cookie failures and make profile reads and field updates coherent across cookie and OAuth commands before landing the accepted scope.
  2. Pause pending acceptance
    Retain the branch and its real-account proof while the credential-flow decision and existing-profile compatibility evidence are resolved.

Technical review

Best possible solution:

An explicitly approved local OAuth mode should preserve legacy cookie profiles, surface required authentication failures, and keep profile settings and credentials coherent across every auth command.

Do we have a high-confidence way to reproduce the issue?

Yes, for the PR defects: the fallback is established by source and the supplied exact-head auto run, and the two profile races have concrete source-level interleavings. No failing current-main execution is claimed; OAuth itself is new functionality.

Is this the best way to solve the issue?

Partly: reusing the existing Web API client is the appropriate boundary, but the implementation needs authentication-error preservation, field-scoped profile mutations, and config reads that cannot observe an in-progress write.

Full review comments:

  • [P1] Preserve missing-cookie failures before OAuth fallbacks — internal/spotify/connect_web.go:8-12
    With valid OAuth but no usable cookie session, Connect search receives an authentication error from graphQL and then reaches this newly injected Web API client, which can succeed. Both connect and auto use this path; the supplied real-account trace confirms cookie-free auto success. This hides the authentication failure that VISION.md and docs/engines.md require these engines to expose. Preserve the missing-cookie error before these fallbacks, while retaining cookie-free operation for explicit web selection. This prior blocker remains unchanged.
    Confidence: 0.99
  • [P2] Preserve OAuth fields when committing cookie-profile changes — internal/app/context.go:60-64
    The shared lock reloads the config, but this assignment then replaces the profile with a stale caller snapshot. For example, start auth paste on an OAuth profile, complete auth oauth clear in another process, then finish the paste: saveCookies submits the old auth=oauth profile and restores OAuth selection after its token was deleted. The inverse ordering can overwrite a completed OAuth login. Update only each command's owned fields against the profile loaded under the lock. This is a late finding on code unchanged since the previous reviewed head.
    Confidence: 0.97
    Late finding: first raised on code an earlier review cycle already covered.
  • [P2] Protect lifecycle reloads from in-progress config writes — internal/cli/auth_oauth.go:262-268
    This new reload bypasses the config-file lock, and config.Save still uses an in-place os.WriteFile. While another profile's update has truncated config.toml but not finished writing it, clear can read an empty config and treat its profile as cookie-authenticated. It then skips persisting the cookie selection and deletes the OAuth token; the other writer subsequently leaves auth=oauth on disk. Make the lifecycle read/decision participate in the shared transaction, or provide atomic config replacement with appropriate mutation locking. This is a late finding on the unchanged reviewed head.
    Confidence: 0.93
    Late finding: first raised on code an earlier review cycle already covered.

Overall correctness: patch is incorrect
Overall confidence: 0.95

AGENTS.md: not found in the target repository.

Codex review notes: model internal, reasoning high; reviewed against e89c46fefed8.

Labels

Label changes:

  • add P2: This is a useful opt-in authentication feature with bounded merge blockers, not evidence of an urgent shipped regression.
  • remove P1: Current review triage priority is P2, so this older priority label is no longer current.

Label justifications:

  • P2: This is a useful opt-in authentication feature with bounded merge blockers, not evidence of an urgent shipped regression.
  • merge-risk: 🚨 compatibility: The introduced fallback can contradict the documented engine and authentication-error contract.
  • merge-risk: 🚨 auth-provider: Profile-update interleavings can restore OAuth selection without a usable token cache or overwrite a completed login.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (terminal): The captured exact-head installed CLI exercised the new OAuth provider against a real Spotify account: an expired token refreshed, the owner-only cache updated, and authenticated Web API reads succeeded. Inherited callback evidence shows invalid state rejected before exchange; lifecycle tests remain supplemental. This does not establish live cookie-backed Connect compatibility or exclude the identified config races.
  • proof: sufficient: Contributor real behavior proof is sufficient. The captured exact-head installed CLI exercised the new OAuth provider against a real Spotify account: an expired token refreshed, the owner-only cache updated, and authenticated Web API reads succeeded. Inherited callback evidence shows invalid state rejected before exchange; lifecycle tests remain supplemental. This does not establish live cookie-backed Connect compatibility or exclude the identified config races.

Evidence

What I checked:

  • Pinned introduction and merge identity: The verified origin is openclaw/spogo and HEAD is the pinned PR head. The test merge records main e89c46f followed by the exact PR head; its resulting tree equals HEAD. The reviewed defects therefore survive the supplied three-way merge rather than arising from base drift. (62f34e81700b)
  • OAuth remains absent from main: Current main constructs Web API clients with CookieTokenProvider, and its profile model has no OAuth fields. Searching main's implementation and documentation found no OAuth or PKCE implementation. (internal/app/context_factory.go:107, e89c46fefed8)
  • Latest-release check: The supplied latest release, v0.10.7, exposes only cookie status, import, paste, and clear commands; it does not contain the proposed OAuth command group. (internal/cli/auth.go:3, dc83047dfa53)
  • Existing compatibility and acceptance contract: VISION.md prohibits fallbacks that hide authentication failures and requires an explicit product decision for persistent formats and credential flows. The file was read fully; its change policy also requires documentation, changelog coverage, regressions where practical, and built-CLI proof. (VISION.md:29, 62f34e81700b)
  • Prior fallback finding remains: The introduced search fallback replaces session authentication with the injected Web API client. Connect search falls back after a GraphQL authentication error, so valid OAuth can turn missing cookies into success. Both connect and auto receive this client; docs/engines.md still requires browser cookies for those engine selections. (internal/spotify/connect_web.go:8, 62f34e81700b)
  • Stale cookie writers can overwrite OAuth state: SaveProfile reloads the config under the new shared lock but replaces the entire profile with its caller's snapshot. auth paste captures that snapshot before waiting for input, and cookie import/clear also pass whole profiles. A cookie command started before OAuth clear can subsequently restore auth=oauth after the token was deleted. (internal/app/context.go:61, 62f34e81700b)

Likely related people:

  • Peter Steinberger: Raw commit 5adbd04 adds VISION.md:31 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: 5adbd048ac0e; files: VISION.md)
  • Sebastien Tardif: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Preserve required cookie-authentication failures for connect and auto, with focused regressions that retain explicit web OAuth success.
  • Cover stale cookie writers and overlapping config reads while repairing the profile transaction boundaries.
  • Confirm bounded credential-flow acceptance and validate that an existing cookie profile survives upgrade and OAuth lifecycle operations unchanged.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (10 earlier review cycles; latest 8 shown)
  • reviewed 2026-09-03T00:04:51.426Z sha 2d85ec8 :: needs real behavior proof before merge. :: none
  • reviewed 2026-09-03T00:12:06.846Z sha 2d85ec8 :: needs real behavior proof before merge. :: none
  • reviewed 2026-09-03T00:25:06.789Z sha 2d85ec8 :: blocked before merge. :: [P2] Keep OAuth token paths inside the credential directory
  • reviewed 2026-09-03T01:26:27.488Z sha 377856a :: blocked before merge. :: none
  • reviewed 2026-09-04T11:00:42.027Z sha 62f34e8 :: blocked before merge. :: none
  • reviewed 2026-09-04T15:11:48.310Z sha 62f34e8 :: blocked before merge. :: [P2] Preserve missing-cookie failures before OAuth fallback
  • reviewed 2026-09-04T16:54:46.717Z sha 62f34e8 :: blocked before merge. :: [P1] Preserve missing-cookie failures before OAuth fallbacks
  • reviewed 2026-09-04T19:00:47.375Z sha 62f34e8 :: blocked before merge. :: [P1] Preserve missing-cookie failures before OAuth fallbacks

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Aug 28, 2026
steipete added a commit that referenced this pull request Aug 31, 2026
Extract the search-parser fix from PR #57 commit
12fed0b without its OAuth changes.
Read plural containers in both Web API search paths and cover all six
supported search types with a synthetic documented-shape response fixture.

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
@VACInc
VACInc force-pushed the feat/oauth-web-api branch 2 times, most recently from efea2fb to 2d85ec8 Compare September 2, 2026 23:58
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. proof: sufficient Contributor real behavior proof is sufficient. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Sep 3, 2026
@VACInc

VACInc commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

@steipete, this should now be ready for your approval and merge when you’re happy with it. I cannot merge it myself because VACInc currently has read-only access to openclaw/spogo. 😂

The current head includes the repairs from #61, the additional cross-profile config serialization, and the profile-derived path containment fix from the latest ClawSweeper review. CI is green, the final security review found no remaining path or collision issues, and the PR body contains redacted real-account proof from the installed final binary: automatic token refresh plus successful search and saved-library reads with zero stderr.

Could you provide the explicit bounded OAuth approval required by VISION.md and merge this if it looks good to you?

I’d also love to help with spogo going forward. I’ve subscribed to the repository so I can follow new work and reviews.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Sep 3, 2026
@VACInc
VACInc force-pushed the feat/oauth-web-api branch from 377856a to 62f34e8 Compare September 4, 2026 10:53
@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 Urgent regression or broken agent/channel workflow affecting real users now. P2 Normal priority bug or improvement with limited blast radius. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. P1 Urgent regression or broken agent/channel workflow affecting real users now. labels Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants