Repository navigation
docs(skill): teach ocx the remote hub roles, pairing boundary, and disconnect halves - #3165
Conversation
…sconnect halves An agent reading skills/ocx had no way to answer two questions it will be asked. The first is whether configuring a hub requires pairing. It does not. GET /opencodex-session mints a session on its own for a loopback request, and for a hub reached through the trusted Tailscale ingress when the login is in remoteGui.allowedTailscaleUsers (src/server/gui-session.ts:177-193). A pairing grant is the fallback for a remote browser that neither position nor identity vouches for, and the management API is a separate admission ladder again (src/server/management-auth.ts:471-491) which an agent drives with the admin token and never pairs at all. The second is that ocx disconnect is only half of leaving a hub. It restores local state and clears the connection, then reports that the hub key is still valid -- stopping there leaves a working credential behind. Revocation is the other half: connect revoke while still connected, or delete the key in the hub dashboard once the device is gone. Also records why rotation is a two-step commit (the old key has to outlive the moment the new one is issued, or a client that has not been updated is stranded), why the four disconnect refusals are the safety property rather than an obstacle, and that credentials are stdin-only with no argv form. references/05_remote_hub.md carries the detail; SKILL.md carries the two corrections inline so an agent that never opens the reference still answers correctly. The test's reference list grows by one entry.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
✅ Deterministic PR hygiene checks passed. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a789b8c54
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "runtimeRole": "hub", | ||
| "hub": { "managementPublicOrigin": "https://host.ts.net" } |
There was a problem hiding this comment.
Include the data-listener bind in the minimum hub config
On a fresh install where no reverse proxy already forwards the data plane, following this “Minimum hub config” leaves hostname unset; startServer consequently binds the main listener to 127.0.0.1 in src/server/index.ts, so another machine cannot reach the hub or run ocx connect. Include a remotely reachable hostname, or relabel this as role-only configuration and direct agents to the full deployment prerequisites.
AGENTS.md reference: AGENTS.md:L181-L183
Useful? React with 👍 / 👎.
| |---|---| | ||
| | `Token file` | `owned` is nominal. `changed` means another process overwrote the token, and `disconnect` will refuse until that is resolved. | | ||
| | `Key rotation` | `recovery-required` means a rotation was interrupted. Re-run `connect rotate` to commit or abort it. | | ||
| | `Catalog` | `unsafe` means the catalog bytes are not the ones this connection wrote. | |
There was a problem hiding this comment.
Stop claiming status verifies catalog ownership
When a user or another process replaces the catalog bytes with any regular file, collectClientConnectionStatus still reports present: it only checks lstatSync(...).isFile(), while unsafe is reserved for a symlink, non-file, or stat failure. An agent relying on this table will therefore miss catalog drift until disconnect refuses it; describe unsafe accurately and state that status does not hash-check ownership, or compare the file against the saved catalogFingerprint.
AGENTS.md reference: AGENTS.md:L181-L183
Useful? React with 👍 / 👎.
| When `disconnect` refuses, do not route around it. Each refusal means the unwind cannot be | ||
| proven safe: another process owns the token, no journal records the pre-connect state, a | ||
| different client key owns the journal, or the restore was only partial. |
There was a problem hiding this comment.
Cover the other disconnect refusal paths
For a connected client whose service token is missing or whose catalog bytes changed, disconnectClient refuses with errors not represented by this exhaustive “each refusal ... or” list; it can also refuse if the token changes during removal or client state races the final commit (src/client/connect.ts). Agents following the operating reference will have no safe guidance for these common drift cases, so include the omitted classes and remedies or clearly label the four listed cases as examples and instruct agents to preserve state and report the exact error.
AGENTS.md reference: AGENTS.md:L181-L183
Useful? React with 👍 / 👎.
…sconnect halves (lidge-jun#3165) An agent reading skills/ocx had no way to answer two questions it will be asked. The first is whether configuring a hub requires pairing. It does not. GET /opencodex-session mints a session on its own for a loopback request, and for a hub reached through the trusted Tailscale ingress when the login is in remoteGui.allowedTailscaleUsers (src/server/gui-session.ts:177-193). A pairing grant is the fallback for a remote browser that neither position nor identity vouches for, and the management API is a separate admission ladder again (src/server/management-auth.ts:471-491) which an agent drives with the admin token and never pairs at all. The second is that ocx disconnect is only half of leaving a hub. It restores local state and clears the connection, then reports that the hub key is still valid -- stopping there leaves a working credential behind. Revocation is the other half: connect revoke while still connected, or delete the key in the hub dashboard once the device is gone. Also records why rotation is a two-step commit (the old key has to outlive the moment the new one is issued, or a client that has not been updated is stranded), why the four disconnect refusals are the safety property rather than an obstacle, and that credentials are stdin-only with no argv form. references/05_remote_hub.md carries the detail; SKILL.md carries the two corrections inline so an agent that never opens the reference still answers correctly. The test's reference list grows by one entry. Co-authored-by: jun <jun@lidge.dev>
…sconnect halves (lidge-jun#3165) An agent reading skills/ocx had no way to answer two questions it will be asked. The first is whether configuring a hub requires pairing. It does not. GET /opencodex-session mints a session on its own for a loopback request, and for a hub reached through the trusted Tailscale ingress when the login is in remoteGui.allowedTailscaleUsers (src/server/gui-session.ts:177-193). A pairing grant is the fallback for a remote browser that neither position nor identity vouches for, and the management API is a separate admission ladder again (src/server/management-auth.ts:471-491) which an agent drives with the admin token and never pairs at all. The second is that ocx disconnect is only half of leaving a hub. It restores local state and clears the connection, then reports that the hub key is still valid -- stopping there leaves a working credential behind. Revocation is the other half: connect revoke while still connected, or delete the key in the hub dashboard once the device is gone. Also records why rotation is a two-step commit (the old key has to outlive the moment the new one is issued, or a client that has not been updated is stranded), why the four disconnect refusals are the safety property rather than an obstacle, and that credentials are stdin-only with no argv form. references/05_remote_hub.md carries the detail; SKILL.md carries the two corrections inline so an agent that never opens the reference still answers correctly. The test's reference list grows by one entry. Co-authored-by: jun <jun@lidge.dev>
Summary
skills/ocx/references/05_remote_hub.mdand a short inline section inSKILL.mdso an agent operating a proxy can answer two remote-hub questions it will be asked, and answer them correctly.GET /opencodex-sessionmints a session on its own for a loopback request, and for ahubreached through the trusted Tailscale ingress when the login is inremoteGui.allowedTailscaleUsers(src/server/gui-session.ts:177-193). A pairing grant is the fallback for a remote browser that neither position nor identity vouches for. The management API is a separate admission ladder again (src/server/management-auth.ts:471-491), which an agent drives with the admin token and never pairs for. Without this written down, the plausible-sounding wrong answer is "yes, you have to pair first."ocx disconnectis only half of leaving a hub. It restores local state and clears the connection, then reports that the hub key is still valid. The reference states both halves and which one applies when the device is gone.disconnectrefusals as a safety property rather than an obstacle, and that credentials are stdin-only with no argv form.Docs and one test-list entry. No runtime change.
Verification
bun test tests/skill-ocx.test.ts— 11 pass, 0 fail, 81 expect() calls. That suite is the relevant one: it asserts everyocx <command>named anywhere in the skill exists in the CLI registry, which is what stops a reference from documenting a command nobody can run.REFERENCESin the test grows by one entry, and the "SKILL.md routes to every reference it ships" assertion covers the new file.skill:surface:checkand the generated01_management_surface.mdare unaffected.Checklist
disconnectrefusals must not be routed around.