Skip to content

Commit cc4de16

Browse files
committed
fix: harden ordinary server setup
1 parent eed319a commit cc4de16

39 files changed

Lines changed: 3998 additions & 413 deletions
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: Ordinary server setup E2E
2+
3+
on:
4+
push:
5+
paths:
6+
- ".github/workflows/server-setup-e2e.yml"
7+
- "scripts/ci/ordinary-server-setup-e2e.sh"
8+
- "npm/**"
9+
- "src/agentnet/approval/cli_commands.py"
10+
- "src/agentnet/cli.py"
11+
- "src/agentnet/core/app.py"
12+
- "src/agentnet/operations/server_setup.py"
13+
- "src/agentnet/storage/postgres.py"
14+
- "skills/agentnet-operator/**"
15+
- "package.json"
16+
- "package-lock.json"
17+
- "pyproject.toml"
18+
- "uv.lock"
19+
pull_request:
20+
paths:
21+
- ".github/workflows/server-setup-e2e.yml"
22+
- "scripts/ci/ordinary-server-setup-e2e.sh"
23+
- "npm/**"
24+
- "src/agentnet/approval/cli_commands.py"
25+
- "src/agentnet/cli.py"
26+
- "src/agentnet/core/app.py"
27+
- "src/agentnet/operations/server_setup.py"
28+
- "src/agentnet/storage/postgres.py"
29+
- "skills/agentnet-operator/**"
30+
- "package.json"
31+
- "package-lock.json"
32+
- "pyproject.toml"
33+
- "uv.lock"
34+
workflow_dispatch:
35+
36+
permissions:
37+
contents: read
38+
39+
jobs:
40+
ubuntu-24-postgresql-18:
41+
name: Ubuntu 24.04 / PostgreSQL 18 clean install
42+
runs-on: ubuntu-24.04
43+
timeout-minutes: 45
44+
45+
steps:
46+
- name: Check out source
47+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
48+
with:
49+
persist-credentials: false
50+
51+
- name: Configure Node.js
52+
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
53+
with:
54+
node-version: "24.18.0"
55+
package-manager-cache: false
56+
57+
- name: Configure uv and Python
58+
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
59+
with:
60+
version: "0.11.28"
61+
python-version: "3.13.13"
62+
enable-cache: false
63+
64+
- name: Install PostgreSQL 18 and local route dependencies
65+
shell: bash
66+
run: |
67+
sudo apt-get update
68+
sudo apt-get install -y postgresql-common nginx jq openssl ca-certificates
69+
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
70+
sudo apt-get update
71+
sudo apt-get install -y postgresql-18
72+
sudo systemctl start postgresql
73+
sudo -u postgres psql -Atq --dbname=postgres -c "SHOW server_version" | grep -E '^18\.'
74+
75+
- name: Run clean installed-artifact setup lifecycle
76+
shell: bash
77+
run: scripts/ci/ordinary-server-setup-e2e.sh
78+
79+
- name: Verify E2E cleanup
80+
if: ${{ always() }}
81+
shell: bash
82+
run: |
83+
set -euo pipefail
84+
! getent passwd agentnet >/dev/null
85+
! getent passwd agentnet-approval >/dev/null
86+
! getent group agentnet >/dev/null
87+
! getent group agentnet-approval >/dev/null
88+
for path in \
89+
/opt/agentnet-e2e \
90+
/var/lib/agentnet \
91+
/var/lib/agentnet-approval \
92+
/var/lib/agentnet-setup \
93+
/etc/agentnet-secrets \
94+
/etc/systemd/system/agentnet-core.service \
95+
/etc/systemd/system/agentnet-approval.service \
96+
/etc/nginx/sites-enabled/agentnet-e2e \
97+
/etc/nginx/sites-available/agentnet-e2e \
98+
/usr/local/share/ca-certificates/agentnet-e2e.crt \
99+
/etc/ssl/certs/agentnet-e2e.crt \
100+
/etc/ssl/certs/agentnet-e2e.pem \
101+
/etc/ssl/private/agentnet-e2e.key \
102+
"$RUNNER_TEMP/agentnet-ordinary-server-e2e"; do
103+
! sudo test -e "$path"
104+
done
105+
! grep -Fq '# agentnet-e2e' /etc/hosts
106+
HBA_FILE="$(sudo -u postgres psql -Atq --dbname=postgres -c 'SHOW hba_file')"
107+
! sudo grep -Fq '# agentnet-e2e' "$HBA_FILE"
108+
[[ "$(sudo -u postgres psql -Atq --dbname=postgres -c "SELECT count(*) FROM pg_roles WHERE rolname='agentnet'")" == "0" ]]
109+
[[ "$(sudo -u postgres psql -Atq --dbname=postgres -c "SELECT count(*) FROM pg_database WHERE datname='agentnet'")" == "0" ]]

‎PUBLIC_RELEASE_STATUS.md‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,33 @@
33
Snapshot: 2026-07-24
44

55
This additive status note reconciles public package availability with AgentNet's
6-
frozen `0.1.24` release evidence. It does not replace requirements, gate
6+
frozen `0.1.25` release evidence. It does not replace requirements, gate
77
ledgers, or accountable-owner evidence.
88

99
## Current public package
1010

1111
A read of the public npm registry on 2026-07-24 returned:
1212

1313
- package: `@misunders2d/agentnet`
14-
- latest published version: `0.1.24`
15-
- published package `gitHead`: `9a948d59f81518b5ac6f46c6862004e3c3d62645`
14+
- latest published version: `0.1.25`
15+
- published package `gitHead`: `eed319a76e4fbd0495f4d1bc1862f4c5891444ff`
1616

1717
Package availability does not authorize deployment and does not establish
1818
production readiness.
1919

2020
## Frozen release-input clarification
2121

22-
The retained `0.1.24` wheel and sdist under
23-
`evidence/local/2026-07-23-v0.1.24/artifacts/` are immutable release evidence.
22+
The retained `0.1.25` wheel and sdist under
23+
`evidence/local/2026-07-24-v0.1.25/artifacts/` are immutable release evidence.
2424
Their packaged release inputs include older pre-publication wording such as
25-
"latest published package: 0.1.22" and "prepared 0.1.24". Those frozen bytes are
25+
"latest published package: 0.1.24" and "prepared 0.1.25". Those frozen bytes are
2626
not rewritten after publication. `scripts/verify_release.py` intentionally
2727
checks them against their release snapshot.
2828

2929
Correcting that wording inside packaged release inputs requires a new version
3030
candidate, fresh artifacts, normal release verification, and separate
3131
publication by Sergey. This note records the post-publication registry fact
32-
without creating a second artifact under version `0.1.24`.
32+
without creating a second artifact under version `0.1.25`.
3333

3434
## Release and gate posture
3535

‎README.md‎

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,13 @@ identity or authority source. You can also load it explicitly with
198198

199199
### Product-owned ordinary Linux server setup
200200

201-
After verifying system-wide root-owned AgentNet, Node.js, and `uv` executables, then
202-
resolving approved PostgreSQL, OIDC, scanner trust, secret-file, and distinct
203-
public HTTPS-route inputs, plan without writes:
201+
Follow the bundled canonical checklist in
202+
[`skills/agentnet-operator/references/ordinary-server-setup.md`](skills/agentnet-operator/references/ordinary-server-setup.md).
203+
First verify system-wide root-owned AgentNet, Node.js, and `uv` executables whose
204+
resolved paths are outside `/root`, `/home`, and `/run/user`. Prepare exact
205+
owner-only OIDC/scanner/environment inputs and the fixed local PostgreSQL peer
206+
contract (`agentnet` OS user → `agentnet` role/database through
207+
`/var/run/postgresql`). Then plan without privileged or managed-host writes (the npm launcher may materialize its caller-owned Python runtime):
204208

205209
```bash
206210
<resolved-root-owned-agentnet-path> server-agent setup --request /home/operator/.config/agentnet-setup/server-setup.json
@@ -215,15 +219,26 @@ sudo -- <resolved-root-owned-agentnet-path> server-agent setup \
215219
--apply --start
216220
```
217221

218-
This fixed wrapper creates only AgentNet's two locked identities, private roots,
219-
Approval/Core state, scanner trust, and two hardened systemd units. It starts
220-
loopback Core and Approval, verifies operator-owned public HTTPS routes, emits
221-
redacted resumable evidence, and rejects conflicting state without overwrite.
222-
It never mutates DNS, TLS certificates, proxy or firewall policy, PostgreSQL
223-
administration, identity, or authority. A remote Manager does not shell into
224-
the target. Human OIDC/WebAuthn and offline activation remain explicit steps in
225-
the bundled skill. Final setup status is `operational` with identity enrolled
226-
and authority still false.
222+
Plan and apply bind exact Node/uv/launcher/`systemctl`/`useradd` paths and
223+
content hashes plus the canonical full AgentNet package-tree content hash to
224+
approval digest v2. Apply
225+
repeats preflight under an exclusive lock, may create the fixed Core OS identity
226+
plus root-owned setup runtime/lock, and then blocks before AgentNet
227+
environments/config/database writes
228+
unless a read-only canary succeeds as that identity and parsed PostgreSQL
229+
HBA/ident views plus config-load freshness prove the exact loaded unshadowed
230+
`local agentnet agentnet peer` rule. PostgreSQL
231+
role/database/HBA edits and reload remain a separate operator-owned approval;
232+
rerun the same AgentNet digest afterward.
233+
234+
The wrapper then owns only AgentNet's two locked identities, private roots,
235+
Approval/Core state, scanner trust, two hardened systemd units, bounded start,
236+
and exact loopback/public health. Retry reloads realized state and commits
237+
marker v2 only through same-request compare-and-swap; manual marker/unit surgery
238+
is unsupported. It never mutates DNS, TLS, proxy/firewall policy, PostgreSQL
239+
administration, identity, or authority. Human OIDC/WebAuthn and offline
240+
activation remain explicit. Final setup status is `operational` with identity
241+
enrolled and authority still false.
227242

228243
For a real network, AgentNet's install-and-use contract is the exact capability
229244
set in [`docs/requirements.md`](docs/requirements.md)—no reduced messaging
@@ -291,7 +306,8 @@ always-on deployment—see the [implementation guide](docs/implementation-guide.
291306
## Project status
292307

293308
AgentNet is an early public implementation; latest published package is
294-
`0.1.24`. That release contains the product-owned ordinary Linux server setup:
309+
`0.1.25`. The current unpublished `0.1.26` candidate corrects ordinary Linux
310+
server setup convergence. The earlier `0.1.24` release introduced product-owned ordinary Linux server setup:
295311
fixed plan/apply/start convergence, Approval/Core separation, scanner trust,
296312
exact public HTTPS health identity, interruption recovery, redacted evidence,
297313
and bundled operator workflow. Setup grants neither identity nor authority.
@@ -302,7 +318,7 @@ runner where that path did not exist. No `0.1.23` package was staged or
302318
published. Published `0.1.24` changed only that fixture to mock AgentNet's
303319
validated host-tool resolver directly; runtime behavior was unchanged.
304320

305-
Prepared `0.1.25` repairs two JSON-RPC interoperability defects exposed by the
321+
Published `0.1.25` repairs two JSON-RPC interoperability defects exposed by the
306322
pinned official A2A TCK: `/rpc` and `/rpc/` now use the same strict endpoint
307323
without POST redirects, and a blank SDK request tenant is restored only from an
308324
exact verified opaque route binding. Missing/spoofed bindings and tenant
@@ -313,10 +329,16 @@ release-manifest self-check reports `1386 passed, 15 expected host/PostgreSQL
313329
skips`. The focused official JSON-RPC lane reports `3 passed`, while the full
314330
MUST run remains non-green at `50 passed, 11 failed, 174 skipped`; G04 therefore
315331
remains `FAILED`. Exact prepublication, retained-artifact, recursive packed, and
316-
Pi-loader checks are recorded in the candidate evidence after they pass.
317-
Privileged clean-host apply, cross-SDK/public-peer evidence, live
318-
PostgreSQL/OIDC/WebAuthn/TLS ceremony, Sergey-only publication, and independent
319-
public-artifact deployment remain pending or separately gated. Repository
332+
Pi-loader checks are recorded in its immutable evidence.
333+
334+
Unpublished `0.1.26` repairs runtime-bound setup approval, semantic broker
335+
preflight, exact PostgreSQL service-identity peer validation, safe same-digest
336+
resume, marker provenance/CAS, Windows CLI imports, and installer guidance.
337+
Local source/package evidence is recorded as working-candidate evidence only;
338+
clean Ubuntu 24.04/PostgreSQL 18 CI, cross-platform CI, retained-artifact refresh,
339+
Sergey-only publication, and independent public-artifact deployment remain
340+
pending. Cross-SDK/public-peer evidence and live OIDC/WebAuthn ceremony remain
341+
separately gated. Repository
320342
evidence is not a completed live cross-host journey or production certification.
321343

322344
Production adoption still requires deployment-specific evidence such as a real

‎RELEASE_MANIFEST.json‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"snapshot_date": "2026-07-24",
55
"release": {
66
"name": "agentnet",
7-
"version": "0.1.25",
7+
"version": "0.1.26",
88
"profile": "self_hosted_local_conformance_candidate",
99
"status": "BLOCKED",
1010
"production_ready": false,
@@ -32,12 +32,12 @@
3232
},
3333
"dependency_lock": {
3434
"path": "uv.lock",
35-
"sha256": "2db5b45786e7d90c466c12731ad15dc7187cb69ca10373f419c1a49845363605",
35+
"sha256": "0435578badd41758f98601e69c8910b519c712110261f2997dccf58b6f374e11",
3636
"format_version": 1,
3737
"revision": 3,
3838
"pyproject": {
3939
"path": "pyproject.toml",
40-
"sha256": "160953aa554cffe7b146bd7e5043aedadb7cab6daf3c5749ab5a214d77ef1395"
40+
"sha256": "a9d2dde83596edafaeefa7bcfbfed7435d8ecc18380b4e5f5731d14949978470"
4141
},
4242
"direct_dependencies": {
4343
"build": {
@@ -193,11 +193,11 @@
193193
"release_inputs": {
194194
"README.md": {
195195
"path": "README.md",
196-
"sha256": "2b381da77b3f31f7efb8c657b64e885a81ee0b466bfc298993fb2f11308accd9"
196+
"sha256": "01f439a71f0af6b2734ae66f45480352fc2736db3dfc9dfc168e188485700f41"
197197
},
198198
"REQUIREMENTS_STATUS.md": {
199199
"path": "REQUIREMENTS_STATUS.md",
200-
"sha256": "f44432d291ab9b1a7ae097d87ae7d1eed33b66b1adb82dec06c86e5a58863e81"
200+
"sha256": "4f9efed2516aa024cf6ddd2c7e7c717f37468004169af01aa1ee353e7582f071"
201201
},
202202
"deploy/Dockerfile": {
203203
"path": "deploy/Dockerfile",
@@ -217,11 +217,11 @@
217217
},
218218
"docs/GATE_EVIDENCE.md": {
219219
"path": "docs/GATE_EVIDENCE.md",
220-
"sha256": "46eddac5af12dc11a9531137d8f2de672fcf421b69923b0cc5a19400a59f5d65"
220+
"sha256": "730f88401bea7d62c8e16918151a36017de3853c2187b94f18a197f4398df41d"
221221
},
222222
"docs/RELEASE_MANIFEST.md": {
223223
"path": "docs/RELEASE_MANIFEST.md",
224-
"sha256": "29e248de07d4766e8d84ed7240e362bf0f5441a12b75ca4ef13eaef842849c4c"
224+
"sha256": "2578fc86f46b32779af0d485b14000ca0c9a29eae886697aef89401c7e25087b"
225225
},
226226
"evidence/gates/G01/2026-07-13-installed-harnesses/manifest.json": {
227227
"path": "evidence/gates/G01/2026-07-13-installed-harnesses/manifest.json",
@@ -245,13 +245,13 @@
245245
},
246246
"scripts/verify_release.py": {
247247
"path": "scripts/verify_release.py",
248-
"sha256": "0a1c73440646d12d1956fe3fc95abb03e6796a1a61b878fadfc22a0682b89862"
248+
"sha256": "7e7674575c7fc0bf20a9af9483b5ed2a289e415bc34019a3e0fb4de391a3e855"
249249
}
250250
},
251251
"release_source_tree": {
252252
"path": "src",
253253
"algorithm": "sha256(path NUL bytes NUL)",
254-
"sha256": "58351234cd75447ff974416d1cbd3e59b9854c28be36e6bd1d94dfeaafa61742"
254+
"sha256": "f871821eb22626249ee6e2b44aacd83383db487c778915cba977c8fd4f1b4417"
255255
},
256256
"protocols": {
257257
"a2a": {
@@ -410,7 +410,7 @@
410410
},
411411
"supervisor_harness_lifecycle": {
412412
"status": "BUILD_OWN_INTEGRATION",
413-
"pin": "agentnet-0.1.25",
413+
"pin": "agentnet-0.1.26",
414414
"boundary": "Exact human plus harness binding and foreground isolation remain owned."
415415
},
416416
"a2a_gateway": {

0 commit comments

Comments
 (0)