@ours.network/install 1.2.1-nightly.3 → 1.2.1-nightly.30
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.
- package/GATEWAY_SETUP.md +178 -0
- package/README.md +320 -9
- package/ROOTLESS_PODMAN_VALIDATION.md +210 -0
- package/assets/Dockerfile +17 -13
- package/assets/Dockerfile.gateway +5 -0
- package/assets/docker-compose.yaml +1 -1
- package/assets/fleet-settings.example.json +48 -0
- package/assets/gateway-entrypoint.sh +37 -0
- package/assets/release-lock.json +1122 -4471
- package/assets/release.json +33 -19
- package/assets/scripts/build/build-common.mjs +1 -1
- package/assets/scripts/build/build-sdk.mjs +6 -1
- package/assets/scripts/maintenance/build-context.mjs +1 -1
- package/assets/scripts/maintenance/daemon-owner.mjs +15 -0
- package/assets/scripts/maintenance/docker-layout-conversion.mjs +7 -3
- package/assets/scripts/maintenance/release-graph.mjs +18 -1
- package/assets/scripts/maintenance/state-operation.mjs +4 -2
- package/assets/scripts/runtime/client-setup.mjs +23 -5
- package/assets/scripts/runtime/diagnostics.mjs +72 -0
- package/assets/scripts/runtime/entrypoint.sh +1 -1
- package/assets/sources.json +46 -28
- package/install.mjs +7 -2
- package/lib/build-transition.mjs +1 -0
- package/lib/client-cli.mjs +127 -0
- package/lib/container-engine.mjs +127 -0
- package/lib/diagnostics.mjs +1 -0
- package/lib/docker-conversion-runtime.mjs +3 -2
- package/lib/docker-layout-installation.mjs +2 -1
- package/lib/docker-runtime-repair.mjs +160 -0
- package/lib/effects.mjs +278 -130
- package/lib/gateway-transition.mjs +87 -0
- package/lib/gateway.mjs +142 -0
- package/lib/legacy-migration.mjs +13 -2
- package/lib/orchestrate.mjs +129 -43
- package/lib/plan.mjs +22 -9
- package/lib/podman-preflight.mjs +40 -0
- package/lib/server-onboarding.mjs +154 -16
- package/lib/server-ports.mjs +17 -0
- package/lib/setup-options.mjs +88 -27
- package/lib/setup.mjs +35 -18
- package/lib/target.mjs +24 -8
- package/lib/uninstall.mjs +2 -2
- package/lib/usage.mjs +19 -6
- package/lib/workspace-setup.mjs +83 -0
- package/package.json +4 -2
package/GATEWAY_SETUP.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Set up Ours with one client connection
|
|
2
|
+
|
|
3
|
+
Fleet, the `ours` CLI and MCP clients share `~/.ours-client/profile.json`.
|
|
4
|
+
Set the server address once. The address is the HTTP gateway: clients append
|
|
5
|
+
`/daemon`, `/cowork`, `/messenger` or `/tg-connector` as needed. They do not
|
|
6
|
+
connect to server Unix sockets, discover server state directories, or try port
|
|
7
|
+
3050 after a connection failure. Fleet's local supervisor/harness sockets still
|
|
8
|
+
control local processes; they do not carry server management requests.
|
|
9
|
+
|
|
10
|
+
## Release availability
|
|
11
|
+
|
|
12
|
+
The nightly manifest selects one published dependency graph: SDK
|
|
13
|
+
`3.8.1-nightly.14`, CLI `2.8.1-nightly.12`, daemon `3.8.1-nightly.6`,
|
|
14
|
+
Fleet `1.2.0-nightly.17`, MCP/Codex/Claude Code `1.2.0-nightly.9`,
|
|
15
|
+
Telegram `1.0.1-nightly.8`, Messenger `1.0.31-nightly.8`, and Cowork
|
|
16
|
+
`1.3.3-nightly.20260926.ceab465`. Exact archive checksums are retained in
|
|
17
|
+
`releases/nightly.json`; the host CLI uses the same SDK/CLI pair.
|
|
18
|
+
|
|
19
|
+
The coordinated installer release must include these pins before using the
|
|
20
|
+
commands below. Its release gate verifies the actual registry and vendored
|
|
21
|
+
package graphs, client acquisition/retry, and rejection of dependency drift.
|
|
22
|
+
These checks do not deploy or certify an existing server installation.
|
|
23
|
+
|
|
24
|
+
The daemon includes ADAPT SDK/native `0.12.1` and the shutdown socket-reset
|
|
25
|
+
correction from [SDK PR70](https://github.com/adapt-toolkit/ours-sdk/pull/70).
|
|
26
|
+
Client profile commands do not control server processes.
|
|
27
|
+
|
|
28
|
+
## Fresh full-stack setup on localhost:4050
|
|
29
|
+
|
|
30
|
+
For an agent asked to “put the daemon on localhost port 4050”, use **4050 as the
|
|
31
|
+
public gateway port**. The daemon's internal container port stays 3050. Docker
|
|
32
|
+
publishes only the gateway. Run as the user who will run Fleet and the harnesses.
|
|
33
|
+
Use Node.js 22+ and a working Docker Compose installation.
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
npm install -g @ours.network/install@nightly
|
|
37
|
+
ours-install all install --mode docker \
|
|
38
|
+
--state-dir "$HOME/ours-server" --identity-name "Your Name" \
|
|
39
|
+
--port 4050 --integrations codex,claude-code
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The installer starts the server, retains or creates its Human identity, issues a
|
|
43
|
+
separate client credential, and imports the connection into `~/.ours-client`.
|
|
44
|
+
For Fleet, add `fleet` to `--integrations` and provide
|
|
45
|
+
`--fleet-settings /absolute/path/fleet-settings.json`; see the Fleet settings
|
|
46
|
+
example in [assets/fleet-settings.example.json](assets/fleet-settings.example.json).
|
|
47
|
+
The example selects Codex for all three jobs; review its model and subscription
|
|
48
|
+
against the installed Fleet catalog before use. The installer prepares Fleet but leaves it
|
|
49
|
+
stopped for review. Use `--dry-run` first to inspect a complete preset.
|
|
50
|
+
|
|
51
|
+
Do not set `OURS_PORT=4050` in a client shell, Fleet role, or user service. The
|
|
52
|
+
single profile contains `serverUrl: "http://127.0.0.1:4050"`, with daemon requests
|
|
53
|
+
at `http://127.0.0.1:4050/daemon` and Cowork management at
|
|
54
|
+
`http://127.0.0.1:4050/cowork/management/rpc`.
|
|
55
|
+
|
|
56
|
+
## Existing or remote server
|
|
57
|
+
|
|
58
|
+
An older Docker installation needs its gateway enabled on the **server host**:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
ours-install server gateway-enable --state-dir "$HOME/ours-server"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This is a server migration that may restart its services; perform it in an
|
|
65
|
+
approved maintenance window. Do not change identities or reinstall a populated
|
|
66
|
+
server to change a client address. `--port` on an existing installation cannot
|
|
67
|
+
silently move the retained public port.
|
|
68
|
+
|
|
69
|
+
For a remote host, expose the gateway through an authenticated HTTPS entrypoint
|
|
70
|
+
and select that URL when installing the server, for example
|
|
71
|
+
`--server-url https://ours.example.net/base`. The reverse proxy must preserve the
|
|
72
|
+
base prefix, streaming responses and WebSocket upgrades. Do not expose the
|
|
73
|
+
individual service ports.
|
|
74
|
+
|
|
75
|
+
Obtain an issued credential using `ours-install server access-issue --state-dir
|
|
76
|
+
/absolute/server/root --output /private/credential` on the server. Transfer it
|
|
77
|
+
privately to the client user. Never print the credential or put it into command
|
|
78
|
+
arguments, source control, chat, or a service unit. Use a private directory
|
|
79
|
+
(mode 0700) and credential/profile files (mode 0600).
|
|
80
|
+
|
|
81
|
+
Prepare a client profile (the UUID must be the selected server's actual instance):
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"serverUrl": "https://ours.example.net/base",
|
|
86
|
+
"endpoint": "https://ours.example.net/base/daemon",
|
|
87
|
+
"expectedInstanceId": "11111111-2222-3333-4444-555555555555",
|
|
88
|
+
"credentialPath": "/absolute/private/credential"
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`endpoint` is optional for the client resolver; when present it must exactly match
|
|
93
|
+
`serverUrl + "/daemon"` after trailing-slash normalization. Older endpoint-only
|
|
94
|
+
profiles must be migrated explicitly: supply the actual gateway URL, not a
|
|
95
|
+
guessed address derived from a direct daemon port.
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
ours-install client --config /absolute/private/profile.json \
|
|
99
|
+
--integrations codex,claude-code
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This imports the profile and issued credential into `~/.ours-client`. All new
|
|
103
|
+
clients use that default without an environment export. A conflicting existing
|
|
104
|
+
server instance is refused and retained; do not delete it to bypass that check.
|
|
105
|
+
To change only the gateway address of the same server, prepare a private profile
|
|
106
|
+
with the new `serverUrl` and matching `/daemon` endpoint, keep its actual
|
|
107
|
+
`expectedInstanceId`, and run the same `ours-install client --config ...` command.
|
|
108
|
+
The installer validates authenticated access before importing the new address;
|
|
109
|
+
it preserves imported Fleet settings. New processes use the new address. A
|
|
110
|
+
failed verification leaves the old selection intact. A different server UUID
|
|
111
|
+
requires a separately planned migration, not an address edit.
|
|
112
|
+
|
|
113
|
+
Changing the retained Docker public listening port in place is not currently
|
|
114
|
+
supported. `--port 4050` above is for a fresh server. For an existing server,
|
|
115
|
+
configure an administered reverse proxy to its gateway at the desired address,
|
|
116
|
+
then use the same-instance client address procedure. Do not edit installation
|
|
117
|
+
state or recreate containers with new identities to work around this limitation.
|
|
118
|
+
Native server installations currently need a separately administered gateway;
|
|
119
|
+
the integrated gateway setup above uses Docker (or supported Podman Compose).
|
|
120
|
+
|
|
121
|
+
## Fleet and systemd
|
|
122
|
+
|
|
123
|
+
For a new Fleet setup, save the linked JSON example as an absolute private file
|
|
124
|
+
and run as the same user after importing the client profile:
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
ours-fleet init --settings /absolute/path/fleet-settings.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
If the installer already imported Fleet settings, reuse them explicitly:
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
ours-fleet init --settings "$HOME/.ours-client/fleet-settings.json"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
These commands work without a terminal. A bare `ours-fleet init` is interactive.
|
|
137
|
+
The installer also accepts `--fleet-settings /absolute/path/fleet-settings.json`
|
|
138
|
+
and passes it to this same noninteractive path. Generated systemd and launchd services persist only the common
|
|
139
|
+
profile path, not a service URL, port, or token. Lingering user services therefore
|
|
140
|
+
use the same selection as CLI and MCP after logout/reboot. Detached Fleet task
|
|
141
|
+
workers inherit the common profile and do not inherit legacy service selectors.
|
|
142
|
+
|
|
143
|
+
`OURS_CONFIG` is an explicit override for the **whole client profile**. Use it only
|
|
144
|
+
when all relevant clients intentionally share that same alternate file. It is
|
|
145
|
+
not a per-service address override. For the normal setup, leave it unset.
|
|
146
|
+
|
|
147
|
+
When migrating existing units, inspect `systemctl --user cat 'ours-fleet-agent@.service'`
|
|
148
|
+
and any per-role drop-ins. Remove stale `OURS_PORT`, `OURS_STATE_DIR`,
|
|
149
|
+
`OURS_API_TOKEN`, `OURS_DAEMON_ID` and Cowork-local overrides from their owning
|
|
150
|
+
configuration. Regenerate Fleet units with `ours-fleet init --settings /absolute/path/fleet-settings.json`
|
|
151
|
+
in the intended profile environment, then restart affected client roles only after approval.
|
|
152
|
+
Already-running clients retain their current connection until restarted; editing
|
|
153
|
+
a profile does not rebind running identities. Do not restart the server for a
|
|
154
|
+
client-only profile correction.
|
|
155
|
+
|
|
156
|
+
## Verify and diagnose
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
curl --fail http://127.0.0.1:4050/.well-known/ours
|
|
160
|
+
ours config show --json
|
|
161
|
+
ours identity list --json
|
|
162
|
+
ours-fleet doctor
|
|
163
|
+
ours-fleet room list
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Discovery must advertise the gateway and expected instance. `ours config show`
|
|
167
|
+
shows only connection metadata and a credential path, never the token. For a
|
|
168
|
+
remote server use its exact prefix in the discovery URL. Test both daemon
|
|
169
|
+
identity access and Cowork room listing: one succeeding does not prove the other.
|
|
170
|
+
Check `command -v ours-mcp` and `ours-mcp version` as well as the MCP binary launched
|
|
171
|
+
by the harness; Fleet can bundle a different MCP version than the global binary.
|
|
172
|
+
|
|
173
|
+
Missing/unsafe profiles, mismatched instances, rejected credentials, HTTP errors
|
|
174
|
+
and timeouts fail on the selected gateway. Fix that selection or service; do not
|
|
175
|
+
add localhost/socket fallbacks. If a task reports `room_probe_unavailable`, check
|
|
176
|
+
Cowork through the gateway. `control_unavailable` means Fleet could not query its
|
|
177
|
+
local role supervisor after its room checks; inspect the role's supervisor and
|
|
178
|
+
control channel separately. An active room alone does not establish agent readiness.
|
package/README.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## Install first, connect the App afterwards
|
|
2
|
+
|
|
3
|
+
```sh
|
|
4
|
+
ours-install --username alex --name Alex --surname Taylor --disable-fleet-agents-setup
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
This permanent command contains no tunnel credentials or enrollment expiry. On a terminal it asks for the remaining installation choices, including Docker, Podman or native packages. The username is local and has no global uniqueness check. A fresh root is named `<username>@<hostname>`; the optional `--hostname` defaults to the machine name. Messenger stores Name and Surname through its supported profile API. Retried setup retains root identities and existing Messenger profiles.
|
|
8
|
+
|
|
9
|
+
`--disable-fleet-agents-setup` installs the Fleet CLI and saves the choice without opening its agent/model wizard or rewriting existing Fleet configuration. Configure agents in the App after device linking. Complete presets still work unattended; partial presets require a terminal and cannot use `OURS_ASSUME_YES`.
|
|
10
|
+
|
|
11
|
+
The separate `ours-fleet setup-tunnel --file /private/setup-payload` step requires the matching Fleet follow-up release. Its private App payload remains scoped, signed-root-bound and expiring. Then run `ours-fleet link-device` and paste its private single-use code into the App. Do not put the expiring tunnel payload in the permanent installer command.
|
|
12
|
+
|
|
13
|
+
Native packages currently provide server-only installation; full Fleet/App onboarding requires the supported gateway (Docker or Podman). The installer refuses unsupported native full-stack setup before changing anything. This PR does not add a native gateway or release unpublished Fleet commands.
|
|
14
|
+
|
|
15
|
+
See [one-connection setup, localhost:4050 and systemd migration](GATEWAY_SETUP.md) for the gateway-only client workflow.
|
|
16
|
+
|
|
1
17
|
# @ours.network/install — one installer for the whole stack
|
|
2
18
|
|
|
3
19
|
Requires Node.js 22+ and npm. Install the selected release channel:
|
|
@@ -10,8 +26,8 @@ ours-install
|
|
|
10
26
|
With no arguments, the wizard explains each step and offers keyboard choices.
|
|
11
27
|
Use arrow keys and Enter to choose, and Space to select integrations. Recommended
|
|
12
28
|
settings keep advanced ports and package overrides out of the usual flow. Text
|
|
13
|
-
input is used for your name and explicitly customized paths or ports.
|
|
14
|
-
|
|
29
|
+
input is used for your name and explicitly customized paths or ports. Docker is recommended for the integrated full-stack gateway on every platform;
|
|
30
|
+
native packages remain available for server-only setup. On Windows run the
|
|
15
31
|
installer inside WSL with Docker Desktop integration. This recommendation concerns
|
|
16
32
|
packaging and isolation, not a guarantee that emulated x64 is faster on ARM Macs.
|
|
17
33
|
|
|
@@ -45,7 +61,7 @@ installers. `--integrations none` explicitly skips client integrations. Use
|
|
|
45
61
|
Fleet's own wizard is available only in interactive setup; CLI Fleet setup requires
|
|
46
62
|
its JSON settings file. Fleet stays stopped until you review and activate it.
|
|
47
63
|
|
|
48
|
-
The server installs the daemon/SDK/CLI,
|
|
64
|
+
The server installs the daemon/SDK/CLI, Telegram, Cowork and Messenger.
|
|
49
65
|
It starts the daemon, preserves the existing Human identity (or creates it once),
|
|
50
66
|
then starts its applications. Full-stack setup issues a separate local client
|
|
51
67
|
credential and configures the selected Codex, Claude Code and Fleet integrations.
|
|
@@ -56,6 +72,28 @@ The installer embeds exact component versions and SHA-512 values for its release
|
|
|
56
72
|
An existing server's retained release selects matching local clients. Secrets are
|
|
57
73
|
read from protected files, and client setup never copies the daemon API master.
|
|
58
74
|
|
|
75
|
+
## Runtime and client packages
|
|
76
|
+
|
|
77
|
+
Server selections include `@ours.network/daemon`, whose `ours-daemon` binary owns
|
|
78
|
+
runtime startup and service administration. Docker runs `ours-daemon serve`;
|
|
79
|
+
native installations install its systemd/launchd service. Existing retained
|
|
80
|
+
installations can still stop and restore their older CLI-owned runtime.
|
|
81
|
+
|
|
82
|
+
Client selections contain the thin SDK and CLI, plus MCP when a harness needs
|
|
83
|
+
it. They exclude the daemon and its native database/ADAPT dependencies. Fleet
|
|
84
|
+
runs beside the harnesses on the client machine and calls the daemon HTTP API.
|
|
85
|
+
Client commands report an unavailable server and never start one automatically.
|
|
86
|
+
|
|
87
|
+
The checked-in source policy and packed installer retain the existing server
|
|
88
|
+
release set (SDK `3.8.1-nightly.11`, CLI `2.8.1-nightly.9`, daemon
|
|
89
|
+
`3.8.1-nightly.3`). The isolated host CLI uses published SDK
|
|
90
|
+
`3.8.1-nightly.13` and CLI `2.8.1-nightly.11`, including the shared gateway
|
|
91
|
+
profile resolver. `releases/nightly.json` binds both selections to verified
|
|
92
|
+
SHA512 integrities. Gateway-only Fleet/MCP release adoption is still pending;
|
|
93
|
+
see [GATEWAY_SETUP.md](GATEWAY_SETUP.md). Mixed or unselected nested ours
|
|
94
|
+
versions remain rejected within each selected graph. An explicit `--sources`
|
|
95
|
+
override remains available for development.
|
|
96
|
+
|
|
59
97
|
## Migrate an existing global installation
|
|
60
98
|
|
|
61
99
|
The wizard detects the old `~/.ours/config.json` and offers to keep its identities,
|
|
@@ -137,8 +175,8 @@ native package acquisition, and reports completion only after service readiness.
|
|
|
137
175
|
If a Docker service fails, the error includes its last 50 log lines (bounded in
|
|
138
176
|
size) and a command to inspect the logs. A failed daemon prevents consumers from
|
|
139
177
|
starting; a failed consumer does not prevent checks of unrelated consumers.
|
|
140
|
-
Server runtime installation selects SDK/CLI,
|
|
141
|
-
Messenger.
|
|
178
|
+
Server runtime installation selects SDK/CLI, Telegram, Cowork and
|
|
179
|
+
Messenger. MCP runs locally with the Codex and Claude Code plugins and calls the daemon API through the SDK.
|
|
142
180
|
The daemon starts first; consumers are checked through their owning readiness
|
|
143
181
|
interfaces. Messenger uses its existing identity prerequisite and never creates an
|
|
144
182
|
identity. Its failure is reported after attempting unrelated consumers. Package
|
|
@@ -195,9 +233,9 @@ relative to the profile file. Select any nonempty subset of integrations; Fleet
|
|
|
195
233
|
When Fleet settings are supplied, the installer passes them to Fleet's strict
|
|
196
234
|
noninteractive `init --settings`; otherwise it opens Fleet's existing wizard.
|
|
197
235
|
Fleet validates and publishes its own configuration. Client setup verifies the selected
|
|
198
|
-
daemon
|
|
236
|
+
authenticated daemon API before registering native integrations. It acquires
|
|
199
237
|
only selected integration packages and their actual client dependencies. It does
|
|
200
|
-
not
|
|
238
|
+
not administer daemon state or invoke Docker. Codex and Claude Code include the local stdio MCP server as a dependency. Exact npm client
|
|
201
239
|
installation needs no Python; Git source builds use the supplied source recipes
|
|
202
240
|
and their build prerequisites. Normal native clients need neither Docker nor
|
|
203
241
|
server maintenance tools.
|
|
@@ -213,7 +251,8 @@ an existing override and does not edit shell configuration or running sessions.
|
|
|
213
251
|
Repeat with `ours-install client install` to reuse imported inputs and installed
|
|
214
252
|
package records. Existing settings and Fleet-generated files are preserved. A
|
|
215
253
|
prepared profile for the same endpoint/instance may supply a valid replacement
|
|
216
|
-
issued token;
|
|
254
|
+
issued token; a different server instance is refused without changing the default. A verified
|
|
255
|
+
new gateway address for the same instance updates the shared profile for new clients. Invalid
|
|
217
256
|
server access is rejected before import. An acquisition or component failure
|
|
218
257
|
reports incomplete setup and keeps the saved configuration for retry. Selected
|
|
219
258
|
native integrations whose executable is unavailable are incomplete, not installed.
|
|
@@ -224,7 +263,7 @@ Interactive no-argument installation asks for package/Docker server mode, a
|
|
|
224
263
|
prepared client profile, or `client`. Client setup offers the saved server when
|
|
225
264
|
present. On first setup it asks for the server HTTP endpoint, issued-token file,
|
|
226
265
|
source manifest and integration choices, obtains the instance UUID from
|
|
227
|
-
|
|
266
|
+
`/.well-known/ours` at the gateway, displays it, then checks authenticated daemon API access before
|
|
228
267
|
saving anything. No UUID must be entered manually. The 2.0 HTTP flow assumes the
|
|
229
268
|
approved trusted same-host deployment; selection metadata is not cryptographic
|
|
230
269
|
server authentication. Fleet collects missing setup answers through its own wizard.
|
|
@@ -281,3 +320,275 @@ maintenance reads both formats. Format2 is not readable by older maintenance too
|
|
|
281
320
|
so this change does not promise executable downgrade support. Restore validates the
|
|
282
321
|
original archive records unchanged, then writes markers for the active target runtime.
|
|
283
322
|
Mixed/incomplete context and component record sets are refused before activation.
|
|
323
|
+
|
|
324
|
+
### Retrying a Docker installation after a source-policy permission failure
|
|
325
|
+
|
|
326
|
+
Setup verifies the selected Docker image before reusing it, including when the image
|
|
327
|
+
already exists. If an older installer left a root-owned, mode-0600
|
|
328
|
+
`/opt/ours/sources.json`, setup repairs only that image file's permissions and
|
|
329
|
+
continues. The selected package bytes, build provenance, image execution settings,
|
|
330
|
+
credentials and stored data are retained. The old materialized Dockerfile's known
|
|
331
|
+
COPY instruction is also corrected for future builds. No manual image or volume
|
|
332
|
+
deletion is required; repeat the original setup with the updated installer.
|
|
333
|
+
|
|
334
|
+
The repair runs isolated verification containers without state mounts or network
|
|
335
|
+
access. Other image verification failures stop setup without replacing the image.
|
|
336
|
+
An interrupted repair can be retried, including after the image tag was replaced.
|
|
337
|
+
|
|
338
|
+
### Remote clients over HTTPS
|
|
339
|
+
|
|
340
|
+
A client may select an `https://` origin backed by a TLS reverse proxy. Keep the
|
|
341
|
+
daemon listener private and configure the proxy separately with a certificate
|
|
342
|
+
trusted by the client and matching the hostname. Node uses its normal trust
|
|
343
|
+
store; a private CA may be supplied through `NODE_EXTRA_CA_CERTS` before starting
|
|
344
|
+
the client. Certificate verification must remain enabled.
|
|
345
|
+
|
|
346
|
+
The existing issued client credential works over either transport; changing the
|
|
347
|
+
URL scheme does not require a new credential. Keep the server's master on the
|
|
348
|
+
server. Forward `x-ours-api-token` and the `x-ours-*` session headers unchanged,
|
|
349
|
+
and support streamed request/response bodies and long polling. Client requests
|
|
350
|
+
refuse redirects, including HTTPS-to-HTTP redirects: configure the final HTTPS
|
|
351
|
+
origin directly. UUID/capability checks still precede credential-bearing calls.
|
|
352
|
+
|
|
353
|
+
This adds client HTTPS support, not an HTTPS daemon listener, certificate
|
|
354
|
+
provisioning or automatic reverse-proxy configuration. Existing local HTTP and
|
|
355
|
+
SSH-tunnel profiles continue to work.
|
|
356
|
+
|
|
357
|
+
## One-URL Docker gateway
|
|
358
|
+
|
|
359
|
+
New Docker installations use one loopback-published nginx port (default 3050).
|
|
360
|
+
Clients import one `serverUrl`; their daemon endpoint is `<serverUrl>/daemon` and
|
|
361
|
+
Fleet derives `<serverUrl>/cowork/management/rpc`. Cowork, Messenger and Telegram
|
|
362
|
+
backend ports are internal only. Existing installations retain their prior layout
|
|
363
|
+
on ordinary install/update. Select compatible releases before explicitly migrating:
|
|
364
|
+
|
|
365
|
+
```sh
|
|
366
|
+
ours-install server gateway-enable --state-dir /private/ours
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Migration checks the installed Cowork, Messenger and Telegram capabilities before
|
|
370
|
+
stopping services, verifies authenticated daemon and read-only Cowork management,
|
|
371
|
+
and preserves the existing credential and client integration settings. Failure
|
|
372
|
+
restores routing, client profile and prior service selection. An interrupted
|
|
373
|
+
migration blocks other mutations: repeat `gateway-enable` to finish rollback,
|
|
374
|
+
then run it again to attempt migration. The private `gateway-transition.json`
|
|
375
|
+
retains recovery state until rollback or migration completes. Back up the whole
|
|
376
|
+
installation using the normal server backup procedure before maintenance.
|
|
377
|
+
|
|
378
|
+
For a nested external URL, pass `--server-url https://ours.example/base` during
|
|
379
|
+
Docker install or `gateway-enable`. This sets browser origin and path configuration;
|
|
380
|
+
it does **not** publish a public listener, provide TLS, or install external
|
|
381
|
+
credentials. Configure the authenticated entry first and retain the `/base` path
|
|
382
|
+
when proxying. A compatible release must contain these capabilities:
|
|
383
|
+
`cowork.http-management-v1`, `messenger.gateway-prefix-v1`, and
|
|
384
|
+
`telegram.gateway-listener-v1`. Older releases are rejected without enabling the
|
|
385
|
+
new listener; no package version is silently substituted.
|
|
386
|
+
|
|
387
|
+
### Authenticated external entry
|
|
388
|
+
|
|
389
|
+
Messenger has no application authentication. Loopback access trusts local users;
|
|
390
|
+
never forward this gateway publicly without authentication. All applications on
|
|
391
|
+
this origin share one trust boundary: scripts or XSS in any application can make
|
|
392
|
+
requests to the others. Cowork's entered server credential grants operator room
|
|
393
|
+
administration and stays in memory until reload. Path prefixes do not isolate
|
|
394
|
+
applications. Only expose this origin to trusted operators.
|
|
395
|
+
|
|
396
|
+
A supported external entry is nginx TLS plus HTTP Basic authentication for browser
|
|
397
|
+
paths, with machine paths left to their existing server-token checks. Create the
|
|
398
|
+
password file using an interactive `htpasswd` prompt and make it readable by the
|
|
399
|
+
proxy worker. Use real certificates and the matching `--server-url`. The inner
|
|
400
|
+
gateway remains bound to `127.0.0.1:3050`; neither backend ports nor the inner
|
|
401
|
+
listener should be externally forwarded. Example for `/base`:
|
|
402
|
+
|
|
403
|
+
```nginx
|
|
404
|
+
# In http {}:
|
|
405
|
+
map $http_upgrade $ours_connection { default upgrade; '' close; }
|
|
406
|
+
server {
|
|
407
|
+
listen 443 ssl;
|
|
408
|
+
server_name ours.example;
|
|
409
|
+
ssl_certificate /private/tls/fullchain.pem;
|
|
410
|
+
ssl_certificate_key /private/tls/key.pem;
|
|
411
|
+
auth_basic "ours operators";
|
|
412
|
+
auth_basic_user_file /private/ours-users;
|
|
413
|
+
access_log off;
|
|
414
|
+
proxy_set_header Host $http_host;
|
|
415
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
416
|
+
proxy_set_header Connection $ours_connection;
|
|
417
|
+
proxy_http_version 1.1;
|
|
418
|
+
proxy_read_timeout 300s;
|
|
419
|
+
proxy_buffering off;
|
|
420
|
+
location = /base/.well-known/ours { auth_basic off; proxy_pass http://127.0.0.1:3050; }
|
|
421
|
+
location /base/daemon/ { auth_basic off; proxy_pass http://127.0.0.1:3050; }
|
|
422
|
+
location = /base/cowork/management/rpc { auth_basic off; proxy_pass http://127.0.0.1:3050; }
|
|
423
|
+
location /base/tg-connector/ { auth_basic off; proxy_pass http://127.0.0.1:3050; }
|
|
424
|
+
location /base/ { proxy_pass http://127.0.0.1:3050; }
|
|
425
|
+
location / { return 404; }
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Browser requests include same-origin proxy credentials. Fleet/SDK use the issued
|
|
430
|
+
`X-Ours-Api-Token`, require no browser login, and reject redirects. An SSH tunnel
|
|
431
|
+
to the loopback gateway is another private transport option, but every client must
|
|
432
|
+
establish its own tunnel and use a URL/origin matching that tunnel; it is not
|
|
433
|
+
automatic remote access. Do not treat a token entered in Cowork as Messenger auth.
|
|
434
|
+
|
|
435
|
+
Publish compatible Cowork, Messenger, Telegram and Fleet artifacts before enabling
|
|
436
|
+
gateway defaults in a qualified installer release. Gateway client setup acquires
|
|
437
|
+
and checks Fleet before activating the managed profile or publishing native
|
|
438
|
+
commands. Migration also checks the installed `ours-fleet version --json`
|
|
439
|
+
capability before stopping services when the selected managed profile includes
|
|
440
|
+
Fleet. Upgrade that executable first. The gate does not inventory differently pinned
|
|
441
|
+
running Fleet instances or remote clients: upgrade every client using this server
|
|
442
|
+
to a compatible Fleet release before cutover.
|
|
443
|
+
|
|
444
|
+
### Cross-repository gateway qualification
|
|
445
|
+
|
|
446
|
+
Build Cowork, Fleet, Messenger and Telegram checkouts with their locked dependencies.
|
|
447
|
+
The real-service test uses disposable local daemon state, a local test broker,
|
|
448
|
+
nginx Docker containers and Chromium; it never uses installed identities or tokens.
|
|
449
|
+
It requires Linux Docker host networking and `openssl`. Set:
|
|
450
|
+
|
|
451
|
+
```sh
|
|
452
|
+
OURS_TEST_GATEWAY_SERVICES=1 \
|
|
453
|
+
OURS_TEST_COWORK_ROOT=/checkouts/ours-cowork \
|
|
454
|
+
OURS_TEST_FLEET_ROOT=/checkouts/ours-fleet \
|
|
455
|
+
OURS_TEST_MESSENGER_ROOT=/checkouts/ours-messenger-server \
|
|
456
|
+
OURS_TEST_TELEGRAM_ROOT=/checkouts/ours-tg-connector \
|
|
457
|
+
OURS_TEST_BROWSER=/opt/google/chrome/chrome \
|
|
458
|
+
node --test packages/installer/test/gateway-services.test.mjs
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
Run `OURS_TEST_DOCKER=1 node --test packages/installer/test/gateway-docker.test.mjs`
|
|
462
|
+
separately for Compose port isolation with a client container. That routing test
|
|
463
|
+
uses echo upstreams; the real-service test covers Fleet room operations, browser
|
|
464
|
+
paths, external authentication and Messenger WebSocket access. Neither test is
|
|
465
|
+
cross-platform Docker Desktop qualification or a live deployment test.
|
|
466
|
+
|
|
467
|
+
### Rootless Podman (qualification in progress)
|
|
468
|
+
|
|
469
|
+
Container installations can select a local Linux rootless backend explicitly:
|
|
470
|
+
|
|
471
|
+
```sh
|
|
472
|
+
export PODMAN_COMPOSE_PROVIDER=/absolute/path/to/docker-compose
|
|
473
|
+
ours-install server install --mode docker --container-engine podman \
|
|
474
|
+
--state-dir "$HOME/.ours-server-podman" --identity-name "Your Name"
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
`mode: docker` remains the legacy container-layout name. `containerEngine` and
|
|
478
|
+
`containerBinding` retain Podman, the invoking UID, native storage paths, socket
|
|
479
|
+
and standalone Compose provider, plus the UID/GID mapping fingerprint. Records without `containerEngine` continue to
|
|
480
|
+
use Docker. Package/client installs reject the engine option. Existing records
|
|
481
|
+
cannot change engines through a flag or ambient connection change; automatic
|
|
482
|
+
Docker-to-Podman data migration is not provided. Legacy local-daemon migration
|
|
483
|
+
(`--migrate-from`) to Podman is also unsupported and is refused before source
|
|
484
|
+
shutdown or managed CLI publication, including migration retries. Use a fresh
|
|
485
|
+
Podman installation, or migrate the legacy daemon with Docker/packages.
|
|
486
|
+
|
|
487
|
+
Podman uses its native build command, with the same resolved Compose build
|
|
488
|
+
context, target, architecture, arguments and secret references, followed by
|
|
489
|
+
Compose `--no-build` startup. It does not require the Docker CLI or daemon.
|
|
490
|
+
The selected standalone Docker Compose provider must be version 2.35 or newer;
|
|
491
|
+
version checks do not replace the behavioral capability probe. `podman-compose`
|
|
492
|
+
is not an interchangeable provider for this implementation. Secrets sourced
|
|
493
|
+
from environment variables use Podman's native build-secret mechanism, never
|
|
494
|
+
build arguments or temporary copies.
|
|
495
|
+
|
|
496
|
+
Prerequisites include a working rootless API socket, sufficient subordinate
|
|
497
|
+
UID/GID mappings, and native volume-subpath isolation. Before setup/start, an
|
|
498
|
+
isolated disposable project tests Compose `!reset`, health waiting, JSON status,
|
|
499
|
+
service DNS, private UID-1000 storage and subpath isolation. A failed check stops
|
|
500
|
+
installation rather than substituting the whole volume. Existing volumes must
|
|
501
|
+
have this installation's project and volume labels. Docker contexts, unrelated
|
|
502
|
+
containers and host directory ownership are not changed.
|
|
503
|
+
|
|
504
|
+
Server boot recovery requires an enabled user `podman.socket`, an enabled
|
|
505
|
+
`podman-restart.service` using `--filter should-start-on-boot=true`, and user
|
|
506
|
+
linger. The standard user-service environment/default socket must select the
|
|
507
|
+
same storage; custom XDG paths and sockets are rejected for server startup.
|
|
508
|
+
The installer diagnoses missing prerequisites and never runs hidden sudo or
|
|
509
|
+
rewrites the vendor unit. Long-running Podman services get `unless-stopped`;
|
|
510
|
+
administration jobs do not. Stop/status remain available when boot prerequisites
|
|
511
|
+
are missing, provided the retained backend is accessible. Runtime-only test
|
|
512
|
+
harnesses may select a separate local socket with `OURS_PODMAN_SOCKET`; its
|
|
513
|
+
storage must match native Podman and the selection cannot change afterward.
|
|
514
|
+
|
|
515
|
+
Gateway images read and validate IPv4/IPv6 nameservers from their container at
|
|
516
|
+
startup. Only the resolver placeholder is replaced; nginx variables and existing
|
|
517
|
+
authentication/routes remain intact. UID 101, read-only rootfs, dropped
|
|
518
|
+
capabilities and tmpfs are retained. Setup and start verify authenticated
|
|
519
|
+
upstream requests in addition to liveness.
|
|
520
|
+
|
|
521
|
+
This change is **not yet a fully qualified server-support release**. Debian's
|
|
522
|
+
Podman 5.4.2 with Compose 5.5.1 failed subpath isolation and has incompatible boot
|
|
523
|
+
recovery semantics. Podman 6.1.2 passed the isolated capability probe on native
|
|
524
|
+
Linux amd64; production and prerelease-source builds, service lifecycle, rebuild and scoped maintenance also passed. See [validation evidence](ROOTLESS_PODMAN_VALIDATION.md). The full public installer/maintenance matrix,
|
|
525
|
+
SELinux Enforcing, logout/reboot, explicit-stop recovery, and Docker regression
|
|
526
|
+
matrix must all be recorded before declaring a supported engine/provider pair.
|
|
527
|
+
The supplied ARM VM results are historical feasibility evidence, not this
|
|
528
|
+
release's qualification.
|
|
529
|
+
|
|
530
|
+
Opt-in gateway fixture (isolated project, only owned resources removed):
|
|
531
|
+
|
|
532
|
+
```sh
|
|
533
|
+
OURS_TEST_DOCKER=1 node --test test/gateway-docker.test.mjs
|
|
534
|
+
PODMAN_COMPOSE_PROVIDER=/absolute/path/to/docker-compose \
|
|
535
|
+
OURS_TEST_PODMAN=1 node --test test/gateway-docker.test.mjs
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
## Account workspace enrollment (task build)
|
|
539
|
+
|
|
540
|
+
The unmerged account onboarding feature requires matching reviewed installer,
|
|
541
|
+
Fleet and Messenger task builds. Do not advertise it as available in `@latest`.
|
|
542
|
+
Use an owned private directory and a 0600 downloaded payload:
|
|
543
|
+
|
|
544
|
+
```sh
|
|
545
|
+
node /absolute/task-ours-network/packages/installer/install.mjs \
|
|
546
|
+
--setup-workspace-file /absolute/private/workspace.payload \
|
|
547
|
+
--workspace-fleet-bin /absolute/task-ours-fleet/dist/cli.js \
|
|
548
|
+
--sources /absolute/private/task-sources.json
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
The wrapper defaults fresh hosts to the full Docker stack and retains existing
|
|
552
|
+
Human roots through the installed SDK with exact instance/private credential
|
|
553
|
+
selection. For an existing supported gateway add `--scope client --config` with
|
|
554
|
+
its private profile. It clears competing inherited daemon selectors before Fleet
|
|
555
|
+
initialization and enrollment; it never copies a browser device bearer to the
|
|
556
|
+
account server. A private stdin payload is also accepted by `--setup-workspace -`.
|
|
557
|
+
Encoding is not encryption; command arguments can enter history/process listings.
|
|
558
|
+
Cloudflare management tokens are forbidden in these payloads.
|
|
559
|
+
|
|
560
|
+
Docker and `cloudflared` are required for the fresh workflow. Supply a complete
|
|
561
|
+
`--fleet-settings` JSON for noninteractive Fleet initialization, or answer its
|
|
562
|
+
terminal prompts. Dry-run never initializes or enrolls Fleet. Read the matching
|
|
563
|
+
ours-app `server/DEPLOYMENT.md` for exact task source-policy generation, external
|
|
564
|
+
Google/Cloudflare prerequisites and account-server setup. On uncertain enrollment
|
|
565
|
+
check account status before requesting a new payload; do not reset identities or
|
|
566
|
+
replay a consumed invitation.
|
|
567
|
+
|
|
568
|
+
Workspace setup accepts exactly https://app.ours.network and the controlled test
|
|
569
|
+
account origin https://app.ours-tunnel.com. To move an existing same workspace to
|
|
570
|
+
the other origin, obtain a fresh payload from the moved account server and add
|
|
571
|
+
`--workspace-migrate-app-origin`. Fleet verifies the signed binding receipt before
|
|
572
|
+
changing local origin trust, preserves identities/config/device records, and
|
|
573
|
+
restarts the runtime. An implicit origin change is rejected. Browser account
|
|
574
|
+
cookies/device IndexedDB must be linked anew on the new origin. See the app
|
|
575
|
+
server/DEPLOYMENT.md switching procedure.
|
|
576
|
+
|
|
577
|
+
Workspace setup automatically reuses the saved managed gateway profile (or explicit `--config`/`OURS_CONFIG`), including a host with a non-default server state directory. It does not reinstall server/client state, create a root, or initialize an existing Fleet configuration. It requires Fleet capability `workspace.enroll.preserve-profile-v1` and passes `--preserve-profile`; Fleet requires the matching Messenger capability before posting signed enrollment. Hosts running older Messenger must first update that host service through its supported installer lifecycle; this wrapper never guesses or replaces its server directory. After Owner releases Messenger/Fleet/installer, app bootstrap pins must be updated before removing the preview guard.
|
|
578
|
+
|
|
579
|
+
### Private-context Docker script permissions
|
|
580
|
+
|
|
581
|
+
Fresh image builds explicitly make non-secret maintenance/runtime scripts readable by the container user even when the host build context was copied under umask077. Host scripts, selected source policy and state retain their private permissions.
|
|
582
|
+
|
|
583
|
+
For a pending installation using an older image, run the corrected installer against the same pending workspace. It recognizes older shipped script COPY instructions combined with private host script modes, updates those image COPY modes and rebuilds the daemon image from the retained source selection. It leaves host data and enrollment state intact and qualifies the rebuilt image before preparing services. A private retry marker retains the rebuild requirement after interruption; it is removed only after verification succeeds. This rebuild resolves third-party transitive dependencies using the existing testing-delivery rules; selected Ours versions and integrity remain release-checked. It is not a byte-identical image permission-layer repair.
|
|
584
|
+
|
|
585
|
+
Fresh server setup checks its loopback daemon, Cowork and Messenger ports before
|
|
586
|
+
writing the installation configuration. Occupied implicit defaults advance to a
|
|
587
|
+
free port, skipping reserved sibling ports; the selected values are saved in the
|
|
588
|
+
installation record and used by native/container services, gateway and client
|
|
589
|
+
profile generation. An explicitly requested occupied port fails with a diagnostic.
|
|
590
|
+
Existing installation records keep their ports and identities. A listener acquired
|
|
591
|
+
by another process after preflight still causes startup to fail safely; no foreign
|
|
592
|
+
process is stopped and no retained installation is silently moved.
|
|
593
|
+
|
|
594
|
+
Workspace setup pins Fleet `1.2.0-nightly.38` with its recorded registry integrity. This release includes first-time Fleet setup through the host API for the account App, direct App access to the workspace services with the device credential, separate `ours-fleet setup-tunnel` and `ours-fleet link-device` commands, host prerequisite checks before the one-time workspace proof (`setup-tunnel --check`), `setup-tunnel --resume` to finish a setup that stopped after the host saved its private pending setup record (not when the proof's answer was lost, or after the setup window expired with an unconfirmed non-default port), and persists the available Fleet loopback port used by the workspace tunnel. It also accepts a setup-generated configuration left behind after the host enrollment state was removed, runs the host Codex when it is at least as new as the packaged one, offers only the Codex models the signed-in account can use, and removes the temporary setup contact after confirmation. Fleet serves no pages and opens no browser: every screen is in the App. Existing installation identities and configured ports remain retained; a retained-port collision fails safely.
|