Commit Graph
192 Commits
Author SHA1 Message Date
Hermes Agent 0704676741 [pending-judge] feat(deploys): catalog deploy via shipdeck bridge (DC-CATALOG-3)
GET /deploys/catalog/apps -> bridge /api/catalog/apps (73 embedded apps,
single source of truth). POST /deploys/catalog/deploy {app,port,env} ->
validated (service-id charset, port 1024-65535, env name/value rules) then
proxied to bridge /api/catalog/deploy which runs the shipdeck CLI catalog
deploy (OCI image -> hardened systemd service; NO Docker daemon). Audited
as deploy.catalog with ok/seconds. 11 table-driven route tests incl.
validation rejections never reaching the bridge + bridge-failure 502 shape.
App Selector submit rewired from /apps/deploy (Docker chain) to
/deploys/catalog/deploy — same modal, same fields (port, mediaPath, plex
claim token as env), no new UI screens. Full suite 3510/3510 (156 suites).
2026-10-07 02:08:32 -07:00
Hermes Agent 8744609887 [pending-judge] fix(integration): catalog detail reads app.docker.* (DC-160); Shield committed; composition-root e2e
- DC-160: /catalog/:appId read app.image/ports/env/volumes which live under
  app.docker.* — every detail response was empty. Now reads docker.* and
  surfaces defaultPort/subdomain/healthCheck/mediaMount/claimToken/difficulty/
  setupInstructions for the deploy form. List/search use the templates own
  category field (old hand-rolled CATEGORY_MAP mis-categorized apps).
- Shield (routes/shield.js + 5-line app.js mount) committed to source after
  weeks as prod-only drift; regression test asserts the mount exists.
- New composition-root e2e suite: boots REAL createApp() on an ephemeral
  port, probes the historically-broken routes through the REAL mount table
  (wizard wiring, shield, catalog detail, deploys bridge) — the class of bug
  all 3 P7 dogfood findings belonged to. 5 tests.
- Full suite 3499/3499 (155 suites); table-driven DC-160 test covers all 73
  image templates.
2026-10-07 00:58:03 -07:00
Hermes Agent c430e02117 [grade=B urn:ump:bbfbsfru4nizg75wcxum7mwzhie6txhr22hw6jvz36wiihmgzmlq] P7 people store: dedupe upsert by providerUserId
CI / Test & Lint (pull_request) Canceled after 0s
CI / Security audit (pull_request) Canceled after 0s
Dogfood finding #3: upsertPerson resolved existing records by id only.
The wizard upserts a bootstrap admin AFTER a provider sync has already
created a person for the same Tailscale user (no id passed), so the same
providerUserId was duplicated into two records. Resolve existing by
providerUserId when no id is given; bootstrap Admin group + protectedAt are
preserved on the merge. New regression test; full suite 3414/3414.
2026-10-04 03:12:23 -07:00
sami7777 e04787477a P7 Private Network [grade=A] (PR #1)
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
Judge A r18 urn:ump:rgxdivsp2xf6zy5lsdoclvdgb7cuqd3qpwlszt2p7fu7xwa3zkkq. 3,399/3,399 tests.
2026-10-04 11:04:23 +02:00
Hermes d4973f3af3 P7 r8 fix: forward_auth trust boundary (XFF/XFH honored only from trusted proxy; direct/spoofed requests use socket identity) + adversarial tests 2026-10-03 23:25:23 -07:00
Hermes 1e606bf0f3 P7 r3 fix: single-preview contract (syncAccess delegates drift-check+preview+push to pushIfNoDrift; acl_preview_failed mapped non-retryable) + test updates 2026-10-03 22:55:22 -07:00
Hermes d2d0d73477 P7 r2 fixes: drift guard wired through pushIfNoDrift (acl_drift_detected ProviderError, never overwrites drifted remote) + unknown-device forward_auth audit + drift regression tests 2026-10-03 22:47:27 -07:00
Hermes a5ef5b345e merge dc/DC-153 into p7-wave1 2026-10-03 22:34:32 -07:00
Hermes 44567031eb DC-153: provider.syncAccess enforcement wiring (tailscale ACL push + wireguard nftables apply) + contract tests 2026-10-03 22:34:02 -07:00
Hermes aac2343df3 DC-154: forward_auth enforcement endpoint (whois + access map + sensitive step-up) + tests 2026-10-03 22:30:23 -07:00
Hermes 5bcf4e99ee merge dc/DC-150 into p7-wave1 2026-10-03 22:05:39 -07:00
Hermes ae78e2e318 merge dc/DC-152 into p7-wave1 2026-10-03 21:49:08 -07:00
Hermes 178a2fbb9f merge dc/DC-147 into p7-wave1 2026-10-03 21:48:27 -07:00
Hermes 38af7ba224 DC-152: Private Network setup wizard (mode/domain/connect/dns/ca/admin steps) + status API + tests 2026-10-03 21:47:34 -07:00
Hermes c12bff597b merge dc/DC-146 into p7-wave1 2026-10-03 21:47:32 -07:00
Hermes d224a24566 DC-147: named root CA with critical name constraints, leaf compliance assertions, install-page hardening, encrypted backup + tests 2026-10-03 21:43:11 -07:00
Hermes b4e683a7fc DC-150: WG invite redemption page (browser X25519 keygen, client-side config+QR) + public redeem API + tests 2026-10-03 21:40:09 -07:00
Hermes 9215037553 DC-146: Technitium zone/record sync (idempotent upserts) + split-DNS gate + setup check + tests 2026-10-03 21:39:33 -07:00
Hermes de6a2fa4ae merge dc/DC-144 into p7-wave1 2026-10-03 21:38:34 -07:00
Hermes 3291f80d0c merge dc/DC-151 into p7-wave1 2026-10-03 21:37:39 -07:00
Hermes 695794987b DC-144: DashCaddy-side groups + resources model/routes with cascade delete + tests 2026-10-03 21:37:13 -07:00
Hermes 24ec88a30d DC-151: WG nftables matrix compiler + transactional apply/rollback + tests 2026-10-03 21:35:15 -07:00
Hermes f7c5ff1d0b merge dc/DC-142 into p7-wave1 2026-10-03 21:34:22 -07:00
Hermes 151b42e0ea merge dc/DC-149 into p7-wave1 2026-10-03 21:33:37 -07:00
Hermes b7d9e2b983 merge dc/DC-143 into p7-wave1 2026-10-03 21:32:45 -07:00
Hermes 88d34c6d7e DC-142: link-first invites routes via network provider + tests 2026-10-03 21:31:57 -07:00
Hermes fcfe5dff1b DC-149: WireGuard hub provider (peer store, pool allocator, hub lifecycle) + tests 2026-10-03 21:31:09 -07:00
Hermes 4e4306b00f DC-143: block/unblock/remove person + revoke device orchestration + tests 2026-10-03 21:29:41 -07:00
Hermes 486d0e8d11 DC-148: Tailscale ACL compiler + lockout guard + preview/push/rollback + drift detection + tests 2026-10-03 21:26:29 -07:00
Hermes a78d0ef857 Merge branch 'dc/DC-145' into dc/DC-142 2026-10-03 21:23:43 -07:00
Hermes b2c70a0323 Merge branch 'dc/DC-141' into dc/DC-142 2026-10-03 21:23:42 -07:00
Hermes c09fc7b1ef Merge branch 'dc/DC-145' into dc/DC-143 2026-10-03 21:23:14 -07:00
Hermes 5d786afcce Merge branch 'dc/DC-141' into dc/DC-143 2026-10-03 21:23:14 -07:00
Hermes 26f4aa8ad0 merge dc/DC-145 into p7-wave1 2026-10-03 21:20:41 -07:00
Hermes d3c1dfd996 merge dc/DC-141 into p7-wave1 2026-10-03 21:20:40 -07:00
Hermes b7df8f5fe0 Merge branch 'dc/DC-140' into dc/DC-148 2026-10-03 21:20:01 -07:00
Hermes 5e03f120b4 Merge branch 'dc/DC-141' into dc/DC-148 2026-10-03 21:20:00 -07:00
Hermes 7ef3914730 DC-140: network provider abstraction (src/network/) + tailscale provider + registry + tests 2026-10-03 21:16:20 -07:00
Hermes 4b560b9c40 DC-141: people store (atomic JSON) + /network/people routes + last-admin guard + tests 2026-10-03 21:14:20 -07:00
Hermes 09152dfde2 DC-145: access map store (grants, effective access, change events) + /network/access routes + tests 2026-10-03 21:12:35 -07:00
DashCaddy Polish Loop f9cbb13a3d [grade=B] DC-131/132/133 install from any Git host
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
Codex source gate: urn:ump:iw2tbbe6mssyl5divymmwo42ael65sbfrciztvyowo3zhrbtircq

Generated assets gate: urn:ump:hintflviuxfpeidth42ry5fi4lwqsjhkxipzspfmk7vrvfc2cnqq
2026-09-14 20:10:14 -07:00
DashCaddy Polish Loop 65a447e27e DC-130 rev3: log.error on unexpected bridge status in /status + test asserting the log call (13 tests green)
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
2026-09-14 04:19:55 -07:00
DashCaddy Polish Loop 121caef488 DC-130 rev2: fail-fast bridge bindings (host), /status gateway-error mapping (401/403/unreachable -> 502, probe-failure stays ok:false) + 3 new tests (13 total)
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
2026-09-14 04:11:30 -07:00
DashCaddy Polish Loop 1fc61c3fdb DC-130: shipdeck deploys panel — bridge-proxied source deploys (routes + tests, opt-in via SHIPDECK_BRIDGE_URL) 2026-09-14 03:33:31 -07:00
DashCaddy Polish Loop 70e252c8a5 [grade=A urn:ump:seyasvbntxsjibq5jiaqmfowc6xgchwe4jvcc54jd6355ujgm75q] DC-122: self-updater hardening + auto-update on + docker disk discipline (v1.16.0)
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
- _isNewer: same-version releases are never 'newer' (commit labels are
  opaque stamps) — kills the same-version auto-apply regression loop
- _autoCheckAndApply: identical version@sha256 never re-applied
- dashcaddy-update.sh: truthful rollback verdicts (failed rebuild/health
  = exit 1 + failure result), exact frontend snapshot/restore (incl.
  update-introduced owned subtrees), contents-copy cp fallbacks with
  manifest reconciliation, JSON-encoded results/meta/stamp, prune on
  every exit path
- self-updater: frontend-only Linux releases fail loudly (no more silent
  no-op success stuck in 'applying')
- start.sh: DASHCADDY_UPDATE_ENABLED=true (Sami 2026-09-13), json-file
  log caps 10M x3, source->webroot sync via update-stamp contract
- tests: _isNewer regression suite, functional cycle + json/escape suites
  (scripts/test-frontend-cycle.sh, scripts/test-json-escape.sh)

15 judge rounds: C,C,D,D,C,C,D,C,C,C,D,C,A
2026-09-13 05:32:14 -07:00
Hermes c28322eb46 [grade=B] api: fix undeclared 'format' runtime bug in routes/ca.js + 10 lint errors
- routes/ca.js: declare format before pfx/pem/crt dispatch (was ReferenceError
  on every request that passed validation); add CA_CERT_FORMATS single source
  of truth + hardened format extraction (string-coerce, whitelist)
- routes/caddycode.js: fix upstream-validation regexes (control-char classes)
- routes/logs.js: SSE/validation lint fixes
- routes/openclaw.js: remove useless regex escape in ALLOWED_PATH_RE
- fleet-validation.js + http-caddy-admin-origin test: eslint-disable for
  intentional control-regex security sentinels
- ca-dc076.routes.test.js: regression test for declared format + behavioral
  coverage of format validation (now pre-PKI)

Judge: Qwen lane (qwen3.8-max) grade B, 0 blocking, verdict
/tmp/judge-batch1-verdict.json. API suite 2859/2859 green.
2026-08-31 23:37:00 -07:00
Hermes b6678cf591 DC-061: remove superseded status/pricing/index.html and obsolete pricing-page-catalog test
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
2026-08-23 20:24:42 -07:00
Hermes 46b6952c36 [glm-grade=A] fix(security): DC-120 surface caddy-source perimeter events in Log Insights dashboard — new GET /api/v1/security/events/perimeter endpoint with per-IP/per-vhost aggregations, event-store compileFilter/filterEvents primitives, and Perimeter section in Log Insights modal with XSS-safe rendering and stale-request guards
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
2026-08-23 17:26:07 -07:00
Hermes 1744d1c86e fix(security): caddy-event self-noise conjunction filter for host curl probes (DC-118) [glm-grade=A]
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
The host-side uptime watchdog and on-host cron jobs curl Caddy with a stock
curl/8.5.0 UA from loopback and the host tailscale IP — ~300 GET /api/health
401 warn-events/day burying real perimeter signal (census: 339+20 of 5000
access.log lines). Dropping on UA alone would blind the store to external
curl scanners, so generic tool UAs (curl/) are now dropped ONLY when the
source remote_ip is one of this host's own addresses (DASHCADDY_SELF_IPS,
default loopback; start.sh derives 127.0.0.1 + tailscale ip -4, empty-safe).
remote_ip (TCP peer) is used, never the spoofable client_ip. DashCaddy-*
probe UAs stay unconditionally dropped. 9 regression pins cover the full
conjunction matrix incl. external-IP+curl KEPT and spoofed-XFF KEPT.
2858/2858 green (128 suites).

Judge: glm-4.6@zai-coding-paas cold-read round 1 = A clean (0 blocking),
both polish notes folded. URN urn:ump:s2sgitfepze65crtp57dpdw4gk4w7upsoi4tqcvfwahcsicyepba
2026-08-23 15:53:58 -07:00
Hermes 2dce6dca5e fix(security): event-store retention + race + total-cap defects (DC-116) [glm-grade=B]
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s
- query().total: full-scan true count (was capped at offset+limit by an
  early break — dashboard 24h stat read ≤1000 vs real ~46k)
- trim trigger/curer mismatch: byte trigger + line curer never converged
  when avg line > ~524B (live avg 355B); now keeps maxDisk lines OR
  ≤80% byte budget, whichever retains fewer (TRIM_TARGET_FACTOR);
  budget env-overridable via SECURITY_EVENT_TRIM_BYTES / opts.trimSizeLimit
- trim/append race: trim renamed over the file mid-append losing events
  to the unlinked inode; now single-flight, queue-empty gated, holds the
  write lock, error paths always release + lazily re-kick (no hot loop)

Judge: glm-4.6@zai-coding-paas adversarial cold-read, grade B clean
(0 blocking, 4 polish — 2 folded, 1 already-satisfied, 1 deferred as
judge-endorsed safer). 127 suites / 2849 tests green.
2026-08-23 15:02:00 -07:00