Commit Graph

1170 Commits

Author SHA1 Message Date
vh 7a33bd9f09 memory: breeze stays put; TTS-stack move to fv-ml1 parked at id 75
Operator ruling: leave breeze-tts on irv-ml1 and park moving it, bragi and
tts-gateway to fv-ml1 until the embedder, reranker and reward seats are evacuated.

Parked as move-the-tts-stack-breeze-tts-bragi-tts-gateway (id 75) with the trigger,
the footprints and the migration gotchas, so it resurfaces with everything needed
rather than as a bare line.

Two things worth having recorded against the trigger. All three services move as a
set because only breeze is GPU-resident at ~10.3 GiB and growing, while bragi and
tts-gateway are CPU-only proxies - co-location with the gateway is the entire reason
not to move breeze alone, since that is what puts a cross-site hop on every TTS call.

And the trigger as stated names gpu0, but vllm-embed, vllm-rerank-a3 and vllm-reward
are all pinned to GPU 1. GPU 1 is the constrained card at 0.975 committed with
4,336 MiB free, while GPU 0 has 11,982 MiB free and carries the live chat path, so
evacuating those three relieves GPU 1 rather than GPU 0. Recorded as a
confirm-before-executing rather than silently corrected, since it changes where the
TTS stack would land.

Also notes that bragi and tts-gateway reach each other by name only through
extra_hosts pins, because containers on irv-ml1 cannot resolve nh3.internal - those
pins travel with them and need re-pointing at the new host.
2026-09-15 09:31:12 -07:00
vh b0e7b408d9 memory: breeze-tts sizing and the fv-ml1 GPU 0 placement recommendation
The operator asked this mid-sweep and the answer never reached durable memory -
caught only because he asked again after the snapshot. Recommendation is not to
move it.

Re-measured rather than reciting the earlier figure, which was right when taken and
is now wrong: breeze holds 10,316 MiB after 53 minutes of uptime against 9,218 MiB
shortly after warm-up. The footprint grows with use, consistent with PyTorch's
caching allocator not returning memory - probably caching rather than a leak, but
resident either way and counting against any neighbour. Two points is a trend, not
a curve; whether it plateaus is unmeasured and stated as such.

That changes the placement answer. fv-ml1 GPU 0 has 11,982 MiB free, so the margin
is 1.7 GB and shrinking rather than the 2.8 GB the earlier number implied, on the
card carrying the live chat serving path.

The stronger objection is topology rather than VRAM: tts-gateway runs on irv-ml1
and reaches breeze on the same box, so moving breeze alone puts a cross-site hop on
every TTS call against a 478 ms to-first-sample budget. Moving it properly means
moving the gateway too. It is also not constrained where it sits - the 3090 still
has 10 GB free.

Also records the trap that nearly produced a wrong number: breeze reports nothing
at idle when queried on the wrong GPU, because BREEZE_GPU_DEVICES=0 is the 3090
rather than the A6000. An idle query of the A6000 shows it absent entirely.
2026-09-15 09:27:59 -07:00
vh 653f7fb939 memory: snapshot — Parakeet STT, svos_miranda live, talk v10, address sweep, secrets fix
Closes both of the previous session's named jobs and six unplanned pieces of work.
Nothing is in flight and nothing is blocked.

Parakeet STT live on fv-ml1 GPU 0 behind LiteLLM ext-stt and whisper-1; GPU 3 is now
a documented reserve after the operator caught an 800 MiB seat parked on the one
pristine 96 GB card. svos_miranda enabled and Miranda serving, with
agent.disabled_toolsets deleted and staying out by operator ruling. talk v10
deployed as the STT seat's first consumer. The irv-ml1 dead-address sweep is
complete at 0 of 112 Homepage cards, having turned up four live breakages on other
hosts. The secrets-broker concurrency bug is fixed, and ~/.local/bin/secret is a
symlink rather than a stale copy.

Auto-archival fired at 433 lines but moved only one entry: three of the four
candidates old enough to qualify carry open deferred-work pointers - a park id, an
althing thread, and an explicit 'untracked by operator choice' - and the guard held
them. The index stays over cap at 389 lines, which is the correct trade: nearly
every entry is genuinely under fourteen days old.

The generated handoff needed correcting in-session before it shipped. The model had
turned three operator-deferred items into a to-do list and invited the next session
to commit files that predate this one. Both would have read as instructions to a
fresh context, which is the durable-false-warning failure this session spent the day
documenting.
2026-09-15 09:26:26 -07:00
vh f4320ff57e docs(memory): the talk-deploy permission problem never existed
Vuong asked me to find and fix the harness issue blocking tts-dev from deploying
talk. There was no harness issue, and no issue of any kind.

/opt/docker/compose on nh3-dev is root:docker 2775, agent sessions run as lkraven,
and lkraven is in the docker group. A mkdir settles it in one second and nobody ran
one for nine days. There is also no tts-dev OS account, so the group request had no
referent.

It held together because a stale persistent-memory row supplied a plausible
mechanism and the operator's routing instruction - 'give it to infra' - was read as
corroboration of a capability limit. Those are different claims and only one was
ever stated: a routing preference explains where work went, never whether it could
have gone elsewhere. A contradicting ls -la was on screen in the same session and
was dropped. I then repeated the claim to the operator as fact in a deploy report,
which put a second name behind it.

Then I did the same thing one layer up. Finding no OS problem and no deny rule, I
inferred an auto-mode classifier refusal because the shape fit, and committed a
settings.json into tts-dev's repo on that inference. Their mkdir showed the path
writes with no refusal at all, so the hypothesis was wrong and the commit is
reverted. I had spent the night writing up this failure class and still built a fix
for a layer nobody had shown me failing.

That commit also claimed a doc correction it did not contain: the edit and the
commit were chained in one invocation, the edit's anchor assertion failed because
the target text had already been fixed, and the commit ran regardless. Amended
before reverting. Never chain an edit and its commit in one invocation.

The rule worth keeping is that 'I can't do X' from any source is a hypothesis until
someone runs the command and pastes the error, and that 'there is no error text,
because there was no error' is a possible answer.
2026-09-15 09:23:57 -07:00
vh af8d6df387 docs(memory): name the fleet's characteristic failure mode
svos-dev observed that three instances of the same shape turned up between two
agents in one night and that it is starting to look like a characteristic failure
rather than a coincidence. Collecting all nine from today, because the class is more
useful than any instance.

The shape is a check that reads the input to a transformation and gets reported as
if it read the output - or more generally, the instrument answering instead of the
system, in a form shaped exactly like a real answer. What makes it expensive is not
that things break but that the broken state is indistinguishable from a legitimate
one, so it passes review and is found later by accident. Every one of the nine
passed a check.

The tell is stated so it can be recognised prospectively: whenever 'broken' and
'legitimately empty, absent or off' produce the same output, the cheap check cannot
tell them apart by construction.

Remedies that actually worked today: measure the output rather than the input;
positive controls, since a method that has only ever passed cannot tell you it is
not blind; true-negative controls, because two apparent failures in the
secrets-broker test were names I had invented and would have been read as a partial
fix; refuse to emit the ambiguous value, which was the real fix rather than the
lock; and do not declare victory on a plausible fix, which is the only reason the
session-establishment root cause was found at all.
2026-09-15 08:53:06 -07:00
vh 0193b31aad fix(secrets-broker): bw is not concurrency-safe — serialise, and never return an empty secret with exit 0
Reported by svos-dev after parallelising four vault reads in SVOS's systemd
wrapper. Reproduced here and it is worse than reported: four concurrent secret get
calls for distinct items returned empty strings with exit code 0, zero of four
succeeding against their one of four. No error, no timeout, no diagnostic.

The shape is the problem, not the race. A caller treating an empty optional secret
as 'not configured' degrades silently and never learns otherwise - it cost SVOS the
ability to page the operator while the process logged a clean startup line.

Root cause is session establishment, not item reads. Every invocation runs bw
unlock, and concurrent unlocks against the shared appdata dir invalidate each
other. The damage then surfaces downstream as an empty listing or an empty item
body, which is why a per-call lock is useless: by the time the read runs the
session it holds is already dead. So the lock wraps the whole command instead.

Three changes. The command-level lock makes concurrent callers queue. cmd_get now
refuses an empty value rather than printing it, since a stored secret is never
legitimately zero-length. And find() no longer coerces empty stdout to '[]' - that
turned a broken read into a confident 'no such secret', the same silent-wrong-answer
shape one layer up.

Verified: four parallel reads of four real items now return all four correctly,
serialised at the honest ~17s each. A name that genuinely does not exist still
fails loudly, so the guard did not simply mute the negative case.

Also replaces the copy at ~/.local/bin/secret with a symlink to this file. It was a
plain copy in sync by luck, and every edit here silently left the live tool behind.
2026-09-15 08:49:11 -07:00
vh 66c860d6c1 fix(sweep): retire the dead 10.100.79.3 address across the fleet
Operator-directed. The wg0 lifeline retired at the 2026-09-06 headscale cutover is
on no interface anywhere, so anything pointing at it gets no route at all. Homepage
went from 9 dead cards to 0 of 112.

The load-bearing part is that there is no single right target: it depends on who
resolves it. The operator's browser and the Homepage and open-webui containers on
esh-docker-vm all resolve nh3.internal, so those get the name and survive the next
renumber. Containers on irv-ml1 and ana-docker cannot resolve it at all, so those
get the IP.

litellm on ana-docker looked like a counterexample and is not: it resolves the name
only through its own extra_hosts entry, while asset-engine on the same host fails on
it. Test from the container you are about to change, never from a neighbour. Before
committing to the name I confirmed the Homepage container actually fetches ytvc's
healthz through it in production rather than assuming resolution implies reach.

On irv-ml1, 24 files swept and 14 comment-only hits left as port-allocation history.
Seven running containers recreated so the labels took. Seven dormant ones carried
stale labels because editing a compose file does not touch an existing container
object - fixed with compose create --force-recreate, which rebuilds the container
without starting it, the right tool for a deliberately dormant stack.

The sweep's real find was off irv-ml1 entirely: four live values on two other hosts,
silently dead for nine days and alerting nobody. Open WebUI's read-aloud TTS,
asset-engine's inference host, and two skaldsong TTS URLs. Both running services were
recreated and verified reaching their targets afterwards rather than merely carrying
the new string.

One self-inflicted outage worth recording: I recreated breeze-tts for a cosmetic
label change and took ext-tts down for its ~90s CUDA-graph warm-up, returning 500. I
caught it only because I had taken a baseline before touching it. A label-only edit
still costs a full model reload on a GPU container.
2026-09-15 08:41:44 -07:00
vh 8bc46e5132 docs(memory): record the gap tts-dev found in my served-page gate
They adopted the gate as tts-stack tools/gate_served_page.py and extended it in a
place that matters: my version would have passed a broken page.

A worklet lives inside a template literal, so a syntax error in it is invisible to
a parse of the enclosing script - it is just a string until addModule compiles it
at runtime, where it fails as a rejected promise and the page quietly falls back to
buffered playback or records nothing. Silent degradation, which is harder to notice
than a dead page rather than easier. They parse the worklet separately, and they
positive-controlled the whole thing against two deliberately broken pages rather
than assuming a gate that has only ever passed is not blind. The second control -
valid enclosing script, broken worklet - is the one my version fails.

The lesson on my own work is the useful part: I built a gate for the failure I had
just been shown and stopped at its boundary. The class is 'code that is a string at
parse time and code at run time'; an inline script is one instance and a
template-literal worklet is another. I checked the instance, not the class.

Also promotes the underlying rule to the index, since it was named twice tonight
from two unrelated directions: a check that reads an artifact as stored cannot see
a transformation that happens between storage and execution.
2026-09-15 08:29:25 -07:00
vh e113660b08 docs(memory): talk v10 deployed with a served-artifact gate
Operator-instructed via tts-dev. First consumer of the ext-stt seat stood up the
same night - talk can now listen as well as speak. Relayed authorization was fine
to act on because the work is reversible: one-line tag rollback, v1..v9 retained,
compose and .env backed up. Checked the escape hatch existed rather than believing
the message that described it.

Gated properly: build, throwaway on a non-live port, four acceptance checks, tear
down, then cut over in a separate invocation. Re-ran all four against production
afterwards, because a gate that only ever ran against the throwaway proves the
image rather than the deployment, and confirmed the two new env vars inside the
running container rather than in the file.

Added a fifth gate worth keeping. tts-dev's worst bug this cycle was a JS escape
inside a Python string arriving transformed, closing the string and killing the
entire inline script while the page still rendered and both import and node --check
passed - because the file still held the backslash. So: fetch the page over HTTP,
extract the inline script from the response body, and node --check that. Same
instrument pointed at the other side of the transformation, and over the wire it
also catches anything that mangles the body after TLS and ASGI.

That is the second instance tonight of one rule: a check that reads the artifact as
stored cannot see a transformation between storage and execution. provider=cuda in
a log is the same error - an echo of configured intent read as a measurement of
running reality.

Also notes an open question for the operator: talk deploys route through infra-ops
only because tts-dev's identity is not in nh3-dev's docker group. The durable fix is
a group membership, not a standing relay.
2026-09-15 08:27:00 -07:00
vh 01f0014489 docs(memory): SVOS/Miranda fully live; bank two restart patterns from svos-dev
svos-dev restarted :8770 at 02:17 and both roster lines printed clean. Confirmed
from this side rather than taken on their word: :8770 answers 200 on the new pid,
an unauthenticated Bifrost dispatch gets 401, and Hermes reports 29 toolsets with
svos_miranda the sole enabled=True row.

Two patterns from their restart that generalise past this service.

A dry-run boot against the still-held port: start the new process while the old
one still owns the socket, and it proves every check above the bind before dying
on EADDRINUSE. Zero downtime, no commitment, and it turns a one-way restart into a
rehearsed one. Worth doing for any service whose startup validates before binding.

And a trap: SIGTERM released the port but left the process alive for 35 seconds,
needing SIGKILL. The port was free that entire time, so a script waiting on port
availability would have started the replacement alongside a still-running old
process. Kill by PID and wait on the PID, never on the port - a freed port is not
evidence of a dead process, the same way an unreachable post office is an outage
rather than an empty inbox.
2026-09-15 02:20:10 -07:00
vh 406769e64b docs(memory): bank the Parakeet bench result and tts-dev's storage-vs-execution lesson
The IRV seat was retired on tts-dev's numbers: it lost to the FV seat at both
clip lengths and to whisper-large-v3 at 6.24s. Their length sweep fits ~58ms
fixed + 56ms per audio-second with an asymptote of ~17.8x realtime, which
independently reproduces our 17x on a different clip and harness, and the gateway
hop measured below their harness resolution so ext-stt is the right consumer path.

Two caveats recorded against our own numbers: their between-run variance is 20%
because GPU 0 carries the live chat path, and our 0.50s median came off an idle
GPU 3 - a best case, not a comparable.

Their RTFx retraction is the durable part: published RTFx is batched throughput on
datacenter hardware rather than single-stream latency, and the two differ by ~200x.

Also banks the shape their acceptance gate caught, because it generalises past
their repo. A JS escape inside a Python string arrives transformed, closing the
string and killing the whole inline script, while the page still renders and both
import and node --check pass - the file still holds the backslash. That is the
same failure as reading provider=cuda out of a log: a check that reads the
artifact as stored cannot see a transformation that happens between storage and
execution. Both check the input to a transformation and get reported as if they
checked its output.
2026-09-15 02:17:57 -07:00
vh 868b56642c docs(memory): svos-dev fixed the roster check; disabled_toolsets deleted from config
svos-dev landed c9d2a96 - build_miranda_roster now returns an empty disabled list
unconditionally and the startup line no longer names the key. The 28-name list is
removed from ~/.hermes/config.yaml rather than left commented, since a paste-ready
array behind a hash is what a future session uncomments; a short warning stands in
its place.

Their mechanism is better than mine and replaces it in the record.
_get_platform_tools resolves platform_toolsets first and applies global suppression
last, so subtracting 28 names from a one-element platform set is a no-op by
resolution order - not merely 'adds no safety on top'. That holds for any future
platform; the measurement only established the single case.

And the endpoint already carried the answer. _handle_toolsets computes each row's
enabled as membership in the per-platform set, so verified live: 29 rows with
svos_miranda the only one reporting enabled=True. A check reading that field rather
than counting rows was correct all along, against a config that never needed the key.
2026-09-15 02:14:09 -07:00
vh 379fc27e7d feat(hermes): enable svos_miranda live; retire irv parakeet and voice-studio
Four operator rulings executed.

svos_miranda is live in Hermes. Gateway restarted 02:10 (PID 3107822 -> 3901622,
confirmed by observing the change). /v1/toolsets now reports 29 rows including
svos_miranda, and an api_server session resolves to exactly the 8 plugin tools
with the write-klass five absent.

agent.disabled_toolsets stays off permanently: 'i dont want the tools disabled
everywhere'. That key is a global end-of-pipeline subtraction rather than an
api_server-scoped one - measured, a default session goes 46 tools to 20 - and it
is unnecessary anyway, since platform_toolsets.api_server alone produces the exact
8-tool surface. The operator's own session was verified intact at 46 tools after
the restart, which was the point of the ruling.

The consequence is now SVOS's to absorb: it must stop verifying against the global
roster before it restarts, because that roster is 29 by design and will not shrink.
Two workable options went to svos-dev - verify the api_server surface instead, or
relax the check to 'svos_miranda present and write-klass absent'. The second also
survives any unrelated plugin landing on this host, which matters because 'stt'
already appears in that endpoint's rows while resolving it logs 'Unknown toolset'.

irv parakeet retired: it lost tts-dev's bench to the FV seat at both clip lengths
and to whisper-large-v3 at 6.24s. Checked for consumers first - no gateway alias
pointed at it, and every other reference on that host was a comment in a
port-allocation register. Retirement banner on its README names the replacement.

voice-studio stopped: it existed for the dots mint loop and Breeze obsoleted dots
on 2026-09-06, so it was retired rather than repaired.
2026-09-15 02:12:19 -07:00
vh 1f98a1be32 docs(memory): voice-studio is retired not broken; agent.disabled_toolsets is global
Two corrections and one finding from the same night.

voice-studio: operator ruled the stack out of service. It existed for the dots
mint/audition loop and dots was decommissioned 2026-09-06 when Breeze took the
fleet seat, so its reason to exist went with it - which is also why nine days of
breakage alerted nobody. No v11 rebuild. The gate one-liner was applied minutes
before the retraction landed and was left in place rather than reverted, since
the value it replaced was a dead address and reverting is another recreate of a
stack that is going away. Container not stopped: it was already running, and
'down for now' arrived as a relayed paraphrase rather than an instruction.

The two host-level facts survive the stack. Containers on irv-ml1 cannot resolve
nh3.internal at all, so on that host the DNS name is the WRONG fix for a dead-IP
bug - it swaps a dead address for an unresolvable one. Confirm resolution from
inside the container before recommending a name. And a stale link can have more
than one drift behind it: voice-studio had three stacked, two of them invisible
from the host compose file.

Hermes: svos_miranda is installed and enabled in config but the gateway was NOT
restarted, so it is not live. agent.disabled_toolsets as specified by svos-dev is
not scoped to api_server - it is a strict end-of-pipeline subtraction applied to
every session on every platform. Measured: a default session goes 46 tools to 20,
losing memory, file, terminal, web, browser and more. It is also unnecessary:
platform_toolsets.api_server alone resolves an api_server session to exactly the
8 svos_miranda tools. The line buys only SVOS's startup check, which reads a
global endpoint to verify a per-platform property. Left commented out with the
measurement inline so an incidental restart cannot gut the assistant.
2026-09-15 02:08:00 -07:00
vh 2fccaf7128 docs(memory): record the Parakeet bench result and a 96-place stale address on irv-ml1
tts-dev benched both endpoints against a Whisper baseline. FV wins at both clip
lengths (155/391 ms vs IRV 354/1010 vs whisper-large-v3 457/690) — IRV is slower
than the incumbent at 6.24 s, so the duplicate seat is now retirable on evidence
rather than on tidiness. Their length sweep fits ~58 ms fixed + 56 ms per
audio-second, asymptote ~17.8x realtime, independently reproducing our 17x on a
different clip and a different harness. The gateway hop measured below their
harness resolution, so ext-stt is the right consumer path.

Two caveats recorded against our own numbers: their between-run variance is ±20%
because GPU 0 carries the live chat path, and our 0.50 s median was taken on an
idle GPU 3 — marked as a best case, not a comparable.

Also records tts-dev's retraction, which is the durable lesson: published RTFx is
batched throughput on datacenter hardware, not single-stream latency, and the two
differ by ~200x. Their plan had projected 60-120 ms from it.

Separately, chasing the one stale Homepage href they flagged turned up 96
occurrences of the retired wg0 lifeline 10.100.79.3 under /opt/docker on irv-ml1.
Most are cosmetic, but voice-studio is genuinely broken: it is configured to reach
studio-gate at that address, both are running, they sit on separate docker
networks, and the address is on no interface on the host. Failing since the
2026-09-06 cutover with nothing alerting. ext-tts verified unaffected.

Not fixed here — eight containers to recreate, three load-bearing, and the
voice-studio repair touches app.py rather than config. Surfaced with evidence.

The pattern is the third of its shape: a retired address needs a repo-wide grep by
ADDRESS rather than by hostname, and container labels live in no file the sweep
reads until the container is recreated.
2026-09-15 01:57:55 -07:00
vh caa04801f3 fix(parakeet): move the seat from the empty GPU 3 to GPU 0
Placed on GPU 3 first because it was the empty card. That was the wrong read:
the seat is ~800 MiB, under 1% of a 96 GB card, so the question was never "where
does it fit" but "whose headroom is cheapest to spend".

vLLM sizes its KV cache as a fraction of TOTAL VRAM, not free VRAM. A resident
tenant on an otherwise-clean card therefore does not cost its own megabytes — it
costs the profiling margin of whatever full-size seat lands there later, and
flash-next needs 93 GiB of 96. A 96 GB card at 2 MiB can still take that; the
same card at 922 MiB is one where the next big seat needs its utilization
hand-trimmed, which this repo's flash-next history shows is both thin and silent
when it goes wrong.

Committed utilization per card is the number that governs, not free bytes:

    GPU 0   0.40 + 0.48                       = 0.88    ~13 GB spare  <- moved here
    GPU 1   0.52+0.24+0.10+0.055+0.03+0.03    = 0.975   ~4.3 GB
    GPU 2   0.96                                        ~1.8 GB
    GPU 3   -                                           kept empty as reserve

GPU 3 is back to 2 MiB / 97,247 MiB free and is now documented as a deliberate
reserve rather than a spare.

Post-move n=5 on the same clip: 0.68 / 0.54 / 0.54 / 0.52 / 0.53 s, median 0.54 s
against 0.50 s on GPU 3. The spreads overlap at this sample size and no difference
is claimed; the GPU 3 figure was taken on an idle card and is now noted as a best
case, since the seat shares GPU 0 with the hot serving path. Silence control and
the gateway round-trip both re-verified after the move.

Also records both Parakeet endpoints (FV v3 on Blackwell, IRV v2 on a 3090) and
the four confounds that make them not an A/B pair, sent to tts-dev for the bench.
2026-09-15 01:50:25 -07:00
vh b9b14b5baf feat(parakeet): stand up Parakeet STT on fv-ml1 GPU 3 + LiteLLM ext-stt/whisper-1
Retargets the existing sherpa-onnx stack from irv-ml1 to fv-ml1's utility card
and puts it behind the gateway. GPU 3 was the only card with room: 0/1/2 carry
the vLLM seats at 84-95.5 GB of 96.

Changes:

- compose: pin GPU via `device_ids: ["3"]` (the dead on-host stub used
  `count: all`, which would have handed a 0.6B ASR seat all four cards);
  join traefik-net; port 8300; homepage href to the live FV address.
- .env.example: default to the v3 int8 model (25 European languages, 464 MiB)
  rather than English-only v2; models to /tank/parakeet/models.
- app.py: warm the recognizer at startup before uvicorn accepts traffic.

The warmup is not an optimisation. ONNX Runtime's CUDA EP compiles and autotunes
lazily on the FIRST DECODE, and on sm_120 that measured 45.7s cold (reproduced at
45.1s on a second container) against ~0.50s warm. A 45s first request is
indistinguishable from a hang and LiteLLM's default timeout abandons it long
before it returns. Decoding 1s of silence at load moves the cost inside the
healthcheck's 300s start_period; first real request after restart is now 0.65s.

Verification, because "provider=cuda" in the log is only an echo of the env var:
ORT falls back to CPU silently and still returns correct text, so the service
being up and the transcript being right establishes nothing. The discriminator is
a process on GPU 3 (922 MiB), confirmed. Controls both directions — a known TTS
sentence transcribes near-exactly (positive), 3s of digital silence returns
empty (null). Warm throughput 0.50s median on an 8.52s clip, n=5, spread
0.47-0.65s, single-stream, one clip: a smoke measurement with its harness
stated, not a benchmark.

Gateway aliases `ext-stt` (engine-neutral, mirrors ext-tts) and `whisper-1`
(OpenAI-compatible drop-in) registered via POST /model/new, i.e. LiteLLM's
Postgres store where the ext-tts family already lives — no gateway restart, and
config.yaml is consequently not a complete picture of what the gateway serves.
Both verified end to end.

The aliases use a raw IP deliberately: ana-docker resolves no .internal names at
all (resolv.conf points at 1.1.1.1), and LiteLLM only reaches irv-ml1 through a
hand-pinned extra_hosts entry. A second hosts entry would mean recreating the
container and bouncing the gateway for every consumer.

Also records the svos_miranda plugin validation pass and its structural findings,
and notes that the irv-ml1 parakeet is still running — there are two now, and
retiring the old one is the operator's call.
2026-09-15 01:41:41 -07:00
vh c6b6435c52 memory: snapshot — mesh retirement complete, next session points at svos-dev + STT
Captures the close-out of the fleet networking session: mesh membership retired
for both fv-ml1 and nh3-dev, leaving six nodes that each have a job, with
fv-ml1 carrying a break-glass rejoin instead of standing membership and exactly
one live reusable pre-auth key left fleet-wide.

In-flight rewritten to lead with the two jobs the operator named for the next
session -- drain the svos-dev message that has been unread since 00:52, then
stand up an STT service from nothing -- so a fresh context opens on the work
rather than on the history.
2026-09-15 01:07:53 -07:00
vh a65cdf65d9 feat(mesh): retire nh3-dev from the mesh and revert the masquerade it required
nh3-dev sits on the NH3 LAN and reaches every site through its own default
gateway; RouteAll was already false, so it never used the tunnel for routing.
Membership bought a 100.64.0.4 address nothing referenced -- grep across the
repo and ~/development found only docs and memory hits.

It also cost something concrete. A host running Tailscale installs
-A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP, and because the fleet's
subnet routers preserve source rather than masquerading RFC1918, a mesh client's
packet reached nh3-dev's ens18 still sourced 100.64.x and was dropped silently.
That is why nh3-dev.nh3.internal failed from the mesh while every NH3 host that
does not run Tailscale worked, and it needed a -d 10.100.10.50/32 -j MASQUERADE
exception on nh3-scale to paper over. Retiring the membership removed the
anti-spoof rule, so the exception went with it -- mesh-exit-masq.sh is back to
the two rules it had before yesterday.

Verified after: nh3-dev reachable at 10.100.10.50 from ESH, Anaheim, FV, Irvine
and NH3, and reaching all four sites plus the internet itself. fv-ml1
unaffected.

The mesh is now six nodes and every one has a job: three site routers,
vb-gateway, irv-ml1 (Irvine's own router, no separate scale node), and the
operator's MacBook Air. Nothing is enrolled just in case.
2026-09-15 01:05:23 -07:00
vh 959a743256 feat(fv): invert the watchdog to break-glass; fv-ml1 off the mesh
Operator's design, and a better one. Once the FV SNAT rules landed, fv-ml1's
mesh membership was redundant for routing and its only remaining value was as a
second way in. Keeping it enrolled bought a standing second door; joining on
demand buys the same recovery path without one.

  normal    tailscaled stopped + disabled; fleet reached via the gateway SNAT
  fault     nh3-dev / nh3-docker unreachable while the WAN is up
  action    start tailscaled + tailscale up -> reachable at its 100.64.x address

fv-ml1 is now off the mesh and its node record deleted. Verified it still
reaches NH3, ESH, Anaheim, Irvine and the internet on the SNAT path alone, then
the break-glass fired on cue (counted 1..4, joined at 5 as 100.64.0.10),
answered ping and ssh from nh3-dev, and was closed again cleanly.

No auto-leave, deliberately: once open the door stays open until a human runs
systemctl disable --now tailscaled. A watchdog that re-closes on recovery flaps,
and a flapping recovery path is down exactly when someone finally looks. It also
skips entirely when already on the mesh, which is what makes it idempotent after
firing.

The question exposed a hole worth more than the redesign. The stored rejoin key
was one of the 2026-09-12 FV cutover keys, expiring 2026-09-19 -- a break-glass
credential that dies in four days and fails silently at the only moment it
matters. Replaced with a dedicated 1-year reusable key (headscale ID 8, expires
2027-09-15), vaulted as fv-ml1/headscale-breakglass-key, root:600 on the host.

That also closes the standing self-join risk rather than trading it: the two
stale reusable keys (IDs 5, 6) are expired, so the mesh now has exactly one live
reusable key -- purpose-built, on a host we control -- instead of two orphans
nobody owned.

Rejoin uses --accept-routes=false and the reason is in the script: on 2026-09-14
tailscale up --accept-routes on this box accepted its OWN subnet from the
gateway and black-holed it. That happened with a human watching; here it runs
unattended, during an incident, on a box already in trouble.
2026-09-15 01:02:16 -07:00
vh 838132cd6b memory: snapshot — FV cross-site routing fixed, fleet conventions pinned
Session captured: the FV outbound-NAT root cause and its diagnostic signature,
the fv-ml1 dead man's switch, fleet identity/group/path conventions and the
root:docker normalization, nh3-dev's ts-input reachability fix, ESPHome
modernisation and the kb KB-search tool, and the Hermes bearer rotation
release. Six new detail files.

Tried-and-abandoned gains three: probing OPNsense endpoints by POSTing at them
(which rebooted the FV firewall), advertising a /32 from nh3-dev, and the
nh3-scale remote-site masquerade rules that fired but were not the fix.

Housekeeping: 8 Recent-decisions entries archived to archival-memory.md, and 21
oversized inline entries split into detail files per the two-tier rule -- they
had been sitting fully inline in the index, which is what the split exists to
prevent. Two pointers to a detail file archived this run were repointed at
archival-memory.md.

The index is 389 lines, still over the ~300 soft cap. The archival guards stop
it there: only 4 further entries are old enough to move and every one carries an
open deferred-work pointer. An over-cap file that keeps live decisions beats a
scannable one that lost a deferred call.
2026-09-15 00:53:48 -07:00
vh 0ab9da5b89 fix(fv): broaden the Tailscale SNAT rules from fv-ml1/32 to the FV LAN /24
All four outbound-NAT rules on the FV gateway now match source
10.251.50.0/24 instead of fv-ml1's single address, so a second host at FV
works on arrival rather than reproducing a failure whose symptoms point at
routing rather than NAT.

Anaheim got a /24 rule of its own through the API. The 2026-09-13 ANA rule was
written with write_config and is invisible to source_nat/search_rule, so
leaving it as the only ANA coverage would have kept one destination on a
different code path from the other three. The legacy /32 rule is now redundant
but harmless -- it NATs identically and first-match wins -- and is noted in the
runbook for deletion from the UI, since it is the one rule the API cannot see.

Descriptions rewritten to name the real scope. Three of them said "fv-ml1 to X"
while covering the whole subnet, and a description that understates a rule's
reach is the same trap as the Anaheim-only scope that caused this.

Verified after: fv-ml1 reaches NH3, nh3-dev, ESH, Anaheim, Irvine, the mesh and
the internet; nh3-dev, esh-docker-vm and ana-docker all reach FV and each
other; the FV BMC remains reachable inbound. Pre-change config backup taken.

Also records that 10.251.250.0/24 (BMC/management) is deliberately NOT covered
-- inbound reachability is what out-of-band recovery needs, but a management
host originating traffic to another site would hit this same wall.
2026-09-15 00:47:00 -07:00
vh fa04f450fb fix(fv): extend the Tailscale SNAT rule to NH3, ESH and Irvine
FV could not reach any site but Anaheim. The cause was a single outbound-NAT
rule on the FV gateway, added 2026-09-13 and scoped to Anaheim only --
docs/runbooks/fv-to-ana-nat.md says so in as many words: "Other remote sites
remain outside this fix's scope." Three mirrors added, same interface and
source, only the destination differing: 10.100.0.0/16, 10.0.0.0/16 and
10.6.110.0/24.

After: fv-ml1 reaches NH3, ESH, Anaheim, Irvine, the mesh and the internet.
Regression sweep clean across nh3-dev, nh3-docker and esh-docker-vm.

The runbook now records what the failure looks like, because it presents as a
routing or Tailscale fault and is neither. fv-ml1 reached mesh addresses
perfectly and LAN addresses not at all; the FV firewall log showed the outbound
passing with src=10.251.50.54 and no reply returning; temporary counting rules
proved nh3-scale received 5 packets and sent 4 replies; both peers' AllowedIPs
were correct. The discriminator that settles it is that every other site pair
works -- nh3-docker to esh/ana/FV and esh-docker-vm to FV all succeed -- so a
general subnet-to-subnet limitation is ruled out and only outbound SNAT is
left.

Also reverts the remote-site MASQUERADE rules added to nh3-scale earlier on the
asymmetric-return theory. They fired but were not the fix, so they are removed
rather than left to accumulate as NAT that achieves nothing.

Applied via source_nat/add_rule + apply with a pre-change config backup taken
first. Source scope is still fv-ml1's /32, so a second FV host will hit this
again -- flagged in the runbook.
2026-09-15 00:40:28 -07:00
vh 8c8559b8ec feat(fv): mesh dead-man's switch on fv-ml1; partial progress on FV cross-site routing
WATCHDOG (done, proven). fv-mesh-watchdog probes two independent anchors every
minute and, after 5 consecutive failures, puts Tailscale back to known-good:
accept-routes off, re-up against headscale with a stored key. It touches
nothing else — a watchdog with a wide remit is a second way to lose the box.

Two anchors that cannot share a failure mode: a plain-internet one and a
mesh-only one. If BOTH fail the site uplink is down, Tailscale cannot fix that,
and it deliberately does nothing — thrashing tailscaled during an ISP outage
turns a wait into an incident. Disable file at /etc/fv-watchdog.disable for
planned work.

Proven by positive control, not assumed: counter incremented 1..4 without
acting, fired the restore at 5 (tailscale up ran, tailscaled restarted), and
reset to 0 once the real anchor returned. fv-ml1 stayed reachable throughout.

This exists because a  on fv-ml1 black-holed it
from its own LAN earlier the same day: it accepted 10.251.0.0/16 from the
gateway — its OWN subnet — and routed the local network through the tunnel.

FV CROSS-SITE ROUTING (partial). Two changes landed, the path is still broken:

  1. acceptSubnetRoutes 0 -> 1 on the FV gateway's tailscale plugin, via
     settings/set + service/reconfigure (the documented apply, not a reboot).
     The GATEWAY now has 10.0/16, 10.100/16 and 10.250/16 in its routing table
     and reaches NH3 and ESH itself. It could not before.

  2. Remote-site MASQUERADE rules on nh3-scale. The existing jump matched only
     -s 100.64.0.0/10, so traffic from another site's LAN never entered
     MESH-EXIT and kept its original source; an NH3 host then replied via its
     own LAN router instead of back through nh3-scale, making the path
     asymmetric. The rule is confirmed firing (counter increments on FV
     traffic) but does not complete the path.

Still failing: fv-ml1 -> NH3/ESH LAN addresses. Mesh addresses work perfectly
from fv-ml1 (100.64.0.1, 100.64.0.4), Anaheim works over the metro link, and
the FV firewall log shows the outbound passing on tailscale0 with
src=10.251.50.54 and no reply ever returning. The remaining gap is forwarded
FV-LAN traffic specifically, not the gateway's own.

Full regression sweep clean: nh3-dev, ana-docker and esh-docker-vm all reach
all four sites plus the internet.
2026-09-15 00:25:55 -07:00
vh 80d982d1d8 feat(backup): stage the FV firewall config in ana-docker's nightly restic run
The FV edge firewall was not backed up anywhere. Its config now lands in
/var/lib/restic/stage/fv-gateway-config.xml via ana-docker's pre-backup hook,
so the existing 01:00 restic snapshot captures it. ana-docker is one of the
three egress addresses the firewall's WAN allowlist permits, which is why the
pull lives there rather than with the FV hardware — a site that has lost power
cannot back itself up, and FV lost power two days ago.

Non-fatal by design: an unreachable firewall must not abort the nightly
database dumps. But a bad pull must not be promoted either. The summary loop
only rejects EMPTY staged files, and this endpoint answers an auth failure
with a perfectly non-empty HTML error page — which would have been backed up
as a firewall config that is the right size and restores nothing. The block
checks the body really contains <opnsense> and writes nothing otherwise.

Three tests cover it, including the HTML-error-page case. The first draft of
those tests was worthless: _fv returned a Path out of a TemporaryDirectory
context, so the tree was deleted before the assertions ran and every
exists()-is-False check passed regardless of what the script did. Only the
positive test failed, which is the sole reason the broken negatives were
caught. They now snapshot inside the tempdir's lifetime, and the docstring
says why.

Also records two OPNsense API lessons in docs/pfi/opnsense-api-reference.md:
endpoints are actions and must never be probed for existence by POSTing at
them — that is how /api/core/system/reboot took the FV site dark for 3.5
minutes while looking for an apply call this same file already documented —
and the apply step is service/reconfigure, which auth/user notably lacks, so
an API-only key edit persists in config.xml and does nothing until the OS user
sync runs at boot.

Credentials in /etc/restic/fv-gateway.env (root:600), template committed,
values vaulted as fv-gateway/opnsense-api-{key,secret}. Pre-change config
snapshot vaulted as fv-gateway/config-backup-20260914.
2026-09-15 00:12:50 -07:00
vh 9dbd829b9d fix(mesh): make nh3-dev reachable at its LAN address from the mesh
One rule on nh3-scale (CT 107): -d 10.100.10.50/32 -j MASQUERADE, above the
RFC1918 RETURNs in /usr/local/sbin/mesh-exit-masq.sh, so it survives a reboot
rather than living only in the running ruleset.

Cause. A host that runs Tailscale installs -A ts-input -s 100.64.0.0/10
! -i tailscale0 -j DROP. The fleet's subnet routers run NoSNAT: true with
RFC1918 explicitly exempted from masquerade — deliberate source preservation,
and a departure from Tailscale's own --snat-subnet-routes=true default — so a
mesh client's packet reached nh3-dev's ens18 still sourced 100.64.x and died
at the anti-spoof rule. Every NH3 host that does not run Tailscale was
unaffected, which is why this read as a DNS or routing fault rather than a
policy one. Masquerading just this destination makes it behave like every
other host and leaves source preservation absolute elsewhere.

Verified before and after against 13 targets from nh3-dev and 9 from the
MacBook Air, and again after restarting the service so the chain was rebuilt
from the script rather than from the manual insert. nh3-dev.nh3.internal now
resolves and connects from the mesh, ssh and the Booth port included, with no
script changes anywhere.

Records the failed approach prominently, because it is the attractive one:
advertising 10.100.10.50/32 from nh3-dev itself black-holed it from ESH,
Anaheim, FV and Irvine. ip rule there puts lookup 52 at priority 5270 ahead of
main at 32766, and becoming a subnet router let table 52 capture cross-site
traffic the node has no accepted route for. Its own LAN and the internet kept
working throughout, so a single-host check confirms a break it cannot see.
2026-09-14 23:18:32 -07:00
vh e64193171b docs(nh3-dev): Hermes bearer rotation hold released
svos-dev split their Bifrost wall's HS256 signing key off the Hermes Bearer
(svos main 7165272), so nh3-dev/hermes/api-server-key is free to rotate again.
The previous note said do-not-rotate and would have made a future session
refuse a legitimate rotation on stale grounds.

Not rotating now: the key was minted today, is vaulted, and has never been
exposed — rotation is a hygiene action with a trigger, and none applies. What
changed is the capability, which is what the record needs to reflect.

Also records two things for when the svos_miranda plugin arrives: it will
reference the dispatch key rather than the Bearer (expected, not a defect), and
its tools array is legitimately seven or eight entries because repo_read is
conditional on a config block SVOS owns. A third number is a real fault.
2026-09-14 19:29:02 -07:00
vh c659fa5020 fix(esphome): correct the record — mDNS advertisement was never removed
ha-dev caught a false claim I committed in 687c699: 'no mDNS advertisement'
and '_esphomebuilder._tcp gone too'. Both wrong. The dashboard is still
advertised; I confirmed it independently with an mDNS PTR query rather than
taking the correction on trust — 331-byte response from 10.0.50.45.

The error was two instruments deep. First, wrong instrument: I inferred a
network fact from a log grep instead of asking the network. Second, the grep
itself was silently truncating —  returned 0 for a
line that exists in the full log at 19:03:03 on the current boot, because a
bare time is parsed against a different reference than the displayed
timestamps. A filter that drops your window reports absence indistinguishably
from a real zero.

Re-verified the peer-link conclusion against the FULL log, since it rested on
the same bad grep: 'peer-link site listening' appears at 18:55:22 and 19:01:28
only, both before the 19:03:01 restart, and Netid State      Recv-Q Send-Q                                                                      Local Address:Port               Peer Address:Port     Process
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 503187424                     * 503225110
u_str ESTAB      0      0                                                                                       * 321804885                     * 321804884
u_dgr ESTAB      0      0                                                                                       * 520466417                     * 25662
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 502189514                     * 502207581
u_str ESTAB      0      0                                                                                       * 20836                         * 15946
u_str ESTAB      0      0                                                                                       * 364734154                     * 364734153
u_str ESTAB      0      0                                                                                       * 172931544                     * 172931545
u_str ESTAB      0      0                                                                                       * 187891155                     * 187891156
u_str ESTAB      0      0                                                                                       * 520270573                     * 520261514
u_str ESTAB      0      0                                                                                       * 20631                         * 25881
u_str ESTAB      0      0                                                                                       * 172931543                     * 172931542
u_dgr ESTAB      0      0                                                                                       * 16863                         * 16864
u_str ESTAB      0      0                                                                                       * 503210394                     * 503205589
u_str ESTAB      0      0                                                                                       * 248399528                     * 248399529
u_str ESTAB      0      0                                                                                       * 105475370                     * 105475371
u_str ESTAB      0      0                                                                                       * 69011789                      * 69011788
u_str ESTAB      0      0                                                                                       * 3165934                       * 3165933
u_str ESTAB      0      0                                                                                       * 24696                         * 20601
u_str ESTAB      0      0                                                                                       * 2175986                       * 2175985
u_str ESTAB      0      0                                                                                       * 172931558                     * 172931559
u_str ESTAB      0      0                                                                                       * 160801993                     * 160801992
u_str ESTAB      0      0                                                                                       * 18386                         * 18385
u_str ESTAB      0      0                                                                                       * 187891160                     * 187891159
u_dgr ESTAB      0      0                                                                                       * 61008                         * 25662
u_str ESTAB      0      0                                                                                       * 3167752                       * 3167753
u_dgr ESTAB      0      0                                                                                       * 17512                         * 25662
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 20596                         * 24684
u_str ESTAB      0      0                                                                                       * 364734156                     * 364734155
u_str ESTAB      0      0                                                                                       * 172931557                     * 172931556
u_str ESTAB      0      0                                                                                       * 163017376                     * 163017377
u_str ESTAB      0      0                                                                                       * 24671                         * 19536
u_str ESTAB      0      0                                                                                       * 160801991                     * 160801990
u_str ESTAB      0      0                                                                                       * 37642868                      * 37642869
u_str ESTAB      0      0                                                                                       * 535492351                     * 535492350
u_str ESTAB      0      0                                                                                       * 105475367                     * 105475366
u_str ESTAB      0      0                                                                                       * 24705                         * 24706
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 271511134                     * 271557694
u_str ESTAB      0      0                                                                                       * 2175985                       * 2175986
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 15948                         * 16931
u_str ESTAB      0      0                                                                                       * 18328                         * 15945
u_str ESTAB      0      0                                                                                       * 105323726                     * 105323727
u_str ESTAB      0      0                                                                                       * 45403900                      * 45403901
u_str ESTAB      0      0                                                                                       * 527114553                     * 527114554
u_str ESTAB      0      0                                                                                       * 287336311                     * 287336310
u_str ESTAB      0      0                                                                                       * 287354062                     * 287354063
u_str ESTAB      0      0                                                                                       * 105315056                     * 105315055
u_str ESTAB      0      0                                                                                       * 3165933                       * 3165934
u_str ESTAB      0      0                                                                                       * 14493                         * 14492
u_str ESTAB      0      0                                                                                       * 16875                         * 24708
u_dgr ESTAB      0      0                                                                                       * 27435051                      * 25664
u_str ESTAB      0      0                                                                                       * 163017377                     * 163017376
u_str ESTAB      0      0                                                                                       * 505982055                     * 505963077
u_str ESTAB      0      0                                                                                       * 505979226                     * 505982036
u_str ESTAB      0      0                                                                                       * 248399529                     * 248399528
u_str ESTAB      0      0                                                                                       * 51378988                      * 51378989
u_str ESTAB      0      0                                                                                       * 364734155                     * 364734156
u_str ESTAB      0      0                                                                                       * 160777161                     * 160777160
u_dgr ESTAB      0      0                                                                                       * 20583                         * 25662
u_str ESTAB      0      0                                                                                       * 37642870                      * 37642871
u_str ESTAB      0      0                                                                                       * 520270568                     * 0
u_str ESTAB      0      0                                                                                       * 105475368                     * 105475369
u_str ESTAB      0      0                                                                                       * 18990478                      * 18991473
u_str ESTAB      0      0                                                                                       * 4332746                       * 4332745
u_str ESTAB      0      0                                                                                       * 4041751                       * 4041752
u_str ESTAB      0      0                                                                                       * 24684                         * 20596
u_str ESTAB      0      0                                                                                       * 520517051                     * 0
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 321223400                     * 321228120
u_dgr ESTAB      0      0                                                                                       * 28403                         * 25662
u_str ESTAB      0      0                                                                                       * 172931542                     * 172931543
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 15945                         * 18328
u_str ESTAB      0      0                                                                                       * 51378990                      * 51378991
u_str ESTAB      0      0                                                                                       * 364734153                     * 364734154
u_str ESTAB      0      0                                                                                       * 172931561                     * 172931560
u_str ESTAB      0      0                                                                                       * 28400                         * 19407
u_str ESTAB      0      0                                                                                       * 287336310                     * 287336311
u_str ESTAB      0      0      /run/containerd/s/11912e5b8985b87f67739888cd3d1796ea228b84682db1a435736131d390e93d 505982036                     * 505979226
u_str ESTAB      0      0                                                                                       * 51378992                      * 51378993
u_str ESTAB      0      0                                                                                       * 163017378                     * 163017379
u_str ESTAB      0      0                                                                                       * 105323728                     * 105323729
u_dgr ESTAB      0      0                                                                                       * 16794                         * 16795
u_str ESTAB      0      0                                                                                       * 502207581                     * 502189514
u_str ESTAB      0      0                                                                                       * 24687                         * 20599
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 61700                         * 61004
u_str ESTAB      0      0                                                             /run/dbus/system_bus_socket 24708                         * 16875
u_str ESTAB      0      0                                                                                       * 172931559                     * 172931558
u_str ESTAB      0      0                                                                                       * 18385                         * 18386
u_str ESTAB      0      0                                                                                       * 502207587                     * 502207588
u_str ESTAB      0      0                                                                                       * 2175982                       * 2175981
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 15947                         * 24716
u_dgr ESTAB      0      0                                                                     /run/systemd/notify 16793                         * 0
u_str ESTAB      0      0                                                                                       * 211929261                     * 211929262
u_str ESTAB      0      0                                                                                       * 505966166                     * 505963075
u_str ESTAB      0      0                                      /home/lkraven/.claude/remote/run/b927d560/rpc.sock 520261514                     * 520270573
u_str ESTAB      0      0                                                                                       * 177602210                     * 177602211
u_str ESTAB      0      0                                                                                       * 160777160                     * 160777161
u_str ESTAB      0      0                                                                                       * 211929262                     * 211929261
u_dgr ESTAB      0      0                                                                                       * 4041742                       * 25662
u_str ESTAB      0      0                                                                                       * 503653921                     * 503666646
u_str ESTAB      0      0                                                                                       * 4041752                       * 4041751
u_str ESTAB      0      0                                                         /run/containerd/containerd.sock 503204798                     * 503100306
u_str ESTAB      0      0                                                                                       * 51378991                      * 51378990
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 18991473                      * 18990478
u_str ESTAB      0      0                                                                                       * 2175983                       * 2175984
u_str ESTAB      0      0                                                                                       * 364734152                     * 364734151
u_str ESTAB      0      0                                                                                       * 172931545                     * 172931544
u_str ESTAB      0      0                                                                                       * 160801990                     * 160801991
u_dgr ESTAB      0      0                                                                                       * 16866                         * 16865
u_dgr ESTAB      0      0                                                            /run/systemd/journal/dev-log 25662                         * 0
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 503222380                     * 503210386
u_str ESTAB      0      0                                                                                       * 2175981                       * 2175982
u_dgr ESTAB      0      0                                                             /run/systemd/journal/socket 25664                         * 0
u_str ESTAB      0      0                                                                                       * 187891158                     * 187891157
u_str ESTAB      0      0                                                                                       * 105323725                     * 105323724
u_str ESTAB      0      0                                                                                       * 271499970                     * 271499971
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 20599                         * 24687
u_dgr ESTAB      0      0                                                                                       * 16865                         * 16866
u_str ESTAB      0      0                                                                                       * 520517939                     * 520517938
u_str ESTAB      0      0                                                                                       * 287354064                     * 287354065
u_str ESTAB      0      0                                                                                       * 105475369                     * 105475368
u_str ESTAB      0      0                                                                      /run/user/1000/bus 283951                        * 286837
u_dgr ESTAB      0      0                                                                                       * 20620                         * 25664
u_str ESTAB      0      0                                                                                       * 187891159                     * 187891160
u_dgr ESTAB      0      0                                                                                       * 16795                         * 16794
u_str ESTAB      0      0                                                                                       * 211826467                     * 211826466
u_str ESTAB      0      0                                                                                       * 158808                        * 158807
u_str ESTAB      0      0                                                                                       * 24716                         * 15947
u_str ESTAB      0      0                                                                        /run/docker.sock 505963075                     * 505966166
u_str ESTAB      0      0                                                                                       * 177602211                     * 177602210
u_str ESTAB      0      0                                                                                       * 160777158                     * 160777159
u_str ESTAB      0      0                                                                                       * 37642872                      * 37642873
u_str ESTAB      0      0                                                                                       * 502207588                     * 502207587
u_str ESTAB      0      0                                                                                       * 286837                        * 283951
u_str ESTAB      0      0                                                                                       * 14492                         * 14493
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 20601                         * 24696
u_str ESTAB      0      0                                                                                       * 160801992                     * 160801993
u_str ESTAB      0      0                                                                                       * 409730867                     * 409730866
u_str ESTAB      0      0                                                                                       * 520517938                     * 520517939
u_str ESTAB      0      0                                                                                       * 287354063                     * 287354062
u_str ESTAB      0      0                                                                                       * 271499971                     * 271499970
u_str ESTAB      0      0                                                                                       * 2175984                       * 2175983
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 19536                         * 24671
u_dgr ESTAB      0      0                                                                                       * 57047973                      * 16793
u_str ESTAB      0      0                                                                                       * 45403901                      * 45403900
u_str ESTAB      0      0                                                                                       * 37642869                      * 37642868
u_str ESTAB      0      0                                                                                       * 158807                        * 158808
u_str ESTAB      0      0                                                                                       * 61004                         * 61700
u_str ESTAB      0      0      /run/containerd/s/642d2e2cfa9c2dce9b0a7f5d1300cbf425c4ebf5c4725e1fe426333f34172e6f 503666646                     * 503653921
u_str ESTAB      0      0                                                                                       * 503225110                     * 503187424
u_str ESTAB      0      0                                                                                       * 3164605                       * 3164606
u_str ESTAB      0      0                                                                                       * 535492350                     * 535492351
u_str ESTAB      0      0                                                                                       * 527114554                     * 527114553
u_str ESTAB      0      0                                                                                       * 287354067                     * 287354066
u_str ESTAB      0      0                                                                                       * 51378989                      * 51378988
u_str ESTAB      0      0                                                                                       * 265067896                     * 265067895
u_str ESTAB      0      0                                                                                       * 172931546                     * 172931547
u_str ESTAB      0      0                                                                                       * 163017379                     * 163017378
u_str ESTAB      0      0                                                                                       * 187891157                     * 187891158
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 19407                         * 28400
u_str ESTAB      0      0                                                                                       * 535601698                     * 535601697
u_str ESTAB      0      0                                                                                       * 531452134                     * 531452135
u_str ESTAB      0      0                                                                                       * 503100306                     * 503204798
u_str ESTAB      0      0                                                                                       * 503210386                     * 503222380
u_str ESTAB      0      0                                                                                       * 4332745                       * 4332746
u_str ESTAB      0      0                                                                                       * 364734151                     * 364734152
u_str ESTAB      0      0                                                                                       * 172931556                     * 172931557
u_str ESTAB      0      0                                                                                       * 3167753                       * 3167752
u_str ESTAB      0      0                                                                                       * 16931                         * 15948
u_dgr ESTAB      0      0                                                                                       * 153774                        * 25662
u_str ESTAB      0      0                                                                                       * 105323729                     * 105323728
u_str ESTAB      0      0                                                                                       * 535601697                     * 535601698
u_str ESTAB      0      0                                                   /run/containerd/containerd.sock.ttrpc 505963077                     * 505982055
u_str ESTAB      0      0                                                                                       * 172931547                     * 172931546
u_str ESTAB      0      0                                                                                       * 105323727                     * 105323726
u_dgr ESTAB      0      0                                                                                       * 16864                         * 16863
u_str ESTAB      0      0                                                                                       * 468781321                     * 0
u_str ESTAB      0      0                                                                                       * 321228120                     * 321223400
u_str ESTAB      0      0                                                                                       * 105475366                     * 105475367
u_str ESTAB      0      0                                                                                       * 535633202                     * 535633201
u_dgr ESTAB      0      0                                                                                       * 30815                         * 25662
u_str ESTAB      0      0                                                                                       * 265067895                     * 265067896
u_str ESTAB      0      0                                                                                       * 177602213                     * 177602212
u_str ESTAB      0      0                                                                                       * 187891156                     * 187891155
u_dgr ESTAB      0      0                                                                                       * 16859                         * 25664
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 15946                         * 20836
u_str ESTAB      0      0                                                                                       * 172931560                     * 172931561
u_str ESTAB      0      0                                                                                       * 321804884                     * 321804885
u_str ESTAB      0      0                                                                                       * 287354065                     * 287354064
u_str ESTAB      0      0                                                             /run/dbus/system_bus_socket 25881                         * 20631
u_str ESTAB      0      0                                                                                       * 51378993                      * 51378992
u_str ESTAB      0      0                                                             /run/dbus/system_bus_socket 280975                        * 286838
u_str ESTAB      0      0                                                                                       * 37642871                      * 37642870
u_str ESTAB      0      0                                                                                       * 531452135                     * 531452134
u_str ESTAB      0      0                                                                                       * 287354066                     * 287354067
u_str ESTAB      0      0                                                                                       * 211826466                     * 211826467
u_str ESTAB      0      0                                                         /run/containerd/containerd.sock 503205589                     * 503210394
u_str ESTAB      0      0                                                                                       * 409730866                     * 409730867
u_str ESTAB      0      0                                                                                       * 105323724                     * 105323725
u_str ESTAB      0      0                                                                                       * 271557694                     * 271511134
u_str ESTAB      0      0                                                                                       * 69011788                      * 69011789
u_str ESTAB      0      0                                                                                       * 286838                        * 280975
u_str ESTAB      0      0                                                                                       * 24706                         * 24705
u_str ESTAB      0      0                                                                                       * 535633201                     * 535633202
u_str ESTAB      0      0                                                                                       * 37642873                      * 37642872
u_str ESTAB      0      0                                                                                       * 105475371                     * 105475370
u_str ESTAB      0      0                                                                                       * 105315055                     * 105315056
u_str ESTAB      0      0                                                                                       * 177602212                     * 177602213
u_str ESTAB      0      0                                                                                       * 160777159                     * 160777158
u_str ESTAB      0      0                                                                                       * 3164606                       * 3164605
u_str ESTAB      0      0                                                                                       * 15925                         * 13386
u_str ESTAB      0      0                                                                                       * 187899267                     * 187899268
u_str ESTAB      0      0                                                                                       * 4489879                       * 4489880
u_str ESTAB      0      0                                                                                       * 321803916                     * 321803915
u_str ESTAB      0      0                                                                                       * 52452825                      * 52452826
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 28383                         * 21596
u_str ESTAB      0      0                                                                                       * 531437601                     * 531437600
u_str ESTAB      0      0                                                                                       * 19420                         * 19421
u_str ESTAB      0      0                                                                                       * 503672006                     * 503563060
u_str ESTAB      0      0                                                                                       * 51388674                      * 51388673
u_str ESTAB      0      0                                                                                       * 25878                         * 24711
u_str ESTAB      0      0                                                                                       * 147394                        * 154728
u_str ESTAB      0      0                                                                                       * 187899271                     * 187899272
u_str ESTAB      0      0                                                                                       * 321803915                     * 321803916
u_str ESTAB      0      0                                                                                       * 249986684                     * 249986685
u_str ESTAB      0      0                                                                                       * 3804253                       * 3804252
u_str ESTAB      0      0                                                                                       * 24408                         * 24709
u_str ESTAB      0      0                                                                                       * 248406427                     * 248406426
u_str ESTAB      0      0                                                                                       * 527128577                     * 527128578
u_str ESTAB      0      0                                                                                       * 318961033                     * 318961034
u_str ESTAB      0      0                                                                                       * 265080194                     * 265080193
u_str ESTAB      0      0                                                                                       * 111082006                     * 111088943
u_str ESTAB      0      0                                                                                       * 19234766                      * 19234767
u_str ESTAB      0      0                                                                                       * 192528046                     * 192528045
u_dgr ESTAB      0      0                                                                                       * 149063                        * 25662
u_str ESTAB      0      0                                                                                       * 520269438                     * 520269437
u_str ESTAB      0      0                                                                                       * 265080189                     * 265080190
u_str ESTAB      0      0                                                                                       * 53881124                      * 53881123
u_dgr ESTAB      0      0                                                                                       * 27429404                      * 16793
u_str ESTAB      0      0                                                                                       * 535470104                     * 535470103
u_str ESTAB      0      0                                                                                       * 192528047                     * 192528048
u_str ESTAB      0      0                                                                                       * 535621794                     * 535621795
u_str ESTAB      0      0                                                                                       * 468766309                     * 468766308
u_str ESTAB      0      0                                                                                       * 265080192                     * 265080191
u_str ESTAB      0      0                                                                                       * 45411693                      * 45411692
u_str ESTAB      0      0                                                                                       * 16086                         * 16087
u_dgr ESTAB      0      0                                                                                       * 321773330                     * 25662
u_str ESTAB      0      0                                                                                       * 531438660                     * 531438661
u_str ESTAB      0      0                                                                                       * 249986680                     * 249986681
u_str ESTAB      0      0                                                                                       * 22636499                      * 22636498
u_str ESTAB      0      0                                                                                       * 535470103                     * 535470104
u_str ESTAB      0      0                                                                                       * 187772975                     * 187772974
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 27035                         * 21527
u_str ESTAB      0      0                                                                                       * 265080193                     * 265080194
u_dgr ESTAB      0      0                                                                                       * 15922                         * 15921
u_str ESTAB      0      0                                                                                       * 10561346                      * 0
u_dgr ESTAB      0      0                                                                                       * 21541                         * 21540
u_str ESTAB      0      0                                                                                       * 187899269                     * 187899270
u_str ESTAB      0      0                                                                                       * 4499989                       * 0
u_str ESTAB      0      0                                                                                       * 248406429                     * 248406428
u_str ESTAB      0      0                                                                                       * 19250299                      * 19250298
u_str ESTAB      0      0                                                                                       * 172954250                     * 172954249
u_str ESTAB      0      0                                                                                       * 37647005                      * 37647006
u_dgr ESTAB      0      0                                                                                       * 15898                         * 25662
u_str ESTAB      0      0                                                                                       * 192528048                     * 192528047
u_str ESTAB      0      0                                                                                       * 25874                         * 25873
u_str ESTAB      0      0                                                                                       * 535590167                     * 535590166
u_str ESTAB      0      0                                                                                       * 249986681                     * 249986680
u_str ESTAB      0      0                                                                                       * 53881123                      * 53881124
u_str ESTAB      0      0                                                                                       * 22636500                      * 22636501
u_str ESTAB      0      0                                                                                       * 19421                         * 19420
u_str ESTAB      0      0                                                                                       * 318989927                     * 318989926
u_str ESTAB      0      0                                                                                       * 192528045                     * 192528046
u_str ESTAB      0      0                                                                                       * 149062                        * 148051
u_str ESTAB      0      0                                                                                       * 527128578                     * 527128577
u_str ESTAB      0      0                                                                                       * 527122038                     * 0
u_str ESTAB      0      0                                                                                       * 341919445                     * 341919444
u_str ESTAB      0      0                                                                                       * 265080190                     * 265080189
u_str ESTAB      0      0                                                                                       * 246588366                     * 246588367
u_str ESTAB      0      0                                         /run/user/1000/zellij/contract_version_1/Claude 527128606                     * 527139333
u_str ESTAB      0      0                                                                                       * 750542                        * 750541
u_str ESTAB      0      0                                                                                       * 57054442                      * 57048863
u_str ESTAB      0      0                                                                                       * 52453681                      * 52453682
u_str ESTAB      0      0                                                                                       * 22636496                      * 22636497
u_str ESTAB      0      0                                                                                       * 150082                        * 158811
u_str ESTAB      0      0                                                                                       * 187899268                     * 187899267
u_str ESTAB      0      0                                                             /run/dbus/system_bus_socket 13386                         * 15925
u_str ESTAB      0      0                                                                                       * 52452830                      * 52452829
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 24406                         * 18609
u_str ESTAB      0      0                                                                                       * 52453682                      * 52453681
u_str ESTAB      0      0                                                                                       * 45411694                      * 45411695
u_str ESTAB      0      0                                                                                       * 187772976                     * 187772977
u_str ESTAB      0      0                                                                                       * 531419342                     * 531419341
u_str ESTAB      0      0                                                                                       * 341919444                     * 341919445
u_str ESTAB      0      0                                                                                       * 249986682                     * 249986683
u_str ESTAB      0      0                                                                                       * 321770450                     * 321770451
u_str ESTAB      0      0                                                                                       * 187899270                     * 187899269
u_str ESTAB      0      0                                                                                       * 4489882                       * 4489881
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 111088943                     * 111082006
u_str ESTAB      0      0                                                                                       * 19250298                      * 19250299
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 20604                         * 18626
u_str ESTAB      0      0                                                                                       * 19234767                      * 19234766
u_str ESTAB      0      0                                                                                       * 21596                         * 28383
u_dgr ESTAB      0      0                                                                                       * 468766299                     * 25662
u_str ESTAB      0      0                                                                                       * 52452828                      * 52452827
u_str ESTAB      0      0                                                                                       * 16087                         * 16086
u_str ESTAB      0      0                                                                                       * 750540                        * 750539
u_str ESTAB      0      0                                                                                       * 52452826                      * 52452825
u_str ESTAB      0      0                                                                                       * 535590166                     * 535590167
u_str ESTAB      0      0                                                                                       * 468766308                     * 468766309
u_str ESTAB      0      0                                                                                       * 265080191                     * 265080192
u_str ESTAB      0      0                                                             /run/dbus/system_bus_socket 148051                        * 149062
u_str ESTAB      0      0                                                                                       * 527139333                     * 527128606
u_str ESTAB      0      0                                                                                       * 187772979                     * 187772978
u_str ESTAB      0      0                                                                                       * 22636497                      * 22636496
u_str ESTAB      0      0                                                                                       * 18626                         * 20604
u_str ESTAB      0      0                                                                                       * 15887                         * 16905
u_str ESTAB      0      0                                                                                       * 4489878                       * 4489877
u_str ESTAB      0      0                                                                                       * 282025                        * 282026
u_str ESTAB      0      0                                                                                       * 246588367                     * 246588366
u_str ESTAB      0      0                                                                                       * 18609                         * 24406
u_str ESTAB      0      0                                                                                       * 318989926                     * 318989927
u_str ESTAB      0      0                                                                                       * 750541                        * 750542
u_str ESTAB      0      0                                                                      /run/user/1000/bus 158811                        * 150082
u_str ESTAB      0      0                                                                                       * 25873                         * 25874
u_str ESTAB      0      0                                                                                       * 248406431                     * 248406430
u_str ESTAB      0      0                                                                                       * 531438661                     * 531438660
u_str ESTAB      0      0                                                                                       * 520269437                     * 520269438
u_str ESTAB      0      0                                                                                       * 53881122                      * 53881121
u_str ESTAB      0      0                                                                                       * 45411692                      * 45411693
u_str ESTAB      0      0                                                                                       * 750537                        * 750538
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 16905                         * 15887
u_str ESTAB      0      0                                                                                       * 319149630                     * 319149631
u_str ESTAB      0      0                                                                                       * 187765377                     * 187765378
u_str ESTAB      0      0                                                                                       * 282032                        * 282033
u_str ESTAB      0      0                                                                                       * 22636498                      * 22636499
u_str ESTAB      0      0                                                                                       * 187899272                     * 187899271
u_str ESTAB      0      0                                                                                       * 4489877                       * 4489878
u_str ESTAB      0      0                                                             /run/dbus/system_bus_socket 24709                         * 24408
u_str ESTAB      0      0                                                                                       * 52452827                      * 52452828
u_str ESTAB      0      0                                                                                       * 282026                        * 282025
u_str ESTAB      0      0                                                                                       * 249986683                     * 249986682
u_str ESTAB      0      0                                                                                       * 22636501                      * 22636500
u_str ESTAB      0      0                                                                                       * 21527                         * 27035
u_dgr ESTAB      0      0                                                                                       * 520269428                     * 25662
u_dgr ESTAB      0      0                                                                                       * 21540                         * 21541
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 497070283                     * 497065485
u_str ESTAB      0      0                                                                                       * 192528044                     * 192528043
u_str ESTAB      0      0                                                                                       * 4489881                       * 4489882
u_str ESTAB      0      0                                                                                       * 531419341                     * 531419342
u_str ESTAB      0      0                                                                                       * 37647006                      * 37647005
u_str ESTAB      0      0                                                                                       * 45411696                      * 45411697
u_str ESTAB      0      0                                                                                       * 187772978                     * 187772979
u_str ESTAB      0      0                                                                                       * 57050542                      * 57045722
u_str ESTAB      0      0                                                                                       * 4510855                       * 4510854
u_str ESTAB      0      0                                                             /run/dbus/system_bus_socket 57048863                      * 57054442
u_str ESTAB      0      0                                                                                       * 53881121                      * 53881122
u_dgr ESTAB      0      0                                                                                       * 527122050                     * 25662
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 57045722                      * 57050542
u_str ESTAB      0      0                                                                                       * 750539                        * 750540
u_str ESTAB      0      0                                                                                       * 282033                        * 282032
u_dgr ESTAB      0      0                                                                                       * 15921                         * 15922
u_str ESTAB      0      0                                                                                       * 321770451                     * 321770450
u_str ESTAB      0      0                                                                                       * 192528043                     * 192528044
u_str ESTAB      0      0                                                                                       * 53881120                      * 53881119
u_str ESTAB      0      0                                                                                       * 187772974                     * 187772975
u_str ESTAB      0      0                                                                                       * 503669018                     * 503673885
u_str ESTAB      0      0                                                                                       * 318961034                     * 318961033
u_str ESTAB      0      0                                                                                       * 53881119                      * 53881120
u_str ESTAB      0      0                                                                                       * 187772977                     * 187772976
u_str ESTAB      0      0                                                                                       * 4510854                       * 4510855
u_str ESTAB      0      0                                                                                       * 52452829                      * 52452830
u_str ESTAB      0      0                                                                                       * 535621795                     * 535621794
u_dgr ESTAB      0      0                                                                                       * 15908                         * 25664
u_str ESTAB      0      0                                                                                       * 4489880                       * 4489879
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 154728                        * 147394
u_str ESTAB      0      0                                                                                       * 249986685                     * 249986684
u_str ESTAB      0      0                                                                        /run/docker.sock 503563060                     * 503672006
u_str ESTAB      0      0                                                                                       * 319149631                     * 319149630
u_str ESTAB      0      0                                                                                       * 248406426                     * 248406427
u_str ESTAB      0      0                                                                                       * 531437600                     * 531437601
u_str ESTAB      0      0                                                                                       * 142624625                     * 142626682
u_str ESTAB      0      0                                                                                       * 51388673                      * 51388674
u_str ESTAB      0      0                                                                                       * 45411697                      * 45411696
u_str ESTAB      0      0                                                                                       * 248406430                     * 248406431
u_str ESTAB      0      0                                                             /run/systemd/journal/stdout 142626682                     * 142624625
u_str ESTAB      0      0                                                   /run/containerd/containerd.sock.ttrpc 503673885                     * 503669018
u_str ESTAB      0      0                                                                                       * 3804252                       * 3804253
u_str ESTAB      0      0                                                                                       * 497065485                     * 497070283
u_str ESTAB      0      0                                                                                       * 45411695                      * 45411694
u_str ESTAB      0      0                                                             /run/dbus/system_bus_socket 24711                         * 25878
u_dgr ESTAB      0      0                                                                                       * 21536                         * 25664
u_str ESTAB      0      0                                                                                       * 321773321                     * 0
u_str ESTAB      0      0                                                                                       * 750538                        * 750537
u_str ESTAB      0      0                                                                                       * 248406428                     * 248406429
u_str ESTAB      0      0                                                                                       * 187765378                     * 187765377
u_str ESTAB      0      0                                                                                       * 4036771                       * 0
u_str ESTAB      0      0                                                                                       * 172954249                     * 172954250
tcp   ESTAB      0      0                                                                            10.100.10.50:8770                 10.0.10.10:61497
tcp   ESTAB      0      0                                                                            10.100.10.50:40898             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:38636             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:48192              104.18.32.47:https
tcp   ESTAB      0      0                                                                            10.100.10.50:40490              104.18.32.47:https
tcp   ESTAB      0      0                                                                            10.100.10.50:844                10.100.50.50:nfs
tcp   ESTAB      0      0                                                                            10.100.10.50:34046             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:52620              10.100.50.40:8390
tcp   ESTAB      0      0                                                                            10.100.10.50:51638             70.230.226.88:https
tcp   ESTAB      0      0                                                                            10.100.10.50:ssh                  10.0.10.10:60190
tcp   ESTAB      0      0                                                                            10.100.10.50:44198           199.165.136.101:https
tcp   ESTAB      0      0                                                                            10.100.10.50:34048             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:52664               10.6.110.50:ssh
tcp   ESTAB      0      0                                                                            10.100.10.50:36054             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:47758              104.18.32.47:https
tcp   ESTAB      0      0                                                                            10.100.10.50:56154               10.0.10.235:ssh
tcp   ESTAB      0      0                                                                            10.100.10.50:48002             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:48206             34.149.66.165:https
tcp   ESTAB      0      0                                                                            10.100.10.50:33262             104.18.28.234:https
tcp   ESTAB      0      0                                                                            10.100.10.50:ssh                 10.100.79.2:62737
tcp   CLOSE-WAIT 1      0                                                                            10.100.10.50:56568              10.250.50.70:4000
tcp   ESTAB      0      0                                                                            10.100.10.50:38016             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:44484             208.111.40.12:https
tcp   ESTAB      0      0                                                                            10.100.10.50:52610             34.149.66.165:https
tcp   ESTAB      0      0                                                                            10.100.10.50:ssh               10.100.10.194:51093
tcp   ESTAB      0      0                                                                            10.100.10.50:58500             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:57430             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:ssh                 38.120.94.3:59226
tcp   ESTAB      0      0                                                                            10.100.10.50:51558             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:57184             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:39920             160.79.104.10:https
tcp   ESTAB      0      0                                                                            10.100.10.50:44666             34.149.66.165:https
tcp   ESTAB      0      0                                                                            10.100.10.50:ssh                  10.0.10.83:49689
tcp   ESTAB      0      0                                                                            10.100.10.50:54550              38.120.12.44:https
tcp   ESTAB      0      0                                                                            10.100.10.50:39908             160.79.104.10:https
tcp   CLOSE-WAIT 1      0                                                                            10.100.10.50:42224             10.250.50.152:http-alt
tcp   ESTAB      0      0                                                                            10.100.10.50:ssh                  10.0.10.10:60814
tcp   ESTAB      0      0                                                                   [::ffff:10.100.10.50]:45876     [::ffff:10.250.50.70]:49346            shows only 6052. That
conclusion holds — but the log evidence originally cited for it was worthless
and happened to agree.

What is actually still advertised is helpers.dashboard_advertise announcing
_esphomebuilder._tcp.local. at 6052, the auth-gated dashboard, independent of
remote-build. It leaks existence, address, dashboard id, Device Builder and
ESPHome versions and hostname: LAN version fingerprinting, not reachability
into the build subsystem. Left alone deliberately; both the compose comment
and the README now say so, including that an earlier revision claimed
otherwise.
2026-09-14 19:09:27 -07:00
vh 687c6999f3 fix(esphome): actually disable remote-build — two switches, only one closes the port
ha-dev found the WS API and tested the read half; this runs the write. But the
command they identified is the wrong half, which is worth recording because the
naming actively misleads.

  remote_build/set_offloader_settings {remote_builds_enabled: false}
      the OUTBOUND half — this dashboard sending builds to peers.
      Persists, reads back false, and leaves the receiver listening.

  remote_build/set_settings {enabled: false}
      the receiver-side master switch, per ReceiverController.set_settings's
      own docstring. Tears the listener down live, no restart needed.

Set both. Verified across a restart: 6055 absent, zero peer-link bind lines,
zero mDNS advertisements, both switches read back false. Persisted at
_remote_build.enabled in /config/.device-builder.json — which did not exist
until the flag was first changed, so 'no on-disk representation' was true only
of the default state.

ESPHOME_REMOTE_BUILD_HOST=127.0.0.1 is KEPT as a backstop rather than removed.
The off state now lives in one JSON file whose in-code default is enabled:True
(controllers/remote_build/_state.py) and whose module's stores soft-recover to
an empty model on a malformed blob rather than erroring — so a lost or corrupt
settings file silently re-enables remote-build. With the env var set, that
regression binds loopback instead of 0.0.0.0.

Also finishes deploy-stack.sh properly. This was patched three times in one
session because -a is -rlptgoD and a non-root identity cannot apply owner,
group, permissions OR times to a root-owned directory; each patch fixed one
letter and the next deploy failed on the next one, every time exiting 23 AFTER
a successful transfer. The rule is now written into the script: the deploy
syncs content, the conventions own metadata. --no-o --no-g --no-perms
--omit-dir-times. Verified: clean run, destination keeps 2775 root:docker with
setgid intact.
2026-09-14 19:05:11 -07:00
vh 8073a6aed9 fix(esphome): bind the remote-build peer-link to loopback; finish the rsync fix
ha-dev asked for the Device Builder 1.0.0 remote-build receiver to be turned
off: one instance, builds run locally, so the feature has no role, and it was
binding 0.0.0.0:6055 with mDNS advertisement on a privileged host-network
container that writes firmware to devices.

Reading the source first changed the framing. controllers/remote_build/
_state.py declares 'remote_builds_enabled: bool = True', so nobody enabled it
— it arrived on by default with the rewrite. And the flag has no on-disk
representation until it is changed: neither .device-builder.json nor
.device-builder-preferences.json carries it, and the only writer is the app's
own command API behind the UI. Setting it from a playbook would mean inventing
a schema for a model I have not read.

So this binds ESPHOME_REMOTE_BUILD_HOST=127.0.0.1 — a documented env var, no
entrypoint override — which removes the LAN reachability now and is verifiable
(ss reports 127.0.0.1:6055, was 0.0.0.0:6055). It is explicitly NOT the off
switch ha-dev asked for and the compose comment says so; the Settings toggle
is one UI click and the line can go once someone flips it.

Also completes yesterday's deploy-stack.sh fix, which was half a fix. --no-o
--no-g stopped rsync chgrp-ing a root:docker destination as a non-root
identity, but the very next deploy failed the same way one layer along —
'failed to set times on ...' — because a non-root identity cannot utime() a
root-owned directory either. Same exit 23 after a successful transfer. Added
--omit-dir-times. Fixing only the group half looked fixed until the next run,
which is the whole reason this is worth a line in the script's comment.
2026-09-14 18:55:54 -07:00
vh d1769ed114 feat(esphome): pin 2026.8.2, relocate config into backup coverage, rotate creds
ha-dev requested all three on esh-docker-vm (operator-authorized); the stack
had no canonical copy, so it is added to stacks/ rather than edited in place.

Pinned ghcr.io/esphome/esphome:2026.8.2 — it was bare, which is exactly how it
sat on 2025.8.2 for a year: docker pulled latest once at container creation
(2026-04-20, from a layer cached 2025-08-29) and never re-pulled. Every current
Everything Presence sensor failed config validation on that build. Verified
after: esphome version reports 2026.8.2 and the vendor's own Pro package now
validates clean (exit 0, 'Configuration is valid!'), which is the item that
unblocks the six waiting sensors.

Relocated /path/to/esphome/config (the upstream template placeholder, taken
literally by docker) to /opt/docker/conf/esphome, matching the mosquitto
pattern. Copied and checksum-verified all 5763 files before removing the
original, with a tarball kept at /root/pre-change-archive/.

Credentials moved off test/ChangeMe to the vaulted 32-char secret
(esh-docker-vm/esphome-dashboard), passed via a host-only .env so nothing
plaintext enters git.

Three things the job surfaced that were not in the request:

  The directory is 538 MB, not the 3 KB reported — .esphome/platformio is
  508 MB of PlatformIO toolchain and .esphome/build another 31 MB, both
  regenerable. Relocating as-asked would have inflated restic's /opt/docker
  source ~45x against its own ~12 MB budget, so both subtrees are excluded in
  /etc/restic/profiles.yaml. The 3 KB of actual config is now covered, which
  was the point.

  2026.8.2 logs a DEPRECATION for the bare USERNAME/PASSWORD env names and says
  they will stop working in a future release — a silent auth loss on some later
  bump, on a privileged host-network container that can flash any ESP device on
  the LAN. Switched to ESPHOME_USERNAME/ESPHOME_PASSWORD; the warning is gone.

  Device Builder 1.0.0 opens a NEW listener on 0.0.0.0:6055 (remote-build
  peer-link) that 2025.8.2 did not have.

Also fixes deploy-stack.sh: plain 'rsync -a' makes rsync chgrp the destination
as the deploy identity, which since the 2026-09-14 root:docker normalisation is
not root. It failed with 'Operation not permitted' and exit 23 AFTER
transferring content — a loud error on a deploy that had succeeded. --no-o
--no-g lets the setgid bit assign the group instead.
2026-09-14 18:47:54 -07:00
vh 68fa80f44d feat(scripts): add kb — direct search over the personal Worldtree KB
The Worldtree HTTP API cannot answer a question about the operator's notes.
/search there searches conversation MESSAGES, so a note that plainly exists
comes back as a clean empty result with no error attached. On 2026-09-14 a
search for 'shrimp' returned 0 hits; searching for 'the' and 'a' also returned
0, which is the only reason the empty result was read as an empty ACCOUNT
rather than an empty KB. kb reads the markdown tree directly instead:
deterministic, ~0.9s for 7,634 files, no tokens.

Two measurements shaped the design rather than being assumed:

  7,492 of 7,634 notes are INGESTED library material (4,155 fiction chapters,
  3,287 book sections, 50 academic papers) and only ~142 are hand-written.
  A flat relevance list buries the wanted note under a hundred chapters of
  Austen, so NOTES and LIBRARY are ranked and reported separately.

  Only 137 notes carry a frontmatter summary: key. Ingested notes use a
  '## Summary' body heading instead and some have neither, so the description
  falls back through all three shapes.

Two bugs caught by controls before shipping, both of which produced confident
wrong output rather than an error:

  Deriving the word list from argv meant a quoted
NOTES — 40 matches, showing 12

  Sous Vide Shrimp
    ATLAS/Cooking/Sous Vide/Sous Vide Shrimp.md
    Thawed shrimp should be sous vide at 135°F (57°C) for 30-40 minutes.

  Beef Stew
    ATLAS/Cooking/Sous Vide/Beef Stew.md
    This note outlines sous vide cooking temperatures and times for stew meat

  Pulled Pork
    ATLAS/Cooking/Sous Vide/Pulled Pork.md
    This note explains how to cook pulled pork sous vide: set the precision

  Brisket Sous Vide
    ATLAS/Cooking/Sous Vide/Brisket Sous Vide.md
    Here''s a concise summary:

  Ribs Sous Vide
    ATLAS/Cooking/Sous Vide/Ribs Sous Vide.md
    Here''s a concise summary:

  Derusting Solution
    ATLAS/Chemistry/Derusting Solution.md
    This note details how to create an enhanced rust removal soak by adding specific

  CNC with Raspberry Pi, USBIP & Camera
    clippings/CNC with Raspberry Pi, USBIP & Camera.md
    Here''s a concise summary of the note:

  SF - Victor
    ATLAS/Buy List/SF - Victor.md
    This order confirmation details 7 separate shipments totaling $2,533.45,

  Espresso Martini
    ATLAS/Cooking/Espresso Martini.md
    This note provides a recipe for a cocktail combining vodka, coffee liqueur,

  Brazilian Cheese Bread - Pão de Queijo
    ATLAS/Cooking/Brazilian Cheese Bread - Pão de Queijo.md
    This note provides a recipe for Brazilian cheese bread (#brazilian #food

  Congee Chao
    ATLAS/Cooking/Congee Chao.md
    This note provides the basic ratio (1 part rice to 7 parts water) for making

  White Bread
    ATLAS/Cooking/Baking/White Bread.md
    Here''s a concise summary:

LIBRARY (ingested books, fiction, papers) — 635 matches, showing 12

  Pride and Prejudice — CHAPTER XXI.
    fiction/rex390-pnp/ch23.md
    Following Mr. Collins’s proposal, Elizabeth encounters Wickham and learns that Jane has received a letter from Caroline Bingley announcing the party's immediate departure for London. While Jane interprets this move as definitive proof of Bingley’s indifference and permanent absence, Elizabeth remain

  Pride and Prejudice — CHAPTER XXIV.
    fiction/rex390-pnp/ch26.md
    Following Bingley’s letter confirming his settlement in London and growing intimacy with Miss Darcy, Elizabeth doubts the sincerity of his attachment to Jane, while Jane remains optimistic that external influences rather than design are responsible for their separation. The sisters debate these diff

  Pride and Prejudice — “On the Stairs.” CHAPTERXXVII.
    fiction/rex390-pnp/ch29.md
    Elizabeth reunites with Jane in London, where Mrs. Gardiner reveals that Jane suffers from periodic dejection despite her cheerful exterior, and the women debate whether Mr. Wickham’s pursuit of Miss King is motivated by mercenary or prudent reasons. Elizabeth then accepts an invitation from her aun

  Pride and Prejudice — CHAPTER XXXII.
    fiction/rex390-pnp/ch34.md
    Mr. Darcy’s frequent visits to Hunsford Parsonage spark speculation among the locals, particularly Mrs. Collins, who suspects he is in love with Elizabeth despite her own dismissal of the idea. Their initial interactions reveal a clash of perspectives on social convenience and local attachment, whil

  Pride and Prejudice — Chapter XLVI.
    fiction/rex390-pnp/ch48.md
    Following Lydia’s elopement with Wickham, Elizabeth Bennet informs Mr. Darcy of the scandal, reflecting that her earlier failure to reveal Wickham’s true character may have prevented the crisis and doubting their intent to marry due to their lack of funds. While Darcy offers sympathetic silence befo

  Pride and Prejudice — CHAPTER XIII
    fiction/rex390-pnp/ch15.md
    Mr. Bennet announces that Mr. Collins, the heir to Longbourn, will visit on November 18th, prompting mixed reactions from his family regarding the entail and Collins’s pompous letter. Upon arrival, the tall and stately visitor formally compliments Mrs. Bennet’s daughters and praises the estate, thou

  Pride and Prejudice — Covering a screen. CHAPTER VIII.
    fiction/rex390-pnp/ch10.md
    In Chapter VIII, Elizabeth endures the superficial sympathy and class-based mockery of the Bingley sisters while they criticize her muddy appearance and "low connections," even as Darcy defends her eyes and acknowledges her sisterly affection. The chapter highlights a clash of values when Darcy argu

  Pride and Prejudice — “Conjecturing as to the date.” CHAPTER XLIII.
    fiction/rex390-pnp/ch45.md
    Elizabeth’s visit to Pemberley fundamentally shifts her perception of Mr. Darcy, as the estate’s elegance and Mrs. Reynolds’ glowing testimony reveal his true character as a kind master and brother. This admiration deepens into gratitude upon seeing his portrait, softening her view of his past pride

  Pride and Prejudice — CHAPTER LVI.
    fiction/rex390-pnp/ch58.md
    Lady Catherine de Bourgh arrives at Longbourn to confront Elizabeth Bennet, demanding she promise never to accept Mr. Darcy’s hand based on claims of superior lineage and the scandal surrounding the Bennet family. She argues that Elizabeth’s inferior birth and lack of fortune constitute a disgracefu

  Pride and Prejudice — PRIDE. and PREJUDICE
    fiction/rex390-pnp/ch02.md
    Jane Austen’s *Pride and Prejudice* is presented as her most perfect work, distinguished by its structural regularity where every incident drives the plot toward a denouement strictly connected to earlier events. The novel’s supreme merit lies in its masterpieces of humor and character creation, whi

  Pride and Prejudice — A note for Miss Bennet. CHAPTER VII.
    fiction/rex390-pnp/ch09.md
    Mr. Bennet’s estate entailed on a distant relation leaves his daughters with limited financial security, yet the family’s attention is dominated by the arrival of the militia in Meryton rather than Mr. Bingley’s fortune. Mrs. Bennet successfully engineers Jane’s stay at Netherfield by sending her ou

  Pride and Prejudice — CHAPTER XVI.
    fiction/rex390-pnp/ch18.md
    In Chapter XVI, Mr. Collins and the Bennet cousins visit Meryton, where Mr. Wickham captivates the room and initiates a conversation with Elizabeth regarding Mr. Darcy’s character. Wickham claims that Darcy unjustly withheld a valuable living promised by his father, attributing this act to jealousy
  arrived as ONE element and became a single three-word pattern. The phrase
  never appears in a note titled 'Sous Vide Shrimp', so the tool reported
  'no match' for a note it had just found for the bare word 'shrimp'. The
  needle is now split on whitespace.

  Resolving the payload from dirname $0 broke the moment it was symlinked onto
  PATH. Now readlink -f.

cat refuses any path resolving outside the KB root — the remote half runs as
root because the volume is root-owned.
2026-09-14 18:17:21 -07:00
vh ce7b07f7af fix(fleet): strip sudo+docker from llmuser; record the pgrep over-attribution trap
Operator ruling: remove the groups and see what breaks. Nothing did.
ana-docker llmuser sudo+docker -> none; irv-ml1 llmuser sudo -> none (it was
never in docker there). 45 containers on ana-docker and 18 on irv-ml1 all
still running with zero unhealthy, and lora-training-worker stayed active.

Extended to irv-ml1 because it is the same account with the same defect and
gpasswd -a reverses it in one command; ana-docker was only the host the audit
happened to run against first.

The durable lesson is why it was safe, and it is a measurement trap rather
than a permissions one.  reported 19 processes on ana-docker
and 3 on irv-ml1, which reads as a busy service account. Nearly all of them
were CONTAINER processes whose in-image UID is 1001 and therefore collides
with llmuser on the host — /proc/<pid>/cgroup shows docker-*.scope. A
container's runtime UID is unrelated to host group membership, so the groups
were buying those workloads nothing. The single real host workload sets
User=/Group= explicitly through systemd, which does not consult the sudo group
either.

Recorded in the conventions doc so the next audit checks the cgroup before
concluding a host account is busy — otherwise a UID collision blocks a
cleanup that carries no risk.
2026-09-14 13:36:33 -07:00
vh abef67aacf feat(fleet): pin identity/group/path conventions + read-only audit playbook
Operator ratified four conventions on 2026-09-14. docs/pfi/fleet-conventions.md
is the pin; playbooks/audit-host-conventions.yaml is its instrument.

Pinned, verified free on all eight surveyed hosts (dynamically-allocated
system accounts cluster in 989-999 and descend, so 800-899 is safe):
  800-849  svc-* service accounts
  850      infra-ops uid+gid
  851      docker gid
  852-899  reserved for fleet-wide groups
  1000     the human account (vh)

Deliberately a pin for NEW hosts, not a migration mandate. The UID drift
(infra-ops is 1001/1002/1003/2001) is tolerable because there is no central
identity anywhere and a UID only has to agree where files cross hosts. They
do on /mnt/smithy — but that export is owned by Synology UIDs that resolve on
neither host and is 0777 throughout, so cross-host sharing works today
BECAUSE permissions are wide open. Aligning UIDs does not fix something
broken; it earns the right to drop that 777. Recorded as such rather than as
an urgent defect.

The audit playbook reports and never enforces, so a standard cannot quietly
become a flag day. Verified against nh3-dev, ana-docker, corviduo-dev and
nh3-extdev; it immediately surfaced two things the survey had missed —
llmuser holds sudo AND docker on ana-docker, and seven stacks on corviduo-dev
run from outside /opt/docker/compose (three under /home/vh, four under /opt,
including the three CI/CD-driven Worldtree deployments that must not be
moved).

Also supersedes the CLAUDE.md posture that made corviduo-dev the one host
excluded from fleet normalisation: the operator ruled all ops on it belong to
infra-ops. Its application layer stays CI/CD-owned.
2026-09-14 13:30:30 -07:00
vh 826a63b00c feat(fleet): normalize docker deploy trees to root:docker setgid
Operator ruling: root:docker, not a personal username and not a new admin
account. lkraven is one of three names he uses, so baking it into shared
infrastructure guarantees a stale owner later; a dedicated deploy account
buys nothing the existing docker group doesn't, since that group already
exists on every host holding exactly lkraven + infra-ops.

Applied to nh3-dev, nh3-docker, esh-docker-vm, irv-ml1, ana-docker. All
five now 2775 root:docker on /opt/docker and /opt/docker/compose. Clears
the 0777 on nh3-docker and ana-docker. 55 stack .env files normalized to
root:docker 0640, tightening 43 world-readable ones and opening 31 that
were readable by only one of the two deploy identities. No containers
bounced — inode metadata only, and .env is read at compose up.

Deliberately not a recursive chmod. Three acme.json files and an ssh
private key are mode 0600 and traefik/ssh refuse to start if that widens,
which would have been a delayed failure surfacing at the next restart
rather than now. Protection is both mode-based (0600/0400 untouched) and
name-based (acme.json, *.key, *.pem, *.pfx, id_*); modes are symbolic so
the 53 executable files in these trees keep their exec bit.

Two defects found and fixed mid-rollout. The name list was initially
reported but not enforced, so a .key already at 0644 on esh-docker-vm was
widened to 0664 — reverted, and the list is now enforced in the chgrp and
widening steps. And the exec-bit verify asserted every .sh is executable,
which was never true and false-FAILED irv-ml1; it now compares the
executable-file count against a recorded baseline.
2026-09-14 13:13:56 -07:00
vh ccc0df6870 fix(upgrade-docker-ce): retry the stack restart under sudo before reporting FAILED
The restart loop runs as the deploy identity, not root, and a stack .env is
allowed to be root-owned 0600. compose bails on the unreadable file before
doing anything, so the stack was reported FAILED while restart=unless-stopped
had already brought it back healthy — a false failure, which is worse than a
quiet one because it trains readers to skim the failure lines.

Retry under sudo -n before calling it a failure, and print compose's own
output either way. Verified on nh3-dev against beszel: plain attempt rc=1
'open /opt/docker/compose/beszel/.env: permission denied', sudo retry rc=0
'Container beszel-agent Started', container back to healthy. The happy path
is unchanged — the sudo attempt only fires after a failure.

Also record that tts-dev migrated talk from ~/talk into
/opt/docker/compose/talk, which removes the one stack on this host that was
invisible to anything walking that path.
2026-09-14 12:50:26 -07:00
vh 92a4114b90 feat(nh3-dev): migrate to docker-ce 29.8 + compose plugin; drop compose v1
Operator cleared the swap and ruled out a docker-compose v1 shim. Ran
playbooks/upgrade-docker-ce.yaml: docker.io 20.10.24 -> docker-ce 29.8.0,
docker-compose 1.29.2 -> compose plugin v5.5.1, containerd 1.6.20 ->
containerd.io 2.3.5, buildx v0.37.1 added. 12 changed, 0 failed, verify
4/4. talk and beszel-agent back healthy on their restart policies.

The pre-state was worse than 'old': there was no cli-plugins directory, so
'docker compose' was not a command and exited 0 on a help blurb — a silent
no-op that reads as a successful deploy.

Records two things the run surfaced. vastblue-u5-pg and its anonymous
volume were removed when the old daemon stopped; the playbook has no rm,
prune or purge and five other containers survived, so the cause is almost
certainly --rm, unprovable now that the record is gone. It was measured
beforehand as zero user tables in every database, so nothing was lost. And
the playbook's restart loop runs as infra-ops and cannot read a root-owned
0600 stack .env, so it false-FAILs that stack.

Also notes that nh3-dev is the only host where /opt/docker/compose is
root-owned; the other four are lkraven. Created /opt/docker/compose/talk
as lkraven so tts-dev can move talk out of ~/talk. Normalising the parent
is left to the operator.
2026-09-14 12:46:12 -07:00
vh 25a7d05f51 feat(nh3-dev): repoint Hermes at gen-large on the LiteLLM gateway
Operator ruled the repoint; Miranda moves off the paid z.ai Coding Plan
onto free local compute. model.default gen-large, provider custom,
base_url http://10.250.50.70:4000/v1. Verified by a real turn rather than
by config: hermes status reports gen-large / Custom endpoint and a
completion through /v1/chat/completions returns 660 tokens. The
openrouter/nous credit warnings cleared with it.

Records the landmine found on the way: CUSTOM_API_KEY and
HERMES_CUSTOM_API_KEY are inert for bare provider: custom — they bind only
a named custom_providers entry through its key_env. Without model.api_key
the request ships the placeholder no-key-required and LiteLLM 401s inside
the response body while hermes status still reports a healthy gen-large /
Custom endpoint, so status alone cannot verify this change.

Also notes that nh3-dev/hermes/api-server-key must not be rotated until
SVOS splits its HS256 signing key off the shared value.
2026-09-14 12:37:47 -07:00
vh a3e42282ff fix(nh3-dev): strip the Hermes api_server tool surface; flag the z.ai model resolution
Set platform_toolsets[api_server] = [] in ~/.hermes/config.yaml. Measured
back on /v1/toolsets: 28 rows before and after, enabled 14 -> 0, registered
tools 40 -> 0. The row count surviving matters — SVOS's _hermes_roster
derives its required-config line from the full report, so narrowing the
surface does not blind the diagnostic. terminal, code_execution, file,
browser and computer_use are now unregistered rather than merely
unreachable.

Separately, record an unresolved finding raised by svos-dev: model.default
names anthropic/claude-opus-4.6 and model.base_url names openrouter, but
provider: auto with only a zai credential resolves Miranda to GLM-5.3 on
the paid z.ai Coding Plan. Nothing under ~/.hermes references the LiteLLM
gateway. The operator believes Miranda runs on gen-large, which does exist
on LiteLLM. Not repointed — the premise is his to confirm.
2026-09-14 12:30:19 -07:00
vh d7e69ddaef docs(nh3-dev): record the Hermes Agent gateway sidecar on 127.0.0.1:8765
Stood up hermes-gateway.service (user systemd, vendor 'hermes gateway
install') for SVOS/Miranda, which cut over from Worldtree to Hermes on
2026-09-11 and aborts at boot without it. Bearer key vaulted as
nh3-dev/hermes/api-server-key.

Notes the wide default tool surface: with no roster config the gateway
registers all 28 toolsets on the api_server platform, terminal and
code_execution included. Loopback bind plus the key are the only
containment until SVOS installs its svos_miranda plugin and the
platform_toolsets / disabled_toolsets roster is applied.
2026-09-14 12:25:03 -07:00
vh cd941f7bf9 memory: snapshot — fv-ml1 rebalance (cyberprev→sec, gen-small A3B, all seats native 262K)
Pre-clear snapshot. Rewrote Current state / in-flight to the post-rebalance topology
(cyberprev is the sec seat, gen-small stood up, char/coder retuned, all generative
seats native 262K in-band, catalog+bench shipped) and added a Recent decisions index
entry + detail file 2026-09-14-fv-seat-rebalance-gen-small.md.

Also commits two previously-untracked durable artifacts (fv-to-ana-nat runbook + its
memory detail) so memory does not lag the work.

Archival: file is over the ~300-line soft cap (377) but 0 entries archived — the 4
age-eligible (>14d) entries all carry open deferred-work pointers (guarded), and all
other entries are <14 days old. Reported per the archival discipline.
2026-09-14 11:00:32 -07:00
vh dfa91a8eaf docs(fv-ml1): add curated LLM seat catalog (lineage/provenance/cards/speed) + bench script
Adds docs/pfi/llm-seat-catalog.md, the durable hand-curated record of what each
seat IS -- lineage, provenance, model-card facts, quantization, speculative
decoding, licenses, and measured warm tok/s + deep-prefill depth results with
their harness and date. It complements the auto-generated
fv-ml1-gpu-seat-inventory.md (live placement/KV/concurrency): the two split by
volatility, and the catalog defers to the inventory for any live number.

Adds scripts/seat-bench.py so the catalog's speed/depth numbers are reproducible
(warm decode tok/s, n=3, conc=1, median; deep prefill at ~0.97x max-model-len
with an allocator-log OOM scan). Serial by design -- concurrent deep prefills
would confound both OOM and tok/s.

Captures the 2026-09-14 measurements: all six generative seats prefill to ~255K
(coder ~16K) with zero OOM/CUBLAS/illegal-memory; warm decode 62.7-337.3 tok/s;
per-seat VRAM. seat-inventory.py now cross-links the catalog in its footer.
2026-09-14 10:45:31 -07:00
vh 05f3d3b2a3 feat(fv-ml1): add gen-small A3B seat; sec/gen/char to native 262K; coder reclaim; gateway
Full seat rebalance across GPU0/GPU1 (flash on GPU2 and empty GPU3 untouched),
operator-directed. Every target seat now serves native 262,144 context with
concurrency in the requested 1.2-2.5x band, verified from live boot logs:

  cyberprev (sec)   262144 @ 1.37x   depth-probed CLEAN to 259,722 tokens
  flash-next (gen)  262144 @ 1.31x   (untouched, already in band)
  gen-small (NEW)   262144 @ 2.56x   MTP k=3 measured 69.6% accept / 3.09 len
  char-rp           262144 @ 1.22x   (was 1.02x; util 0.40->0.52)
  char-rp-fast      262144 @ 2.04x   (util cap 0.30->0.24, pinned KV unchanged)

- gen-small: NEW seat, Qwen3.6-35B-A3B (3B active MoE), llmfan46 Heretic
  (MPOA) NVFP4 experts-only, already on disk at qwen36-35b-a3b-heretic-nvfp4.
  There is no general Qwen3.8 A3B (3.8 MoEs are Flash-Next and the 2.4T), so
  this is the 3.6 fallback the operator specified. GPU0, :8026, MTP k=3, coherent
  and MTP-verified before wiring. gen-small / gen-small-reasoning gateway aliases.

- coder: 8192 @ 13.75x -> 16384 @ 4.70x (util 0.06->0.055). Context doubled,
  waste cut. Not the exact 2-3x target: the 1.5B weight+overhead floor (~4.2 GiB)
  sits just under the util knob's resolution, so hitting <=3x reliably needs a
  --kv-cache-memory byte pin (compose change) rather than the util fraction.

- cyberprev raised 163840 -> 262144: depth-probed with non-repeating prompts to
  259,722 tokens, clean (no OOM, memory flat). Unlike mog-sec (same base arch,
  capped at 163840 for depth crashes), this checkpoint holds native depth.

- Gateway (operator calls): summarizer + classifier -> gen-small; new
  classifier-large -> gen-large (flash) for the accuracy tier; summarizer-large
  stays on flash. All verified end-to-end.

- GPU1 hit its ceiling raising char-rp; resolved by trimming char-rp-fast's
  reservation cap (its KV is pinned, so concurrency held at 2.04x) rather than
  moving a utility seat -- the shared GPU_ID on reward/embed/rerank made a
  single-seat move messier than the in-GPU rebalance.

Seat inventory regenerated from the live containers.
2026-09-14 10:25:10 -07:00
vh ff8dfed498 docs(fv-ml1): regenerate seat inventory — cyberprev in the sec seat, mog-sec gone
Live-read regeneration after promoting cyberprev into sec/sec-reasoning and
retiring mog-sec. GPU0 now carries cyberprev alone; sec/sec-reasoning aliases
resolve to :8025.
2026-09-14 09:11:07 -07:00
vh 207798de66 feat(litellm): promote cyberprev into the sec / sec-reasoning seats; retire mog-sec
Operator instruction: take down the existing sec seat (mog-sec) and promote
hotdogs (cyberprev) into the sec and sec-reasoning gateway seats.

- mog-sec container (vllm-mog-sec, :8019, fv-ml1 GPU0) taken down; ~48 GB freed
  on GPU0 (cyberprev, already co-resident there, is now the sole GPU0 chat seat).
- Gateway sec -> hosted_vllm/cyberprev-27b @ :8025; sec-reasoning ->
  hosted_vllm/cyberprev-27b-thinking @ :8025. sec/sec-reasoning are ROLE aliases,
  so this is a promotion, not silent substitution (samplers were already identical
  between the sec blocks and cyberprev, so only model+api_base changed).
- Removed the standalone cyberprev-27b / cyberprev-reasoning gateway aliases added
  in the prior commit -- now redundant with sec/sec-reasoning, and the fleet
  convention is a role alias on the gateway with the model's served-name only at
  the vLLM layer (as mog-sec had). cyberprev's vLLM served-names are unchanged.
- Verified e2e through the gateway: sec answers (nmap -sV version detection),
  sec-reasoning answers with a thinking split (127 reasoning tokens); retired
  mog-sec-27b now 400s.

Note: mog-sec was the fleet's only offense+defense/blue-team seat; the sec role
is now offense-only (cyberprev tool-calling). Operator-directed after reviewing
the capability comparison. mog-sec stack files retained for a future restore.
2026-09-14 07:49:40 -07:00
vh 3906c6842c docs: correct sec-seat lineage — M.O.G.-SEC/mog-sec is an offense+defense SFT finetune, not a persona-on-stock
The sentinel-r3 header and two memory notes described mog-sec (Blackfrost
M.O.G.-SEC / Qwentium) as 'a persona system prompt on stock weights'. Its card
is explicit that it is NOT: base_model_relation: finetune on Qwen/Qwen3.8-27B,
a refusal-free offense+defense cybersecurity SFT with YaRN 1M context ('not a
system-prompt sticker on a stock Qwen'). So all three sec-seat candidates are
Qwen3.8-27B SFT finetunes and differ in training focus, not in kind:
mog-sec = broad offense+defense SFT; sentinel-r3 = pentest agent-trajectory SFT;
cyberprev = cyber tool-calling LoRA SFT on an abliterated base.
2026-09-14 07:31:23 -07:00
vh 196416f3da docs(cyberprev-seat): correct model lineage — it is a cyber SFT finetune, not an abliteration
Earlier commits and the compose header called cyberprev "an abliteration of
Qwen3.8-27B (refusal-direction weight edit, no finetune)". That was wrong. Per
the hotdogs model card (base_model_relation: finetune), cyberprev is an
offensive-security agentic tool-calling LoRA, merged at scale 1.0, trained on
hotdogs/cyber-sft-agent-qwen38 (8,400 rows across 22 pentest tools: nmap,
sqlmap, metasploit, hydra, crackmapexec, ...). The abliteration is INHERITED
from its base (hotdogs/Qwen3.8-27B-abliterated); the new capability in this
repo is the cyber SFT itself.

So the sec-seat lineage is: mog-sec = persona on stock weights; sentinel-r3 =
pentest-trajectory SFT on stock weights; cyberprev = cyber tool-calling SFT on
an abliterated base. All three are SFT-or-prompt variants; the earlier framing
of cyberprev as "not a finetune" was backwards.

Corrects the compose header lineage block, the homepage dashboard description,
and the gateway alias comment. No functional change; the running seat and its
weights are unchanged (label refreshes on next container recreate).
2026-09-14 07:28:26 -07:00
vh b94d173887 fix(cyberprev-seat): serve coherent v2 quant from name-repaired source; wire gateway
The first cyberprev quant served pure gibberish despite passing every structural
check. Root cause: the hotdogs/Qwen3.8-27B-abliterated-cyber-preview checkpoint
ships broken -- 850 of 1199 tensors (the whole transformer body) carry a TRIPLED
`language_model.` prefix, confirmed present in the upstream HF index (an unsloth
export bug, not our download). transformers silently loaded the unmapped tensors
as random-init, the pipeline quantized noise, and structural verification passed
because it inspects the output config, never that input names mapped. A plain
greedy coherence smoke caught it; nothing structural could.

Fix: rewrite tensor names against a known-good reference of the same architecture
(qwen38-27b-uncensored-bf16), verified the repaired name-set == reference name-set
exactly (1199 tensors, 0 collisions), and re-quantized from the corrected source
(cyberprev-bf16-fixed). v2 is coherence-verified (spec off AND live with dflash):
Paris/Berlin/Rome, correct arithmetic precedence, primes, clean cyber-domain chat
with a proper thinking split. dflash k=7 measured at 2.77 mean acceptance length.

Seat serves cyberprev-27b / cyberprev-27b-thinking on :8025/GPU0 with dflash k=7,
displacing the retired sentinel-r3. Gateway: removed the retired sentinel-r3 /
sentinel-r3-reasoning aliases and added cyberprev-27b / cyberprev-reasoning -- NOT
repointed, since serving cyberprev weights under sentinel's name is silent
substitution. Verified end-to-end through the gateway; sentinel-r3 now 400s.

Playbook gains a superseded-claims row: structural verification does not imply a
good quant; a coherence smoke is the load-bearing gate, and third-party sources
must have their tensor names diffed against a reference before quantizing.

Broken v1 quant dir removed.
2026-09-14 04:28:59 -07:00
vh 1418edb03e feat(cyberprev-seat): mixed-NVFP4 quant of the abliterated cyber-preview, displacing sentinel-r3
Third sec-seat candidate: hotdogs/Qwen3.8-27B-abliterated-cyber-preview, an
abliteration (refusal-direction weight edit) of Qwen3.8-27B aimed at the
cyber-offense refusal surface -- distinct from mog-sec (persona on stock
weights) and sentinel-r3 (SFT finetune). Operator instruction: quant it, take
sentinel down, serve it with mtp or dflash.

Quantized to the house mixed recipe via services/gen-seat-mixed-quant/ (NVFP4
W4A4 on MLP layers 0-55 + FP8 W8A8 on attn/linear_attn/lm_head/MLP 56-63, FP8
KV). The prior attempt (2026-09-11/14) died with "Cannot determine
num_attention_heads" because it ran from a bare .venv whose newer
compressed-tensors reads that field at top level; quant_mixed_nvfp4.py already
promotes text_config attention fields for exactly this reason, and the run
through the canonical vLLM-image + llmcompressor 0.13.0 / compressed-tensors
0.18.0 path (versions recorded from the container) completed clean.

post_quant.py did its job: grafted the 15 MTP tensors verbatim (BF16), and
re-injected re:^mtp.* into the ignore list after llm-compressor pruned it for
matching no module at quant time -- without which vLLM loads the grafted head
uninitialised and speculative decoding runs at 0% acceptance. It also caught a
missing preprocessor_config.json (absent from the abliterated source AND its
hotdogs upstream); restored from Qwen/Qwen3.8-27B, verified byte-identical to
the working sentinel-r3 build, so the vision tower preprocesses.

Verified from the tensors, not the config: NVFP4 covers MLP 0-55, FP8 covers
56-63, no overlap, 168 weight_packed tensors (56x3), 15 BF16 MTP, 333 BF16
vision. 51.0 GiB bf16 -> 21.0 GiB.

Served under its own name (cyberprev-27b / -thinking), NOT sentinel-r3 --
serving different weights under a retired name is silent substitution. Takes
over :8025 and GPU 0 (co-resident with mog-sec). dflash k=7 is the default,
carried from the sentinel measurement, but is re-measured against MTP on this
ABLITERATED body before cutover, since abliteration is exactly what can desync
an MTP head. Drafter (qwen38-27b-dflash2-drafter) shared with mog-sec.

Context capped at 163840 not native 262K, inherited from mog-sec's hard-won
depth lesson; raise only after a non-repeating deep-prefill probe on this
checkpoint.
2026-09-14 03:32:09 -07:00
vh 4954cf6756 test(flash-next-seat): depth-probe orca to 258K clean; record a blind instrument
Bisected context depth on the orcarouter checkpoint with non-repeating prompts
(unique random hex per probe, so prefix caching cannot short-circuit the
prefill). Six depths from 31,978 to 258,517 tokens, all served.

The load-bearing evidence is the engine allocator log: zero OOM, CUBLAS, or
illegal-memory entries across the run. That is the same detector that caught
the dealignai near-miss at 155K on the previous checkpoint, where it did fire.
The probe also ran under real concurrent operator load, making it a stricter
test than a solo run rather than a weaker one.

Positive control passed: a mis-sized first attempt produced a ~265K-token
prompt and got a clean 400 naming the limit instead of killing the engine, so
the probe could detect the failure mode it was looking for. Calibration for
re-runs: random hex words tokenize at 7.9 tokens/word here.

vLLM #54919 (long prefill starving decode for 3-7 minutes) did not reproduce:
258K prefilled in 28.9 s, roughly 8,900 tok/s, scaling near-linearly from 32K.

Records that the probe's memory-headroom half was BLIND and must not be reused.
It reported an identical 95,460 MiB used / 2,427 MiB free on every row across an
8x range of depths, which is the tell. Two causes: --kv-cache-memory pins the
pool and the engine logs "skipped memory profiling", so GPU usage is flat with
respect to depth; and the actual risk is a transient activation spike during
prefill, which before/after nvidia-smi bracketing structurally cannot observe.
Peak-activation headroom therefore remains unmeasured; the pass/fail result
rests on the allocator log alone.

Also qualifies the earlier 167.5 tok/s decode figure as a possibly-contended
lower bound, and records the operator's independent 140 tok/s average measured
in real use while this probe was loading the same card.
2026-09-14 03:02:55 -07:00