Skip to content

test: verify the initial Spotify CLI vertical slice #8

Closed

Description

@rianjs

Parent: #1
Depends on: #2, #3, #4, #5, #6, #7

Planned commit

test: verify the initial Spotify CLI vertical slice

Work

  • Add an opt-in live smoke harness for a dedicated Spotify Development Mode app/account.
  • Exercise init, me, normal/no-result/paginated track search, token refresh, credential replacement, clear, and re-init recovery.
  • Complete README setup instructions for creating a Spotify app, registering the loopback redirect, selecting credential backends, and installing through every package manager.
  • Run the repository check suite, GoReleaser snapshot, auto-release dry-run, and macOS Keychain/signature gates.
  • Record release prerequisites and the asynchronous Winget/Chocolatey indexing expectation in Ship the initial secure Spotify CLI vertical slice #1 and the draft PR.

Acceptance

Activity

  1. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Plan: issue #8 — verify the initial vertical slice

    1. Add one external, opt-in live harness

    • Add scripts/live-smoke.sh as an orchestration harness around the built sptfy binary; do not add a production command, credential export, or new Go abstraction.
    • Refuse to run unless SPOTIFY_CLI_LIVE=1, SPOTIFY_CLI_LIVE_DEDICATED_ACCOUNT=1, a client ID is present, and stdin is a TTY. The dedicated-account acknowledgement prevents accidental mutation of a personal account.
    • Create an exact mktemp -d state root with a restrictive umask and install traps before mutation. Before any CLI/helper invocation, pin cli-common's complete eight-variable isolation set to distinct children of that root: HOME, USERPROFILE, AppData, LocalAppData, XDG_CONFIG_HOME, XDG_CACHE_HOME, XDG_DATA_HOME, and XDG_STATE_HOME. Generate the file-backend passphrase in memory for the process environment. Never use the OS keychain or the developer's normal state.
    • Build sptfy and run interactive init, me, an ordinary query, guaranteed-no-result query, page-size-1 query plus parsed continuation resume, ID-only output, and one projected/artwork query. Assert expected non-secret output structure and stdout/stderr routing without snapshotting account-specific values.
    • Exercise safe credential replacement via init --overwrite, then config clear, prove me fails, and re-run init/me to prove recovery.
    • Verify refresh without exporting credentials: add a tiny build-tagged live test helper under internal/livesmoke that is compiled only with spotify_live. It opens only the harness's explicitly selected encrypted-file store, rewrites the in-memory decoded envelope with an expired access token while preserving the refresh token, persists it, and exits. The shell harness remains the only orchestrator: it then invokes the built binary's me and checks streams/status. No token or envelope is printed or written outside the encrypted store. Guard the helper with the same opt-in variables and all-eight-variable hermetic-root validation. Keep this helper credential-specific, not a reusable framework.
    • Remove the temporary state tree on success, failure, or interrupt. The harness is not referenced by ordinary make check or CI; expose it only as an explicit make live-smoke target whose recipe retains the environment guards.

    Verification: run shell syntax checking, guard-failure tests proving no state creation without each opt-in, the build-tagged helper's non-live skip path, and a dry harness mode using a fake binary to validate sequencing/cleanup without Spotify. When dedicated live credentials are available, run the real harness and record only command/status evidence—never IDs, URLs containing codes, or tokens.

    2. Complete fresh-user and release documentation

    • Expand README with Spotify Development Mode app creation, exact loopback redirect registration, PKCE/no-client-secret explanation, interactive and non-interactive setup, me, first track search, backend selection/precedence, encrypted-file passphrase behavior, and all supported package-manager install names (spotify-cli) versus binary name (sptfy).
    • Document the opt-in live harness, dedicated-account requirement, hermetic encrypted-file state, cleanup guarantees, and that ordinary CI never runs it.
    • Update docs/development.md with the exact local verification commands and release prerequisites: repository/action tokens, self-signing material, and package-manager credentials expected by the shared workflows. Follow the shared distribution policy exactly: macOS artifacts are self-signed and verified but not notarized. State that Winget and Chocolatey community-index publication is asynchronous after the canonical GitHub release, while Homebrew and deb/rpm publication follow their configured channels.

    Verification: follow the README from a clean temporary state through build/setup/search where credentials permit; verify every documented command/identifier against repository manifests and workflows; run link/grep consistency checks for spotify-cli versus sptfy.

    3. Run and record the final release/security evidence

    Verification: retain command results in the issue/PR summary, run git diff --check, verify one logical issue commit, and watch all required GitHub checks.

    4. Commit and final batch handoff

  2. added 3 commits that reference this issue on Jul 22, 2026
    512c134
    7b8b226
    7aa28db
  3. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Implementation and non-live verification are complete at 7aa28db.

    Verified:

    • make check passes, including the fake live-smoke guard, sequence, backend-pinning, and cleanup harness.
    • All eight PR checks pass on Linux, macOS, and Windows.
    • The exact-head GoReleaser snapshot produces six archives, four deb/rpm packages, and the Homebrew cask.
    • The pinned shared auto-release path and feat: commit gates pass and compute v0.1.1 for the first run.
    • The pinned shared release-config preflight passes.
    • Both Darwin snapshot binaries are Mach-O and link Security.framework; the hermetic manifest-driven probe reports the native Keychain backend with automatic selection.
    • Release signing is self-signing, not notarization. Winget and Chocolatey indexing remains asynchronous after submission.

    Still required before this issue can close:

    • Run make live-smoke interactively against a dedicated Spotify Development Mode app/account.
    • Confirm the org/repository signing and publishing secrets are visible to this repository. The current user can see no repository secrets and lacks permission to enumerate organization secrets.
    • GitHub will not dispatch a workflow that does not yet exist on the default branch, so the attempted pre-merge Actions dry-run returns 404. Its pinned gate and preflight have instead been exercised locally without publishing; the hosted workflow can only be dispatched after the one-lump merge places release.yml on main.

    No live result, secret readiness, or hosted dry-run is being claimed yet.

  4. added a commit that references this issue on Jul 22, 2026
    b1763bf
  5. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Dedicated-account live verification passed at b1763bf.

    The run proved PKCE login and identity, normal/no-result/paginated track search, ID and artwork projections, album/artist breadcrumbs, credential overwrite, forced token refresh, clear with expected authentication failure, re-init, and final identity recovery.

    The first run exposed that Go's read-only module cache followed the temporary HOME, preventing cleanup. The harness now preserves the caller's existing GOPATH, GOMODCACHE, and GOCACHE while keeping all application state inside the eight-variable hermetic root. The full rerun exited successfully and left no spotify-cli-live.* directory behind. make check, ShellCheck, and the fake live harness pass after the fix.

    Remaining before closure: confirm the organization/repository signing and publishing secrets are available to this repository. No secret values are needed or requested.

  6. added a commit that references this issue on Jul 22, 2026
    c0d54b6
  7. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Fleet comparison found and fixed one missing release preflight at c0d54b6: auto-release.yml now exposes the same workflow_dispatch dry-run as atlassian-cli, google-readonly, codereview-cli, newrelic-cli, and slack-chat-api. actionlint and make check pass.

    The release caller's eight publishing/signing secret mappings are identical to the standardized CLIs. Recent shared-workflow releases—including codereview-cli v0.10.267, google-readonly v1.1.67, and both Atlassian tools—completed signing, Homebrew, Chocolatey, Winget, and Linux jobs successfully.

    One intentional difference remains: every deployed CLI currently maps auto-release tagging to TAP_GITHUB_TOKEN, while the newer cli-common policy requires a separate RELEASE_TAG_TOKEN (or GitHub App token) so tag creation does not reuse the broader Homebrew credential. Spotify currently follows the newer policy. Completion therefore needs either confirmation/provisioning of RELEASE_TAG_TOKEN, or an explicit decision to retain the older fleet divergence.

  8. added a commit that references this issue on Jul 22, 2026
    613cb99
  9. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Release wiring is now aligned with the deployed Go CLI fleet at 613cb99.

    • Auto-release and release both expose manual dry-runs.
    • TAP_GITHUB_TOKEN is passed for tag creation and Homebrew publishing, matching Atlassian, Google, codereview-cli, New Relic, and Slack.
    • The remaining seven publishing/signing names match those callers exactly.
    • actionlint and make check pass.

    This removes the unprovisioned Spotify-only RELEASE_TAG_TOKEN assumption. A future dedicated-token migration should be done fleet-wide rather than introduced as a one-repository divergence.

  10. added a commit that references this issue on Jul 22, 2026
    55f1f2c
  11. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Independent Terra TDD review completed (tdd-batch-spotify-cli-issues-2-8-20260722-9-1784755892) with no blockers and three actionable coverage findings. All are addressed at 55f1f2c:

    • a command-level continuation-token test asserts the Spotify request receives offset=10;
    • the fake live binary asserts SPOTIFY_CLI_LIVE_ROOT, the file backend, and every one of the eight hermetic state variables;
    • ordinary make test-live-smoke compiles the spotify_live refresh helper without executing it.

    Targeted tests, ShellCheck, actionlint, git diff --check, and full make check pass.

  12. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Issue #8 is complete at 55f1f2c.

    • Dedicated-account Spotify PKCE smoke passed with complete hermetic cleanup.
    • make check, ShellCheck, actionlint, release preflight, snapshot, Darwin/Keychain probes, and all eight GitHub checks pass.
    • Sol architecture review and post-TDD/post-cr convergence are 0/0/0/0.
    • Terra's one-shot TDD findings are all addressed.
    • The standard cr review retained the existing approval.
    • CI/CD triggers, reusable callers, and secret names match the deployed Go CLI fleet.

    The integration PR now closes #1–#8. Winget and Chocolatey indexing remains asynchronous after release submission.

  13. added 5 commits that reference this issue on Jul 22, 2026
    498f2fc
    e85e5d4
    7c6ee8d
    a3db6f7
    76735a3
  14. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Exact-head follow-up (76735a3): all local, CI, independent-review, and six-platform release-render gates pass. The final architecture review accepts the release and dependency-inversion changes and requires the dedicated-account live smoke to be rerun because review-driven initialization/session boundaries changed after the original successful smoke at 55f1f2c.

    The rerun reached Spotify PKCE authorization successfully but timed out awaiting the human browser consent callback. No credential was persisted; the hermetic state root was removed by the harness trap. This one browser approval and the resulting smoke completion are the sole remaining pre-merge gate.

  15. rianjs commented on Jul 22, 2026

    @rianjs
    ContributorAuthor

    Exact-head verification complete at 76735a3.

    The dedicated-account PKCE smoke passed initialization, identity, ordinary/no-result/paginated track search, output projections and breadcrumbs, credential overwrite, forced refresh persistence, clear with expected auth failure, re-initialization, final identity, and complete hermetic cleanup. The harness used the encrypted-file backend under its isolated eight-variable state root and removed that root on exit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions