# Subsignal agent setup playbook This installation's release is ready for review. Publishing it at the production https://subsignal.dev origin is a separate operator action. Do not claim that a production install URL is live until its release actually downloads successfully. Use Python 3.11+ on macOS/Linux in Codex or Claude Code. No token, password, device secret, or API-key value belongs in model context, command arguments, logs, or support messages. Only the public verification URL and human user code are shown. 1. Inspect the existing skill and credential selection without reading secrets into the conversation. Preserve modified installs and all existing credentials. If an environment API key conflicts with the requested OAuth setup, obtain a deliberate choice. Selecting OAuth disables automatic API-key fallback. 2. Fetch and inspect these own-origin release artifacts before executing code: /skills/subsignal/install.py /skills/subsignal/manifest.json /skills/subsignal/SKILL.md /skills/subsignal/scripts/connect.py /skills/subsignal/scripts/read.py Save the reviewed installer to a temporary file. Never pipe downloaded content into a shell. It uses a fixed HTTPS Subsignal source, refuses redirects, and verifies known paths, content hashes, and size bounds. Missing or invalid artifacts are an installation failure, not permission to invent a package. 3. Run the reviewed installer with python3 /path/to/reviewed/install.py. Codex defaults to ~/.agents/skills/subsignal. For Claude Code explicitly add --destination ~/.claude/skills/subsignal. Project paths are respectively .agents/skills/subsignal and .claude/skills/subsignal. Official documentation: https://learn.chatgpt.com/docs/build-skills https://code.claude.com/docs/en/skills Identical versions are a no-op. Intentional updates use --update and preserve a rollback copy. Modified/unmanaged installs require preserving them and choosing another destination; never silently replace them. Follow host reload guidance. 4. Read the installed SKILL.md. Let SKILL_DIR mean its actual installed directory. Run python3 SKILL_DIR/scripts/connect.py login. It reuses working authorization or resumes an unfinished challenge. Keep this process running while the user signs in. Show its flushed progress immediately; stdout is newline-delimited JSON containing public status only. Never wait for the process to exit before presenting the verification link and matching code. 5. On a local desktop the helper opens the browser. On remote hosts, or if browser launch fails, present verification_uri_complete (or verification_uri) and the matching user_code as a clickable link. --no-browser suppresses browser launch. The user signs in, checks the matching code, and explicitly allows or cancels read-only access. Never approve for them. New accounts still need email verification and owner-approved API access. Expired codes require a fresh login. 6. The login process detects browser consent and exchanges the grant automatically. Do not ask the user to return to chat to trigger completion. Honor its result: authorization alone is not yet a verified read. Stop on denial or expiry. Ctrl-C stops waiting; login can resume an unexpired request. If the host cannot keep a process running, use begin and python3 SKILL_DIR/scripts/connect.py poll-once at or after next_poll_at. Honor the saved interval and slow_down; each poll-once makes at most one token request. A lost successful response cannot be replayed: reconnect and remove any orphan connection from the dashboard. Failed persistence attempts revocation. A transient status error must be resolved before starting a new grant. To also read public Instagram profiles, run python3 SKILL_DIR/scripts/connect.py login --instagram (or begin --instagram, then poll-once). It requests a wider connection that the user approves by name, and needs Instagram enabled for the workspace by the owner. The current connection stays selected and working until the wider one is approved; a denied, expired or failed request changes nothing. The old connection then stays listed in the dashboard for the user to disconnect. Plain login never asks for Instagram and reuses any working connection. 7. Authorization is not yet verified setup. Run exactly one small read: python3 SKILL_DIR/scripts/read.py /v1/search q=python limit=1 Only call setup verified after this authenticated request succeeds. Report the actual meta.request_id and returned Reddit permalink, if present. An empty result verifies access without providing a source; never invent one. Distinguish authorized-but-unverified, verification failure, and exhausted allowance. Stop on failed verification without automatic scraping or retries. API-key setup also requires a successful read. Each admitted read consumes shared allowance once. Instagram reads use the same helper, for example python3 SKILL_DIR/scripts/read.py /v1/instagram/profile/USERNAME and one fixed non-read request that starts a reel collection: python3 SKILL_DIR/scripts/read.py /v1/instagram/profile/USERNAME/reels/collection --start A 403 profile_private, scope_denied or instagram_not_entitled on an Instagram read is reported as a failed request and leaves the connection as it is. 8. Use python3 SKILL_DIR/scripts/connect.py disconnect to revoke the connection and remove its local bearer. A pending challenge is canceled locally and expires on the server. OAuth selection persists independently of its secret: disconnect, expiry, revocation, missing files, errors, and interrupted writes never silently enable a preserved key. Reconnect explicitly, or deliberately run python3 SKILL_DIR/scripts/connect.py use-api-key to select SUBSIGNAL_API_KEY first, then the private legacy api_key file. Selecting key mode does not revoke an old server OAuth connection; disconnect separately. The fixed first-party public client is subsignal-skill (RFC 8628 device flow). Tokens grant reddit:read, or "reddit:read instagram:read" when that exact scope is requested, the human approves the named Instagram permission, and the owner has enabled Instagram for the workspace. No other scope is accepted. Existing reddit:read tokens never gain Instagram access; a new approval is required. Tokens expire after 30 days and have no refresh token. They cannot read /v1/usage or manage keys. Account status/version and current workspace/partner/owner approval are checked again during admission. Password reset/change invalidates OAuth connections; ordinary browser logout does not. The dashboard shows allowance and offers connection revocation while suspended. After verification, ask what the user wants to research. Follow the installed skill's endpoint allowlist, bounded request budget, source citation and untrusted Reddit-content rules. This playbook does not authorize additional Reddit reads. Testing alongside an existing installation Install the reviewed bundle to a separate directory with --destination; do not update or replace the user's current skill for a trial. Use its explicit helper path. Set SUBSIGNAL_CONFIG_DIR to a new absolute private directory for every login, status, read and disconnect command in the trial. The default remains ~/.config/subsignal. A separate install path alone does not isolate credentials. Keep the trial outside the host's automatically discovered skill directories. Do not read or copy existing credential files, and do not change HOME. OAuth login selects the trial's own credentials; keep any existing environment API key out of the trial process. Clean up by disconnecting the trial connection only.