Skip to content

Connections panel — credentialed backends (Company Compute + Pasqal Cloud) in the app UI - #172

Merged
kateebonner merged 20 commits into
mainfrom
amico/issue-159-connections-panel
Jul 20, 2026
Merged

Connections panel — credentialed backends (Company Compute + Pasqal Cloud) in the app UI#172
kateebonner merged 20 commits into
mainfrom
amico/issue-159-connections-panel

Conversation

@kateebonner

@kateebonner kateebonner commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Closes #159

amicode-side integration branch for the Connections panel DAG. All amicode-side afk slices complete, gates green (extension 634+ · amico-run 282 · python 16/16). Companion fork PR: harmoniqs/opencode#33.

Merged slices:

Remaining in the DAG (not in this PR): #171 (re-point setCloudKey onto the panel seam) — hitl, gated on rchari/hp-cloud-key merging first.

🤖 Generated with Claude Code

kateebonner and others added 10 commits July 19, 2026 20:12
…ation (AC1)

New standalone validator (sibling of the connectivity spike's connector):
env-only credentials, authenticates via the pasqal_cloud SDK, extracts the
bearer token best-effort through the SDK's token-provider chain (null token
= session-only fallback signal), enumerates devices, and emits exactly one
JSON line: ok / project_id / devices / token (nullable) / expires_at.

Tests stub the SDK fully via sys.modules injection; no network, no
pasqal-cloud install required.

Part of #164 (parent #159).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auth failure -> 2, network failure (connect or device fetch) -> 3,
project-authorization failure -> 4; stderr carries a fixed, distinct,
token- and password-free message per class and stdout stays empty.
Stub exceptions embed a poison password so any echoed exception text
fails the hygiene assertions (verified by mutation: swapping an exit
code and echoing exception text each break the suite).

Part of #164.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…DK shape (AC3, AC4)

- Stub now mirrors pasqal-cloud 0.23.0's real object graph:
  PasqalCloudConnection.cloud_client._client.authenticator.token_provider;
  token extraction walks that chain (verified offline against the real
  SDK) and reads the exact expiry from ExpiringTokenProvider's token
  cache, with JWT exp decode as fallback.
- Devices come from cloud_client.get_device_specs_dict() (pure SDK) —
  never fetch_available_devices, which deserializes specs via pulser.
- AC3: recorder-backed stub proves no run/submit/backend/job call path.
- AC4: poison password appears in no argv and no output stream, across
  every scenario; spawn tests are hermetic via a PYTHONPATH shadow stub
  (never the live service, even where pasqal-cloud is installed).
- Misconfigured python (SDK not importable) renders a fixed exit-1
  message, distinct from unreachable-service, never a traceback.

Part of #164.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
requirements.txt pins pasqal-cloud==0.23.0 (the spike's pin; the token
extraction chain in pasqal_validate.py is verified against this
version's object graph). tests/slow_live.py is the optional live smoke:
excluded from default discovery by filename, gated on
PASQAL_LIVE_SMOKE=1, and asserts token shape without echoing it.

Closes out #164's testing decisions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fork's route auth (ServerAuth @ v1.17.3-amicode.5) is a verified no-op
without OPENCODE_SERVER_PASSWORD in the server env. New server_auth module
mints a cryptographically random per-boot password (32B base64url, in-memory
only) and builds the spawn env the extension ADDS — PATH + config content +
password — used by all three ServerManager sites (boot, solver switch, vault
respawn), so no respawn path can drop it. Tests pin exactly the ADDED env
keys (never full-env equality — the server inherits the host env by design),
the fork's Basic base64(opencode:pw) credential shape, and that two mints
differ.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
With route auth armed, the extension's own calls 401 without it — found four
surfaces, each now authenticated and pinned by tests against real transports:
- ServerManager health probe (derives Basic from the spawn env it injected,
  so probe and server can never drift; real-spawn fake-binary test)
- SSE /event subscription (silent retry-loop forever otherwise; live http
  server captures the Authorization header)
- fetchProviderSignal /config* probes (boot signal, healthcheck, chat gate —
  would read 'server unreachable' forever)
- chat iframe src ?auth_token= — the fork app's own credential bootstrap
  (entry.tsx adopts it for its authenticated-fetch path and strips the URL);
  no-token path unchanged for the unsecured dev server
Also fork parity on OPENCODE_SERVER_USERNAME: the spawned server inherits a
host-env override, so the credential builders honor it too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The channel scans landed with their transports (server_manager / sse_client
sweep real captured output; chat_panel pins the raw value out of the webview
html). These close the two remaining leak seams: mintServerPassword never
writes the host process env (in-memory only, per the no-persist decision),
and a poisoned env can't surface the password in OPENCODE_CONFIG_CONTENT
(dumpable via opencode debug config) — same idiom as the D11 key guard.

Verified against the live vendored fork (v1.17.3-amicode.5, serve on a
scratch port): anonymous /, /amicode/vaults, /event, /config/providers all
401 with the password armed; our Basic header and the app's ?auth_token
bootstrap both 200.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner and others added 5 commits July 19, 2026 21:09
…off argv

readPasqalCredentials (AMICO_PASQAL_FILE → ~/.amico/pasqal.json), interpreter
resolution (AMICO_PYTHON → python3 on PATH, absolute-path spawn), and a
built-from-scratch minimal child env: PATH + PASQAL_TOKEN + PASQAL_PROJECT_ID,
never a process.env spread. The launcher takes no flags at all, so no secret
can ride our argv; the fake-interpreter shim records argv+env and the tests
assert env-carriage, exact-key minimality, argv cleanliness, and verbatim
child exit-code passthrough (connector exit-3 stays 3).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n-free

Missing file ('not connected — … Connections panel'), unparseable file
('malformed … reconnect'), wrong shape (names keys only — a value could be a
mistyped secret; null token rejected per the #162 no-nulls-at-rest contract),
expired token ('expired at <iso> — reconnect', injectable clock), and the two
interpreter lanes (AMICO_PYTHON named vs python3-on-PATH hint) — all exit-64
config-class, cleanly distinct from the connector's own exit-3 unreachable
passthrough. No message may ever contain the token value.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…corpus bytes

Vendor cloud.json + pasqal.json byte-for-byte (sha256-verified) from the
opencode fork's canonical corpus (packages/opencode/test/server/fixtures/
credentials, provenance header in the consuming test). The test pins BOTH the
exact at-rest bytes (2-space JSON + trailing newline, key order) and the real
parse: readRemoteConfig via AMICO_CLOUD_FILE → {baseUrl, token}, and
readPasqalCredentials via AMICO_PASQAL_FILE (parse-level only — expiry is
launch-time, keeping the golden test time-independent). Any byte drift on
either side of the repo boundary fails here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…le e2e

Third bin from the package (the amico-run/amico pattern): package.json bin →
launcher/amico-pasqal bash shim → dist/amico-pasqal.js (esbuild) → the thin
pasqal_cli.ts entry over pasqal_launch.ts. Bundle-level e2e proves the shipped
artifact: env-injection happy lane (argv stays token-free at the bin layer),
the not-connected 64 lane on stderr, --help documenting the ENV ONLY contract,
and the bin/launcher wiring itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kateebonner and others added 5 commits July 20, 2026 00:30
…branch

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
setCloudKey's logic re-points at the fork's one-round-trip submit route
(POST /amicode/connections/credential, #163 boot credential in
Authorization, token only in the JSON body): the server owns
validate -> write -> HP flip, so the command's whole side-effect budget
is one HTTP call. classifyValidation / validateCloudKey /
buildCloudConfig are deleted (dead in the command path); the direct
probe of the external Solve Service is gone with them.

Review findings addressed in the mapping: (1) connected + error field
renders as connected-warning, never a clean success; (5) the vacuous
classifyValidation leak test is replaced by adversarial redaction tests
over server/transport error text embedding the token; (6) the prod URL
is single-sourced in DEFAULT_CLOUD_URL — package.json's amicode.cloudUrl
default drops to "" (description: built-in production endpoint) and a
test pins the non-duplication.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
extension.ts's runSetCloudKey is now a thin vscode wiring around
runSetCloudKeyCommand: input box / progress / toasts injected, server =
opencodeReadyUrl + the #163 Basic header (the sse_client/chat_panel
idiom), cloudUrl passed raw (the core resolves the "" -> default). The
direct cloud.json write and the direct applyEntitlementForMode +
writeSolverModeSwitching flip are deleted from the command path — the
server flips exactly once via #167 (AC3).

writeSolverModeSwitching itself is removed from solver_mode.ts: its only
caller was this command, and keeping an exported client-side flip writer
around invites the duplicate-flip bug back (review finding 3 — rotation
while already HP causes no client-side flip logic at all; server
idempotence owns it). The watcher contract test now writes the server's
literal {mode, status:"switching"} JSON instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kateebonner
kateebonner merged commit 886a737 into main Jul 20, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Connections panel — credentialed backends (Company Compute + Pasqal Cloud) in the app UI

1 participant