Files
felhom.eu/REPORT.md
T

62 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# felhom.eu — task reports
> **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md).
## Direction-2a agent-plane immediate-sync — poke sender + ep0 felhom-poke surface (hub v0.59.0) — 2026-07-16
**Baseline:** hub v0.58.0 → **v0.59.0** (LIVE on prod, ArgoCD Synced/Healthy). Pairs with felhom-agent
v0.89.0 (the poke listener). Green gate `go build ./... && go vet ./... && go test ./...` passes.
Design contract: `documentation/audits/SPIKE-immediate-sync-transport-2026-07-16.md` option (a).
### What shipped
- **`internal/poke`** — the SSH poke SENDER (third sibling of `internal/wgsync`/`internal/tenantsync`):
a pinned-host-key (algorithm-pinned `ssh.FixedHostKey`) in-process client reusing the peersync
endpoint + host key, its OWN forced-command key. `Client.Poke(ctx, boxWGIP)` refuses any target
outside `10.77.0.0/24` BEFORE dialing, then SSHes to ep0's `felhom-poke` with the box WG /32 as the
command string (→ `$SSH_ORIGINAL_COMMAND`) which sends one empty UDP datagram to `<ip>:51822`.
`Notifier.PokeHost`/`PokeAllHosts` are fire-and-forget (detached goroutine, nil-receiver-safe) — a
poke never blocks or fails the operator save; a missing peer / SSH error is logged, the report cycle
reconciles. Tests: resolved-IP send, no-peer / store-error no-send, nil no-op, `Poke` pre-dial
non-WG refusal.
- **Wiring:** `Server.SetPoke`; `applyPBSDR` fires `PokeHost(host.HostID)` after each generation-bumping
descriptor save; `handleSetArtifacts` (MinAgent-floor save) fires `PokeAllHosts()`. `cmd/hub/main.go`
env-configures the sender (`POKE_SSH_KEY_FILE`, reusing `WG_ENDPOINT_SSH_ADDR`/`_HOSTKEY`/user).
- **ep0 surface:** `scripts/felhom-poke.sh` v1.0.0 — a NON-root (`felhom-peersync`, no sudoers grant)
forced command that validates `$SSH_ORIGINAL_COMMAND` to the WG /24 and sends one empty datagram
from wg0. Contentless + confined (the WG kernel refuses non-peer /32s — spike P1 EKEYREJECTED).
Runbook `documentation/runbooks/offsite-endpoint.md` §11. Port **51822** = shared cross-repo constant.
- **`manifests/hub.yaml`:** `POKE_SSH_KEY_FILE` env + optional `Secret/agent-poke` mounted 0400; image
tag `0.58.0``0.59.0`.
### Landmarks as found at source
- **Poke wiring is host-keyed** (`store.GetWGPeerForHost` → the box WG /32), the sibling of the
customer-keyed `internal/intent` long-poll (Direction-2b / controller plane). `SetHostDesired` bumps
the poked host's generation; the poked immediate report carries the advanced envelope generation →
the agent fetches the new descriptor.
- **Spec-vs-source note (source wins):** the MinAgent-floor / artifact-manifest save
(`handleSetArtifacts`) does NOT itself bump per-host desired generation — the agent self-update
dispatches via signed-ops on the next report — so `PokeAllHosts()` there accelerates the next report
cycle where the floor is applied, rather than delivering a desired-state delta. Kept the poke there
(the spec names this handler) and documented the semantics.
### Live validation
- **Deployed:** hub 0.59.0 built + pushed on 180, manifest tag bumped + ArgoCD synced (Synced/Healthy,
rollout complete, image `:0.59.0`); after the Secret was created it logs `agent-plane poke enabled`.
- **ep0 poke surface installed live** (additive; `felhom-peersync` authorized_keys 2→3 lines,
peersync/tenantsync UNCHANGED; `/usr/local/bin/felhom-poke` 0755; `Secret/agent-poke` holds the
private key, the build-server copy shredded).
- **ep0 leg live-validated with the poke key:** a valid WG target (`10.77.0.2`) → `poke-fired`;
`8.8.8.8` AND `rm -rf /` as the SSH command → `refused non-WG target` (the forced command NEVER
executes client input, only reads it as an IP candidate). This proves the full hub→ep0→box datagram
path and the credential-theft blast radius (≤ "make a registered box tick").
- **Fired end-to-end from a REAL operator save (2026-07-17):** the operator's Day-0 manifest save
(`Artifact manifest set: agent=0.89.0 … min_agent=0.89.0`) immediately logged `poke: sync-poke
delivered to 10.77.0.2 via 167.233.158.164:22` + `fleet nudge sent to 1/2 WG peers` — the
`handleSetArtifacts``PokeAllHosts()` wiring proven live to the box (the 2nd peer is offline). The
MinAgent-floor coupling also fired: `managed floor HELD for demo-felhom: agent 0.88.0 < MinAgent 0.89.0`.
- **Scenario 3 box-side latency measured** once the demo reached v0.89.0: a poke ep0→box delivered in
**~31 ms** and fired the immediate desired-state cycle (see the felhom-agent REPORT). Full save→tick
≈ ~0.45 s (SSH-dominated), well under the ≤23 s target. All three live legs (Scenario 4 A/B train,
Scenario 1 R-22 self-heal, Scenario 3 latency) are proven-live; the capability-map poke + F4 rows are
upgraded to PROVEN-LIVE.