@abot-ai/socket 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +21 -0
  3. package/README.md +129 -2
  4. package/bin/abot-socket.mjs +15 -0
  5. package/config.example.json +14 -0
  6. package/docs/APP-REVIEW.md +184 -0
  7. package/docs/DEPLOYMENT.md +124 -0
  8. package/docs/INSTALLATION.md +177 -0
  9. package/docs/MIGRATION.md +84 -0
  10. package/docs/PROTOCOL.md +371 -0
  11. package/docs/SECURITY.md +116 -0
  12. package/docs/SELF-HOSTING.md +161 -0
  13. package/package.json +65 -4
  14. package/src/auth/auth-database.mjs +105 -0
  15. package/src/auth/auth-limits.mjs +17 -0
  16. package/src/auth/auth-pairing.mjs +95 -0
  17. package/src/auth/auth-sessions.mjs +119 -0
  18. package/src/auth/auth-storage-path.mjs +70 -0
  19. package/src/auth/auth.mjs +45 -0
  20. package/src/auth/runtime-credentials.mjs +39 -0
  21. package/src/cli/cli-arguments.mjs +23 -0
  22. package/src/cli/cli-entry.mjs +84 -0
  23. package/src/cli/cli-environment.mjs +31 -0
  24. package/src/cli/cli-help.mjs +34 -0
  25. package/src/cli/cli-output.mjs +35 -0
  26. package/src/cli/cli.mjs +58 -0
  27. package/src/cli/client-capabilities.mjs +14 -0
  28. package/src/cli/doctor.mjs +106 -0
  29. package/src/config/config-validation.mjs +41 -0
  30. package/src/config/config.mjs +57 -0
  31. package/src/deployment/deployment-command.mjs +42 -0
  32. package/src/deployment/deployment-input.mjs +76 -0
  33. package/src/deployment/deployment-plan.mjs +62 -0
  34. package/src/deployment/deployment-templates.mjs +109 -0
  35. package/src/main.mjs +26 -0
  36. package/src/notifications/notification-delivery-credentials.mjs +48 -0
  37. package/src/notifications/notification-delivery-fcm.mjs +100 -0
  38. package/src/notifications/notification-delivery-gateway.mjs +36 -0
  39. package/src/notifications/notification-delivery-http.mjs +53 -0
  40. package/src/notifications/notification-delivery-payload.mjs +45 -0
  41. package/src/notifications/notification-delivery.mjs +43 -0
  42. package/src/notifications/notification-gateway-command.mjs +48 -0
  43. package/src/notifications/notification-gateway-store.mjs +159 -0
  44. package/src/notifications/notification-gateway.mjs +181 -0
  45. package/src/notifications/notification-http.mjs +39 -0
  46. package/src/notifications/notification-input.mjs +82 -0
  47. package/src/notifications/notification-outbox.mjs +60 -0
  48. package/src/notifications/notification-preview-crypto.mjs +42 -0
  49. package/src/notifications/notification-preview-schema.mjs +7 -0
  50. package/src/notifications/notification-preview-store.mjs +63 -0
  51. package/src/notifications/notification-preview-text.mjs +20 -0
  52. package/src/notifications/notification-projection.mjs +20 -0
  53. package/src/notifications/notification-schema.mjs +22 -0
  54. package/src/notifications/notification-service.mjs +147 -0
  55. package/src/notifications/notification-store.mjs +132 -0
  56. package/src/pairing/pairing-qr-payload.mjs +32 -0
  57. package/src/pairing/pairing-qr.mjs +42 -0
  58. package/src/protocol/approval-protocol.mjs +39 -0
  59. package/src/protocol/protocol-validation.mjs +137 -0
  60. package/src/protocol/protocol.mjs +120 -0
  61. package/src/protocol/spark-chat-protocol.mjs +51 -0
  62. package/src/relay/relay-approvals.mjs +86 -0
  63. package/src/relay/relay-client-admission.mjs +40 -0
  64. package/src/relay/relay-correlations.mjs +101 -0
  65. package/src/relay/relay-model-catalog.mjs +69 -0
  66. package/src/relay/relay-request-adoption.mjs +97 -0
  67. package/src/relay/relay-requests.mjs +211 -0
  68. package/src/relay/relay-runtime-registration.mjs +49 -0
  69. package/src/relay/relay-session-mutations.mjs +122 -0
  70. package/src/relay/relay.mjs +222 -0
  71. package/src/relay/request-ownership-schema.mjs +18 -0
  72. package/src/relay/request-ownership-store.mjs +115 -0
  73. package/src/review/review-demo-isolation.mjs +132 -0
  74. package/src/review/review-demo-setup.mjs +97 -0
  75. package/src/review/review-portal-access.mjs +64 -0
  76. package/src/review/review-portal-form.mjs +24 -0
  77. package/src/review/review-portal-page.mjs +68 -0
  78. package/src/review/review-portal-server.mjs +105 -0
  79. package/src/setup/setup-files.mjs +37 -0
  80. package/src/setup/setup-questions.mjs +62 -0
  81. package/src/setup/setup-wizard.mjs +50 -0
  82. package/src/setup/setup.mjs +42 -0
  83. package/src/transport/http-api.mjs +32 -0
  84. package/src/transport/server.mjs +175 -0
  85. package/src/transport/transport-limits.mjs +85 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,38 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 - 2026-11-14
4
+
5
+ ### Added
6
+
7
+ - Recover pending tool approvals after client reconnects and Socket or runtime
8
+ restarts, using persistent request ownership and runtime-authoritative waits.
9
+ - Continue and approve requests started on the computer from a paired client,
10
+ after the current runtime confirms the exact session and request. Existing
11
+ ownership is never reassigned to another owner or session.
12
+ - Open and chat with the runtime's SPARK companion through compatible clients,
13
+ using its configured model and permissions. This does not expose SPARK
14
+ management, settings writes or proactive activity.
15
+
16
+ ### Fixed
17
+
18
+ - Restore scoped live request delivery when recovering an owned request, without
19
+ rerunning it or reconstructing events missed during disconnection.
20
+
21
+ ### Upgrade notes
22
+
23
+ - New features require a compatible client and the selected runtime's
24
+ `request_approvals_v1` or `spark_chat_v1` capability. Legacy chat and live-only
25
+ approval behavior remain available when the new capabilities are not used.
26
+ - Private SQLite state upgrades transactionally from schema v1, v2 or v3 to v4.
27
+ Existing pairing, device credentials, notification metadata, preview keys and
28
+ delivery queues are preserved. Stop the service and back up its private state
29
+ and matching code before upgrading; rollback requires both the pre-upgrade
30
+ state and old code. See [Migration](docs/MIGRATION.md).
31
+ - Node.js 24 or later remains required. Dependencies and the HTTP/WebSocket
32
+ protocol envelope are unchanged.
33
+
34
+ ## 0.1.0 - 2026-11-11
35
+
36
+ - Initial MIT-licensed npm release with authenticated runtime relay, QR/manual
37
+ pairing, device revocation, notification delivery and optional encrypted
38
+ previews, and CLI setup/deployment guidance.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dor Shitrit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,130 @@
1
- # Temporary Holding Version
1
+ # ABot Socket
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A self-hosted chat relay between a native ABot client and your ABot Runtime
4
+ instances. You operate the relay, pair your devices, and connect your own
5
+ computers. The relay does not require an ABot-hosted account or backend.
6
+
7
+ The source is available under the [MIT license](LICENSE). Install the versioned
8
+ `@abot-ai/socket` package from npm, or build a local tarball from source.
9
+ See the [changelog](CHANGELOG.md) for release notes and upgrade requirements.
10
+
11
+ ## Install and prepare
12
+
13
+ Start with [Installation and first connection](docs/INSTALLATION.md), the consumer
14
+ guide for installing the command, preparing a server, connecting a runtime and
15
+ pairing the app by QR or manual entry.
16
+
17
+ ```sh
18
+ npm install --global @abot-ai/socket@0.2.0
19
+ abot-socket setup
20
+ ```
21
+
22
+ The command requires Node.js 24 or later. Its terminal wizard creates private
23
+ configuration/state and, on Linux, reviewable systemd/HTTPS proxy files. The
24
+ operator supplies DNS, TLS, service activation and the runtime's bridge settings.
25
+ Neither npm installation nor setup activates those services; no install hook runs.
26
+
27
+ - [Installation](docs/INSTALLATION.md): wizard, defaults, runtime connection and pairing.
28
+ - [Deployment](docs/DEPLOYMENT.md): explicit Linux service and HTTPS activation.
29
+ - [Self-hosting](docs/SELF-HOSTING.md): configuration, operation and the proxy trust boundary.
30
+ - [Protocol](docs/PROTOCOL.md): pairing API and existing runtime bridge.
31
+ - [Security](docs/SECURITY.md): authentication, trust boundaries and limitations.
32
+ - [Migration](docs/MIGRATION.md): moving an existing installation deliberately.
33
+ - [App review preparation](docs/APP-REVIEW.md): a separate review installation,
34
+ protected renewable pairing access and the remaining deployment/device checks.
35
+
36
+ `abot-socket start` runs the relay in the foreground. `abot-socket doctor` checks
37
+ public HTTPS relay health without credentials; runtime readiness is verified in
38
+ the paired app. `abot-socket pair` creates fresh one-time pairing details and
39
+ displays a private QR in a capable terminal. Scanner-enabled clients can scan it
40
+ and confirm the server address; manual entry remains available.
41
+
42
+ ## Scope
43
+
44
+ One installation represents one owner, with up to 10 paired devices and 16
45
+ runtimes. Pairing requires a six-digit code and a separate random temporary key
46
+ created locally by the operator. Both expire after five minutes or one successful
47
+ use. There is no email delivery or central authentication provider.
48
+
49
+ ABot App scans the private pairing QR and asks you to confirm its server address.
50
+ Manual code, HTTPS URL and temporary-key entry remains available. The app receives
51
+ its own device credential; never copy the runtime credential into the app.
52
+
53
+ The relay supports chat, steering, tool approvals, runtime history, model selection
54
+ and attachments through the runtime Bridge. Compatible clients can recover pending
55
+ approvals across reconnects and restarts, continue requests created on their
56
+ computer, and open the runtime's SPARK companion chat. SPARK model settings and
57
+ permissions remain runtime-owned; management and proactive activity are not exposed.
58
+ These features require the selected runtime to advertise `request_approvals_v1`
59
+ or `spark_chat_v1` respectively; older runtimes retain the legacy chat path.
60
+ The relay does not execute models or store conversation history. Configure the
61
+ runtime's existing Bridge; this installer does not modify runtime source.
62
+
63
+ Device sessions last up to 30 days without sliding renewal and survive restarts
64
+ in a private SQLite database. Operators can list and revoke devices locally.
65
+ The device-scoped notification inbox records completion, failure and observed
66
+ approval events for routed requests. Notifications belong to the initiating device
67
+ or the device that first recovers a computer-created request through the verified
68
+ ownership flow; later recovery by another device does not transfer that inbox.
69
+ Push delivery is off by default;
70
+ operators may configure their own FCM sender or an explicitly trusted ABot push
71
+ gateway. Notifications are generic by default. An optional per-device encrypted
72
+ preview can show a bounded final-answer excerpt; the gateway/provider never gets
73
+ the preview key or plaintext. The app remains usable without push.
74
+ Cancellation and reconstruction of events missed while disconnected are not
75
+ implemented. Approval recovery queries current runtime state and restores scoped
76
+ live delivery; it never automatically resends an interrupted request. The relay
77
+ host is trusted and can read routed content; transport encryption is not end-to-end
78
+ encryption.
79
+
80
+ Notification metadata, pending deliveries and durable request ownership share the
81
+ private SQLite state. Upgrading migrates schema v1, v2 or v3 to v4 without replacing
82
+ paired devices. Back up the private state and matching code while stopped before
83
+ upgrading. Older binaries cannot open v4; rollback requires the matching state
84
+ backup and old code together. See [migration](docs/MIGRATION.md#durable-request-ownership-schema-upgrade)
85
+ and [notification protocol and delivery](docs/PROTOCOL.md#notifications).
86
+
87
+ ## Source layout
88
+
89
+ `bin/abot-socket.mjs` is the installed entry point; `src/main.mjs` starts a
90
+ configured relay. The source modules are grouped by responsibility:
91
+
92
+ | Directory | Owns |
93
+ | --- | --- |
94
+ | `src/cli/`, `src/setup/` | Command dispatch, operator output and new-installation preparation. |
95
+ | `src/config/`, `src/deployment/` | Private configuration validation and reviewable service/proxy plans. |
96
+ | `src/auth/`, `src/pairing/` | Durable device credentials, revocation and one-use pairing/QR. |
97
+ | `src/transport/`, `src/protocol/` | HTTP/WebSocket boundary, limits and allowed client message shapes. |
98
+ | `src/relay/` | Runtime routing, correlations, request ownership and session operations. |
99
+ | `src/notifications/` | Device inbox/outbox, delivery adapters, gateway and encrypted previews. |
100
+ | `src/review/` | Separate app-review installation and protected pairing portal. |
101
+
102
+ ## Local validation
103
+
104
+ From the development checkout, install the locked dependencies and run the local tests:
105
+
106
+ ```sh
107
+ npm ci --omit=optional --ignore-scripts
108
+ npm test
109
+ ```
110
+
111
+ Runtime dependencies are pinned `ws` for transport and `qrcode-generator` for
112
+ local pairing QR generation; the latter has no runtime dependencies. Source tests and
113
+ package-verification scripts are not shipped inside the npm consumer package.
114
+
115
+ To inspect the exact distribution files before installing a source-built package:
116
+
117
+ ```sh
118
+ npm pack --ignore-scripts --json > /tmp/abot-socket-pack.json
119
+ npm run check-package -- /tmp/abot-socket-pack.json
120
+ ```
121
+
122
+ The tarball contains an explicit allowlist of runtime modules and consumer docs.
123
+ Keep credentials, machine configuration, state, logs and private support reports
124
+ outside the checkout. Never attach pairing codes or QR images to a public issue.
125
+
126
+ Tests use dummy identities and mock runtime peers. The transport tests
127
+ open loopback HTTP and WebSocket listeners; they do not connect to a live runtime
128
+ or send email. Run them only in an environment permitted for that local traffic.
129
+ Passing these tests does not establish proxy correctness,
130
+ or compatibility with a separately installed client/runtime version.
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Check before loading node:sqlite so unsupported Node versions get a useful error.
4
+ if (Number(process.versions.node.split('.')[0]) < 24) {
5
+ console.error('ABot Socket requires Node.js 24 or later. Install a supported Node.js version first.');
6
+ process.exitCode = 1;
7
+ } else {
8
+ try {
9
+ const { runEntry } = await import('../src/cli/cli-entry.mjs');
10
+ process.exitCode = await runEntry(process.argv.slice(2));
11
+ } catch {
12
+ console.error('ABot Socket could not complete the command. Check the local configuration and installation.');
13
+ process.exitCode = 1;
14
+ }
15
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "publicOrigin": "https://socket.example.invalid",
3
+ "port": 8788,
4
+ "runtimeGrants": [
5
+ {
6
+ "runtimeId": "workstation",
7
+ "tokenSha256": "REPLACE_WITH_SHA256_OF_A_NEW_RUNTIME_TOKEN",
8
+ "allowedModes": [
9
+ "ask"
10
+ ]
11
+ }
12
+ ],
13
+ "stateDirectory": "./state"
14
+ }
@@ -0,0 +1,184 @@
1
+ # Preparing a dedicated app-review installation
2
+
3
+ This guide prepares renewable access to an isolated review Socket using the
4
+ ordinary app pairing protocol. It does not deploy services, configure a model,
5
+ publish a package or establish App Store readiness. Actual hosting and signed
6
+ device checks remain required; installing the package does not complete them.
7
+
8
+ Apple requests full app access, necessary resources such as pairing QR codes,
9
+ and backend services that remain live during review. See the current
10
+ [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#before-you-submit),
11
+ including sections 2.1 and 2.3.1. Reviewers should not have to contact the developer
12
+ for each new five-minute code.
13
+
14
+ ## 1. Prepare a fresh installation
15
+
16
+ Use Node.js 24 or later and an explicitly installed package version. Choose a
17
+ new, private output directory outside source control. Its parent must already
18
+ exist; the output directory must not. Run setup as the account that will own and
19
+ run both processes; the private files are deliberately rejected for another owner.
20
+ Replace these reserved example origins
21
+ with the dedicated HTTPS origins you intend to operate:
22
+
23
+ ```sh
24
+ abot-socket review-setup \
25
+ --output /srv/abot-review \
26
+ --origin https://demo.example.test \
27
+ --runtime-id review-demo \
28
+ --review-origin https://review.example.test \
29
+ --port 8788 \
30
+ --review-port 8789
31
+ ```
32
+
33
+ The Socket and reviewer portal require distinct HTTPS origins and listener
34
+ ports. The default ports are 8788 and 8789. Pick unused ports if other services
35
+ share the host. These examples do not authorize or perform changes to those
36
+ services.
37
+
38
+ The command creates a separate installation rather than attaching review access
39
+ to an existing Socket:
40
+
41
+ | Output | Purpose |
42
+ | --- | --- |
43
+ | `config.json` | Configuration for the dedicated review Socket. |
44
+ | `runtime-connection.json` | Private bridge URL, runtime identity and runtime secret. |
45
+ | `state/` | Dedicated Socket database, ownership and review-installation metadata. |
46
+ | `review-portal.json` | Private portal configuration bound to this review installation. |
47
+ | `review-access.txt` | Portal URL, reviewer username and generated stable password. |
48
+
49
+ The directory is private and the credential/configuration files use mode 0600.
50
+ Console output identifies the files; do not copy their secret contents into
51
+ logs, source, screenshots or a public support page. Keep this installation's
52
+ state separate from production and from any push gateway database.
53
+
54
+ The portal verifies its fresh-installation marker and database owner as well as
55
+ the bound Socket identity: origin, state directory and runtime credentials.
56
+ Changing those identity fields makes the binding invalid. Do not edit a marker
57
+ or credential hash to attach the portal to another installation. This workflow
58
+ is not a migration or a generic pairing endpoint for an existing personal server.
59
+
60
+ ## 2. Configure the review runtime and optional push
61
+
62
+ Privately transfer `runtime-connection.json` only to the dedicated runtime host.
63
+ Use that runtime's existing bridge configuration to connect it; never enter the
64
+ runtime secret into the app or disclose it to reviewers. Configure a working
65
+ model and benign sample resources on that runtime. No runtime source changes
66
+ are required by this setup.
67
+
68
+ Provide enough access to exercise the app's normal features while isolating the
69
+ review workspace from personal files, accounts, credentials and production
70
+ administration. Do not rely on a home Mac remaining awake or on a developer
71
+ manually maintaining the connection during review. Hosting, model capacity and
72
+ availability are operator responsibilities.
73
+
74
+ The app uses the same submitted binary and standard behavior. There is no
75
+ reviewer-specific client mode, fake chat implementation or hidden feature switch.
76
+ Document the normal model/tool capabilities offered by this workspace.
77
+
78
+ Remote push remains disabled unless configured deliberately. If the submitted
79
+ app offers push, configure the dedicated Socket's appropriate delivery mode and
80
+ provider/gateway through the normal configuration described in
81
+ [Self-hosting](SELF-HOSTING.md) and [Deployment](DEPLOYMENT.md#optional-notification-gateway).
82
+ Keep sender credentials and gateway configuration private. Permitted operational
83
+ changes such as notification delivery and allowed permission modes do not replace
84
+ the installation's bound identity. Restart the affected process after a deliberate
85
+ configuration change, then verify the complete signed-device flow. Setup does not
86
+ prove push delivery or provision a sender service.
87
+
88
+ ## 3. Prepare separate HTTPS forwarding
89
+
90
+ Run each process behind its own HTTPS origin, forwarding only to the corresponding
91
+ loopback listener. Use valid certificates and separate proxy routes. Keep the
92
+ relay's WebSocket upgrade support; the reviewer portal is a separate HTTP service.
93
+
94
+ The direct HTTPS proxy must:
95
+
96
+ - Preserve `Host` for the intended public origin, and pass `Authorization` and
97
+ `Origin` without rewriting their meaning.
98
+ - Remove untrusted incoming `X-Forwarded-Proto` and `X-Socket-Client-IP`, then set
99
+ the verified HTTPS protocol and the actual connection client's IP itself.
100
+ Never trust a client-supplied forwarding header.
101
+ - Disable caching for the reviewer portal, including authenticated pages and
102
+ QR responses. Do not enable CDN caching for this origin.
103
+ - Disable proxy access/body/header logging and tracing for the reviewer portal.
104
+ Ensure upstream/CDN logging cannot record credentials, generated pairing
105
+ bundles or responses. Do not introduce secret logging in the relay either.
106
+
107
+ See [the proxy trust boundary](SELF-HOSTING.md#3-configure-https-and-the-proxy-boundary).
108
+ Additional proxies or a CDN require a separately validated trusted-peer policy;
109
+ copying their incoming IP headers is not sufficient. Configuring DNS, TLS,
110
+ firewalls, service users and process supervision is separate deployment work.
111
+ No setup command activates or reloads those components.
112
+
113
+ ## 4. Start and verify deliberately
114
+
115
+ After the hosting configuration has been reviewed, run the two processes with
116
+ the same Socket configuration path, in separate supervised processes or terminals:
117
+
118
+ ```sh
119
+ abot-socket start --config /srv/abot-review/config.json
120
+ ```
121
+
122
+ ```sh
123
+ abot-socket review-portal --config /srv/abot-review/config.json
124
+ ```
125
+
126
+ The second command derives the fixed sibling `review-portal.json`; do not pass
127
+ that file as the `--config` argument. Keep the separate portal origin and port
128
+ chosen during setup.
129
+
130
+ Open the protected `/review` webpage on the portal origin using the access
131
+ details in `review-access.txt` (for example, `https://review.example.test/review`).
132
+ Generate a fresh standard QR and pair the real app. The QR
133
+ lasts five minutes and is single-use. Generating another QR replaces the pending
134
+ one, while devices already paired successfully remain authorized.
135
+
136
+ Display the webpage on another screen for camera scanning. A reviewer using one
137
+ device can instead copy the displayed six-digit code, Socket URL and temporary
138
+ pairing key into the app's normal manual flow. The QR is not an app-opening link.
139
+ The app also requires the device's own passcode or biometric authentication;
140
+ this is separate from the webpage's reviewer login and Socket pairing code.
141
+
142
+ Put actual reviewer access details only in private App Review Information in
143
+ App Store Connect. Keep the portal login usable throughout review and allow
144
+ repeat pairing without developer intervention. Monitor capacity so additional
145
+ review devices can pair; revoke only obsolete review devices deliberately.
146
+
147
+ ## 5. Readiness record
148
+
149
+ Before submitting the app, verify and record:
150
+
151
+ - Both public HTTPS origins, their proxy boundaries and the protected portal
152
+ work externally; no secret appears in caches or operational logs.
153
+ - Fresh, expired, replaced and already-used pairing codes behave correctly.
154
+ Replacing a pending code leaves paired devices usable.
155
+ - The intended runtime is online, the configured model completes real chat
156
+ requests, and history, attachments, tool activity and approvals work with the
157
+ submitted app. An HTTP health check proves neither runtime nor model readiness.
158
+ - The runtime and review files are isolated from personal data, and availability
159
+ does not depend on a home computer or developer attendance.
160
+ - Device authentication, background return, camera permissions and manual
161
+ pairing work on the actual supported Apple devices and signed build.
162
+ - Any advertised push capability is configured and verified end to end,
163
+ including permission denial, background delivery and authenticated tap routing.
164
+ - App privacy disclosures describe actual Socket, runtime, model-provider,
165
+ Firebase/APNs and gateway traffic. User-controlled hosting is not a substitute
166
+ for verifying those data flows.
167
+
168
+ No deployment, live runtime/model test, notification send, account operation or
169
+ submission is implied by this guide. Keep readiness evidence and actual access
170
+ details outside the source repository.
171
+
172
+ ## 6. End or renew review access
173
+
174
+ Keep both services and the runtime available until the review and any follow-up
175
+ checks finish. Afterwards, stopping the portal prevents new reviewer pairings;
176
+ it does not revoke devices that have already paired. Inspect those devices with
177
+ `abot-socket devices --config /srv/abot-review/config.json` and revoke obsolete
178
+ ones with `abot-socket revoke <device-id> --config /srv/abot-review/config.json`.
179
+ Stop the dedicated Socket/runtime as well when the demo is no longer needed.
180
+
181
+ The reviewer password remains stable until the installation is retired. If it
182
+ needs replacement, prepare a new dedicated installation and replace the private
183
+ review instructions; do not weaken checks or reuse a production configuration.
184
+ Retiring or deleting actual hosted resources is a separate operator action.
@@ -0,0 +1,124 @@
1
+ # Preparing a Linux deployment
2
+
3
+ The deployment command creates files for operator review. It does not install
4
+ packages, enable services, reload a proxy, obtain certificates or change system
5
+ configuration. The existing operating-system user and proxy remain your choice.
6
+ Begin with [Installation](INSTALLATION.md) to install the package and
7
+ prepare private state; this guide is the subsequent service/HTTPS step.
8
+
9
+ After creating the private installation, prepare a plan on the Linux host where
10
+ the package is persistently installed. Run this as the installation owner; the
11
+ optional --user value must match that current unprivileged account:
12
+
13
+ ```sh
14
+ abot-socket deployment --config /srv/abot/config.json \
15
+ --output /srv/abot/deployment-plan --user abot --proxy nginx \
16
+ --certificate /etc/tls/socket/fullchain.pem \
17
+ --private-key /etc/tls/socket/private.key
18
+ ```
19
+
20
+ Use `--proxy apache` for Apache 2.4.47 or later. Use `--proxy none` if HTTPS is
21
+ already configured; certificate/key arguments are then unnecessary. The output
22
+ directory must not exist. Its parent must exist. Generated files use mode 0600
23
+ inside a new 0700 directory. No certificate contents or pairing secrets are read
24
+ or copied into the plan.
25
+
26
+ ## Review the service
27
+
28
+ The systemd unit runs the installed Node executable and CLI directly in the
29
+ foreground. It uses the specified unprivileged user, a 0077 umask, restart on
30
+ failure, and limits persistent writes to the configured state directory.
31
+
32
+ The named user must already exist and own the private configuration/state. The
33
+ state directory must exist with mode 0700 and its files must be private. It must
34
+ be outside temporary filesystem paths. The user also needs access to the Node
35
+ and package paths; a root-only Node installation cannot serve an unprivileged
36
+ application. Do not use an `npx` cache installation for a persistent service.
37
+
38
+ The plan contains exact executable/configuration paths. Regenerate it after
39
+ changing those locations. Paths with spaces are quoted; percent signs are escaped
40
+ for systemd. Other shell/proxy metacharacters are rejected rather than interpreted.
41
+ See [systemd command syntax](https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html).
42
+
43
+ ## Review HTTPS forwarding
44
+
45
+ The proxy examples require existing certificate/key files and a DNS hostname.
46
+ They preserve the incoming Host authority, including a non-default port, so the
47
+ relay can reject unknown authorities. They preserve Origin and Authorization,
48
+ support WebSocket upgrades and overwrite the trusted client-IP/protocol headers.
49
+ The generated proxy plans cap request bodies at 4 KiB. Application limits differ
50
+ by route: push registration accepts up to 8 KiB and preview-key registration up
51
+ to 512 bytes. See [HTTP limits](PROTOCOL.md#http); a stricter proxy limit wins.
52
+ If an installation needs the full registration limit, review that proxy setting
53
+ explicitly while retaining the application's route-specific limits.
54
+
55
+ The nginx example belongs in the `http` context and uses its connection address.
56
+ Review inherited real-IP settings before use. The Apache example uses
57
+ `CONN_REMOTE_ADDR`, the actual connection peer, and requires `ssl`, `headers`,
58
+ `proxy` and `proxy_http`. Apache also needs an existing Listen directive for the
59
+ HTTPS port; the plan does not add a potentially duplicate listener.
60
+
61
+ These examples describe a direct Internet-to-local-proxy-to-relay connection.
62
+ CDN or additional proxy chains need a separate trusted-peer policy. Keep pairing
63
+ details, request bodies and Authorization headers out of inherited logging rules.
64
+
65
+ References: [nginx WebSocket proxying](https://nginx.org/en/docs/http/websocket.html),
66
+ [Apache WebSocket upgrade](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html),
67
+ [Apache header handling](https://httpd.apache.org/docs/2.4/mod/mod_headers.html),
68
+ [Apache connection address](https://httpd.apache.org/docs/current/en/expr.html).
69
+
70
+ ## Apply explicitly
71
+
72
+ `DEPLOYMENT.txt` lists commands to run manually from the generated directory.
73
+ Inspect existing destination files before copying anything; these are new-install
74
+ examples, not an overwrite or migration tool. Execute one command at a time and
75
+ stop on a failure. Check the proxy configuration before reloading it. The Apache
76
+ command examples use Debian/Ubuntu conventions; other distributions differ.
77
+
78
+ The service starts separately from the HTTPS proxy. After verifying both, issue
79
+ fresh pairing details and connect the app. An HTTPS health response establishes
80
+ relay reachability; the paired app must still verify that the intended runtime
81
+ is online and can complete a chat request.
82
+
83
+ ## Optional notification gateway
84
+
85
+ Users of the Store app configure their Socket to use the publisher's trusted
86
+ gateway; they do not need to host this additional process. Self-built apps can
87
+ use their own FCM sender directly. See [push delivery configuration](SELF-HOSTING.md#optional-push-delivery).
88
+
89
+ The Store application's publisher can run a separate sender process from this
90
+ package. It is distinct from a user's Socket and must have its own private state
91
+ directory, HTTPS origin and Firebase service account. Nothing in ordinary Socket
92
+ setup creates an account, starts this gateway or enables remote delivery.
93
+
94
+ Keep the gateway JSON and service-account file outside source with mode `0600`:
95
+
96
+ ```json
97
+ {
98
+ "publicOrigin": "https://push.example.invalid",
99
+ "port": 8790,
100
+ "stateDirectory": "./push-state",
101
+ "serviceAccountFile": "./firebase-service-account.json"
102
+ }
103
+ ```
104
+
105
+ Run `abot-socket push-gateway --config /absolute/private/gateway.json` behind a
106
+ trusted HTTPS reverse proxy. Like the Socket, it binds loopback only; the proxy
107
+ must supply the verified client address and HTTPS forwarding headers described
108
+ in this guide and allow its bounded JSON requests up to 8 KiB. Do not reuse the
109
+ Socket's authentication state directory: the gateway
110
+ has a separate database identity and rejects mixed state.
111
+
112
+ The app uses `/v1/enroll` and `/v1/confirm` to prove receipt of a short-lived
113
+ provider challenge. It receives separate device-scoped send and revoke grants,
114
+ valid for up to 30 days. Only proof of receipt can replace an existing target.
115
+ The paired Socket calls `/v1/deliver` with the send grant, fixed event kind and
116
+ opaque notification ID. The gateway accepts neither arbitrary text nor a target
117
+ token from a sender. `/v1/revoke` requires the separate management grant.
118
+
119
+ Enrollment and sending have bounded rates, record counts, request sizes and
120
+ timeouts. Provider tokens and credential hashes stay in private gateway state.
121
+ The gateway sees delivery metadata, not chat text or pairing/runtime credentials.
122
+ Data-only enrollment delivery is best effort; a delayed challenge can expire
123
+ and must be retried while the app is open. Production deployment and a real
124
+ signed-device test remain separate from local mocked validation.