Commit Graph

377 Commits

Author SHA1 Message Date
vh b990951d80 chore(vllm): retire LFM2.5-2.6B permanently; audit finds nevermore on the harmful reranker
Operator directive: lfm2.5-2.6b goes down permanently.

  - stacks/vllm/compose.yaml   vllm-lfm25 service removed (replaced by a
                               tombstone comment), pushed live to ana-ml2
  - ana-ml2                    container docker rm -f'd, 8,721 MiB freed on GPU1
                               (95,388 -> 86,667 of 97,887)
  - litellm config             lfm2.5-2.6b alias deleted, live + canonical,
                               28 -> 27 models

It was an EVAL-ONLY bake-off seat against granite-4.1-8b that never received
the operator ruling it was pending; the comparator was retired from the roster
on 2026-08-15; it was deliberately never wired into any default or fallback
routing chain; and spend logs show 0 calls in the 4-day window to 2026-08-21.
Weights stay in the shared HF cache -- nothing deleted from disk.

The gateway restart that makes the alias deletion take effect is HELD so it can
batch with a pending reranker change. Until then the name is still routable
in-memory and will error against a dead backend.

Auditing the three reranker seats while answering "why do we have three" turned
up a real problem. The design is one production, one rollback, one fallback --
but the traffic is backwards:

  :8013 A3 bge-v2-m3      PRODUCTION, backs `reranker`     0 calls / 4 days
  :8002 Qwen3-Reranker    RETIRED incumbent, rollback only 7 calls, 12-hourly
  :8014 A4 gte-modernbert "fallback"                       no alias at all

nevermore is hard-wired to the incumbent by name (NEVERMORE_RERANK_MODEL=
qwen3-reranker), so the R43 cutover never moved it -- the cutover repointed the
`reranker` alias and correctly left `qwen3-reranker` naming the Qwen model.
Brokkr R43 measured that model harming 80/90 fleet queries, so nevermore's
twice-daily rerank pass is likely degrading its own briefing.

Fix is one line in nevermore's .env plus a nevermore restart, and it must land
before :8002 is retired. Recorded in persistent-memory with the A4 alias also
noted as absent (global CLAUDE.md names reranker-a4-gte-modernbert; it does not
exist).
2026-08-20 23:23:22 -07:00
vh e3ce713f7f feat(gen-seat): cut over to Heretic-300 — 7/7 aliases, vision intact, MTP 59.7%
Live GEN_MODEL is now qwen38-27b-coldfusion-h300-nvfp4-mixed (ana-ml2 GPU0
:8015). Served-name left unchanged so all 7 LiteLLM aliases route without a
gateway edit.

Verification:
  KV pool            401,550 tok / 1.53x   (baseline 403k / 1.54x)
  LiteLLM aliases    7/7 green
  vision             3/3 shapes, colour+form+position correct
  MTP acceptance     59.7% median @ 118.37 tok/s
  quality gens       4/4 correct
  abliteration       4/4 compliance
  PPL                NOT measured (see below)

The roadmap predicted ~47% acceptance for a pristine MTP graft versus L35's
59.1% in-band edit. Measured 59.7% on the same harness: there is no acceptance
penalty, which removes the throughput argument for reimplementing MPOA.

A single long-prose generation read 47.5% off the same counters -- below the
8-run minimum of 49.0% -- and would have "confirmed" the prediction by
coincidence. Acceptance must be read from quickbench.py, never one sample.

PPL is blocked on VRAM, not on the model: eval_quality.py aborts with
"prompt_logprobs look uniform" under --speculative-config, and the probe-seat
workaround needs ~22 GB while both cards sit at ~96% committed.

Also normalizes the quant dir from root:0600 to llmuser:llmuser 0664 to match
every other model dir, and records that config.json sha256 is byte-identical
across the h300 and L35 quants and is therefore useless for confirming which
weights are mounted (mtime and a head-hash are the discriminating views).

Rollback is one line to .env.bak-pre-h300-20260820.
2026-08-20 23:13:15 -07:00
vh 407ca017ae memory: snapshot — Heretic-300 built, quantized and verified; gen-seat cutover is the next step
8/100 refusals at KL 0.0136, hand-verified coherent, beating the absolute-heresy
bar 3.6x. NVFP4 quant complete: 21 GB, 1968 tensors, MTP head grafted back after
PR #317 dropped it, and re:^mtp.* re-injected into quantization_config.ignore
after llm-compressor pruned it. Self-harm guardrail is gone on this build and is
the operator's own next work item; the four-dwarf panel is stood down.
2026-08-20 22:54:32 -07:00
vh f90a5025de feat(coldfusion-abliteration): Heretic-300 — 8/100 refusals at KL 0.0136, beats the heresy bar 3.6x
Ran Heretic v1.4.0's 300-trial TPE search on Cold-Fusion. Best trial scores
8/100 refusals at KL 0.0136 against a 98/100 base, versus absolute-heresy at
29/100 and our hand-tuned Robinson L35 at 72/100 / KL 0.0116 — i.e. 64 fewer
refusals for the same damage. Hand-verified coherent: correct arithmetic with
shown working, clean code, 66-167 word prose across nine probes.

Durable findings:

- direction_scope=0 (single shared direction) is decisive on this merged base:
  n=129, best 8/100. Per-layer directions n=131 never beat 52/100 despite a
  better median. Points against the multi-direction intuition for a diffuse
  direction (our two-template |cos| is 0.62 vs Robinson's 0.99 on stock).
- Aggression is not the lever. r(KL, refusals) = -0.561 over 261 trials; the
  KL<0.02 band contains both the worst results (median 87/100) and the single
  best. A KL 0.3554 trial scored worse than one at 0.0193.
- PR #317 confirmed: Heretic silently drops the MTP head on save. Source 1199
  tensors -> export 1184, all 15 mtp.* gone, vision 333/333 intact, exit 0, no
  warning. This is also why absolute-heresy ships a byte-identical MTP head —
  a bug, not a design choice. Always diff tensor keys after a Heretic export.
- Heretic's recovered direction carries 6.18% of its energy in sink dim 3994,
  versus 0.094% for our L35 and 1.97% for the L39 we rejected as brick-inducing.
  It survives that only because of magnitude-preserving ablation
  (row_normalization=FULL); our plain projection has no such protection, so the
  sink screen correctly refused the in-band MTP graft. Same direction, different
  operation. MPOA is the prerequisite for in-band MTP on a Heretic trunk.
- Heretic's edit is recoverable from weights: delta is rank-1 (s2/s1 ~ 0.010),
  SVD gives the direction, norms give per-layer weights (1.08 -> 1.34, i.e.
  over-projection). Cross-layer |cos| agreement 0.9903 independently confirms
  the single-direction result.

New tooling in services/coldfusion-abliteration/:
  kl_divergence.py    first-token KL, class-split, zero noise floor
  catatonia_gate.py   12 probes x 220 tokens, prints every completion
  heretic_export.py   PTY driver; selects by measured value, never by menu
                      position — Heretic's resume prompt puts "delete the
                      checkpoint and all results" one arrow-key from the target
  graft_mtp.py        recovers the trunk direction by SVD; --pristine for the
                      safe path when the sink screen refuses

Also adds quant playbook 3.13: the NVFP4 recipe sets observer="imatrix_mse" but
llm-compressor has always silently fallen back to uniform MSE for want of
importance data — on this build and on the incumbent. Existing A/B comparisons
stay valid since every build shares the fallback. Parked as id 42.

Guardrail note: this build has lost the self-harm guardrail that the Robinson
L35 build retained. Restoration is the operator's own work item.
2026-08-20 22:51:56 -07:00
vh 78484ac87d memory: GPU0 seat boot order is part of the state — restore rule + KV-pool baselines
vLLM sizes --gpu-memory-utilization against total VRAM but gates startup on free
VRAM, so the GPU0 pair coexists only in its original boot order. Records the
restore sequence (meromero to healthy first, then gen), the observed-not-slept
rule, and the KV-pool baselines to verify a restore against — nvidia-smi used-MiB
is the wrong check, it swings ~7 GB on allocator slack at identical capacity.
2026-08-20 13:09:21 -07:00
vh a9d73dad41 fix(coldfusion-abliteration): GPU0 seat restore order is load-bearing — correct the claim and the runbook
Restoring the two GPU0 seats with `start meromero; sleep 10; start gen` put
meromero into a 7-restart crash-loop:

  ValueError: Free memory on device cuda:0 (35.3/94.97 GiB) on startup is less
  than desired GPU memory utilization (0.52, 49.38 GiB).

The previous commit's README claimed restore order "is not actually load-bearing"
on the grounds that both seats pass --gpu-memory-utilization as a fraction of
total VRAM. That is half right and the wrong half mattered: the fraction sets the
target, but vLLM gates startup on FREE VRAM and refuses to start unless the whole
target is available. GPU0 runs at ~96.4/97.9 GB with roughly 0.4 GiB of slack, so
the seats coexist only in the order they were originally brought up, and meromero
is the one that does not fit in the remainder. The pre-existing auto-memory note
("gen takes a fraction of free VRAM at startup and will starve meromero") was
pointing at the real effect.

Also: "first" means healthy, not ten seconds earlier. A sleep 10 against a
two-to-three minute weight load is simultaneity, not ordering — gate on observed
state.

Recovery applied: stop gen, wait for meromero healthy, start gen. Verified
against the pre-window baseline rather than against "both green":

  gen KV       14.36 GiB / 403,065 tok / 1.54x  ->  14.34 GiB / 401,550 tok / 1.53x
  meromero KV  542,202 tok                      ->  542,202 tok
  RestartCount 0 on both; summarizer smoke-tested through LiteLLM

Note for the next reader: raw nvidia-smi used-MiB is the wrong check here. It
reads 89,503 now vs 96,376 before, which looks like a 6.9 GB regression and is
allocator slack — serving capacity is unchanged. The anomalous boots were the
high ones (34.95 GiB KV), where gen came up on an empty card mid-window.
2026-08-20 13:08:56 -07:00
vh 1b3fb270e7 feat(coldfusion-abliteration): first-token KL measured — 28.4x selectivity, harmless median 0.0211
Adds `kl_divergence.py`: first-token KL(stock || abliterated) over the full
248,320-token vocabulary, bf16 vs bf16, scored separately for held-out harmless
and reserved-harmful prompts.

Result (L35, 256 harmless / 104 harmful, answer mode):

  harmless  median 0.0211  mean 0.0364  top-1 agreement 89.8%
  harmful   median 0.5996  mean 0.6992  top-1 agreement 55.8%
  selectivity 28.4x (72.8x in think mode)

Self-KL noise floor is exactly 0.0, and all 720 per-prompt values are
bit-identical between a single-process and a two-process run, so the figures are
signal rather than bf16 jitter. Reverse KL on harmful/answer is 1.43 vs forward
0.70 — the mass-where-stock-had-none asymmetry expected of a refusal-direction
removal. Against the Heretic reference figures (0.1191 prior seat, 0.0759 the
live absolute-heresy seat) this is materially gentler, but those are the other
tool's optimizer output on a different base with its own harmless set and
template — order-of-magnitude, not head-to-head. KL remains a fidelity number;
the viability gate is still MTP acceptance (59.1%).

Method notes:
- Prompt classes are reported separately by design. A single averaged KL over a
  mixed corpus is close to meaningless, since the metric is meant to be large on
  harmful prompts and small on benign ones; the ratio carries the information.
- The harmless evaluation set is drawn from the alpaca pool minus calibration's
  own draw, reconstructed by replaying that draw rather than remembered, and
  asserted disjoint on text. The harmful set is the reserved test split.
- `render` is imported from abliterate.py rather than copied, so the measurement
  cannot drift from the rendering the direction was captured against.
- Batch size 1 with logits_to_keep=1: no padding semantics, ~0.6 MB of logits.

Three corrections to the runbook, each of which cost time:
- "bf16 is 50 GB, only gen must go" was 50.10 GiB mislabelled. Text-only weights
  are 51,300 MiB; freeing either GPU0 seat alone leaves ~50,933 MiB. Both must
  stop. VRAM is now sized from the safetensors headers at run time.
- A 27B model cannot be released in-process: `del` + gc + empty_cache left free
  VRAM at 45,287 MiB, and so did confining the model to an inner frame that
  exits. Only process exit returned the card (96,689 MiB). The first run
  completed only because the allocator hit OOM, collected, and retried. Each
  model now gets its own process, handing log-probs to disk between stages.
- The residency gate read hf_device_map, which transformers leaves empty when the
  model fits on one device — it reported "(unsharded)" whether or not anything
  was wrong, so it could never fail. It now reads parameter devices directly.

Model-agnostic lessons promoted to the quant playbook (new 3.12).
2026-08-20 13:00:39 -07:00
vh 8c354a0e79 memory: snapshot — Cold-Fusion thesis PROVEN (MTP 59.1% > incumbent 47%)
Flip the Cold-Fusion in-flight line to thesis-proven: L35 quantized to mixed
NVFP4, MTP acceptance 59.1% median beats the incumbent Heretic graft's ~47%,
abliteration survives quant. Not cut over — cutover is a separate operator
decision. Records the two env foot-guns hardened (quant venv config-delegation
drift; single-file no-index quant needs a header-built index).
2026-08-20 10:19:09 -07:00
vh c55b1390b7 memory: snapshot — Cold-Fusion abliteration LANDED at layer 35
Flip the in-flight status from 'capture done, calibration expansion next' to
'landed, works'. New detail file captures the three corrected diagnoses (layer-
selection metric, sharding/allocator misdiagnosis, corpus-size falsified) and the
verify/quant work still owed. Supersedes the -capture.md detail file's framing.
2026-08-20 08:47:47 -07:00
vh 530f1452e8 memory: snapshot — Cold-Fusion abliteration in flight, capture done
Captures the session's real work as the in-flight focus: abliterating
DavidAU Cold-Fusion with the Robinson formula. fp32 capture succeeded
(finite direction, layer 22, sink-clean) but two-template agreement is
0.59 vs Robinson's 0.99 — calibration-set expansion is the next step.

New detail file records the full saga including the transformers/DeltaNet
bf16-NaN fight (fp32 fix, the causal-conv1d kernel gap, the seat-restart
VRAM-greed gotcha). Supersedes the earlier "watch for DavidAU's heretic
build" posture — we abliterate it ourselves.

Auto-archived 4 closed entries (Recent decisions: Booth-3-features 08-05,
worldtree-sdk 07-31; Tried and abandoned: containerd-race 08-03,
mv-rename 08-02) to archival-memory.md; the rest of the over-cap entries
are held back by the <14-day and open-deferred guards. Index 331 -> 327.
2026-08-20 07:36:15 -07:00
vh 40257247b0 memory: IPv6 plan settled — endpoints not internal numbering; ESH has a /56
Corrects three claims that had been standing in the fleet IPv6 notes and that
sent a three-arm research effort after a problem that did not exist:

- ESH was recorded as having no IPv6. It has a /56 delegated and a routable
  WAN GUA -- substantially more prefix than NH3's single /64.
- The mesh was recorded as broken by ESH's CGNAT. It is not and was not down;
  ESH is outbound and working. CGNAT on v4 alongside generous v6 is just the
  modern ISP pattern, not an outage.
- IPv6 was framed as the escape hatch for that outage. The actual plan is that
  IPv6 carries tunnel ENDPOINTS for Site Magic and WireGuard, and LANs are not
  numbered in v6 at all.

NH3 internal v6 was brought up on the delegated /64 and verified end-to-end
(global GUA on nh3-docker, zero loss to Cloudflare and Google v6, un-NATed
source address seen from outside), then reverted on operator direction: one
/64 lights exactly one VLAN and that is not worth the split-brain.

The AT&T prefix research is kept as reference rather than deleted -- the /60
is real but undelegatable, the living multi-prefix mechanism is multiple
IA_PD in one solicit rather than the VRRP/multi-MAC recipe we were handed,
and the UDM SE can express neither. That is the answer if NH3 LAN-side v6
ever earns a maintenance window; it is not on any critical path now.
2026-08-19 10:44:56 -07:00
vh b92097688c fix(esh-pve): hardware watchdog, and close the single-resolver DNS SPOF
esh-pve hard-froze at 03:34 on 2026-08-19 and stayed frozen ~4.5 hours
until a manual power cycle. No panic, no OOM, no MCE — the journal stops
mid-operation. The whole ESH site lost DNS with it, because esh-userland
(VLAN 10, the PVC SSID and wired userland LAN) was handed exactly one
resolver: 10.0.50.45, AdGuard on esh-docker-vm, on a different VLAN, with
no secondary. Internet and routing were healthy throughout.

Two fixes.

1. DNS: 10.0.10.1 (the gateway, verified resolving) added as secondary on
   esh-userland via the UDM Classic API. Note this is degradation cover,
   not clean failover — clients that query resolvers in parallel will
   bypass AdGuard for a share of lookups.

2. Watchdog: softdog -> iTCO_wdt under systemd (RuntimeWatchdogSec=60),
   watchdog-mux masked. The box looked watchdog-protected and was not: a
   software watchdog cannot fire when the kernel it lives in is wedged,
   and watchdog-mux only pets the device while an HA client is connected,
   which never happens on a cluster with no HA resources. Firmware does
   not block the TCO timer here, checked before committing to it.

Also pins VM 102 off (onboot: 0). It starts with full GPU passthrough and
vfio-pci enabling that device is the last thing the kernel logged, 39
minutes before the freeze. The other suspect is the kernel itself: the
host ran 4.5 months on 6.8.12-16, took 6.8.12-42 in an apt batch on
08-18, and died 20 hours into the first boot on it. 6.8.12-16 is still
installed as the rollback.

The playbook is idempotent — a second run skips all six steps and passes
all six verifies. The watchdog is confirmed armed (identity=iTCO_wdt,
state=active, held by PID 1) but has NOT been observed firing; proving
that needs a deliberate wedge.

Memory also corrects two wrong mid-incident calls: the mgmt VLAN is
routed over the site tunnel and is not firewalled off — both symptoms
were the dead host generating ICMP unreachables.
2026-08-19 09:05:52 -07:00
vh e6907819b0 feat(waterland-studio): deploy b72425b — all three upstream findings fixed
One update.sh run on irv-ml1 carried both open upstream PRs, per the
operator's green-light on the job-store fix:

- #5 (464dfc2) declares cupy-cuda12x[ctk] on the gpu extra and takes uv
  out of the render path (sys.executable -m waterland.cli), retiring the
  runtime prune trap at the source.
- #6 (b72425b) rehydrates the job index from the data volume at startup,
  fixing the unbounded store growth reported from this side.

Verified after the update rather than assumed: healthy on backend cupy;
/api/jobs went 1 -> 16 against 16 directories on disk, so API and volume
agree for the first time; nothing wrongly reclaimed, correct since 16 is
under RETAIN=40 and adoption only makes them visible; a real 256^2 plate
render completes warm, so the kernel-cache volume survived the image swap.
A subsequent render took both counts to 17.

The image keeps its explicit [ctk] install and UV_NO_SYNC/UV_OFFLINE pins
even though both are now redundant. The header requirement is a property
of this slim base, not of the upstream extra, and the cost is measured
rather than assumed: uv sync satisfies it first, so the line reports
"Audited 1 package" and adds 0.3s to the build. The env pins are now
cheap defence-in-depth against any future path that re-enters uv.

Docs corrected in place: the README's upstream-finding section is now a
resolved-finding record, and the two "bounded ~500 MB" claims say which
commit made that bound hold across restarts rather than only within a
process. Comment-side changes pushed to the live compose dir; no restart
was needed for them.
2026-08-19 01:39:13 -07:00
vh a2b6bf409e memory: waterland-studio upstream fixes landed, container stays pinned
waterland-dev merged PR #5 (main now 464dfc2), fixing both landmines at
source: the gpu extra declares cupy-cuda12x[ctk], and the renderer spawns
sys.executable -m waterland.cli instead of re-entering uv mid-job.

The running container deliberately stays on 8025366. Its own [ctk] install
and UV_NO_SYNC/UV_OFFLINE pins already neutralise both defects, so a rebuild
would buy reliability that is already present — and the project is in
wind-down. Both guards are kept rather than dropped: the header requirement
is a property of this slim image, not of the upstream extra, and the uv pins
are now cheap defence-in-depth against any future path that re-enters uv.

Also records waterland-dev's confirmation of the unbounded job-store growth
and the operator's green-light on their startup-rehydrate fix. That PR
merging is the rebuild trigger: one update.sh run lands the rehydrate and
464dfc2 together. Marks the inbox drained.
2026-08-19 01:26:32 -07:00
vh bc3aada73a memory: snapshot — .internal DNS live, waterland containerised, homepage themed
Captures a long infra session: fleet *.internal DNS (git-sourced, 42 names,
three resolvers including a new colo one), waterland studio containerised on
irv-ml1, Homepage cleaned up and themed with Australis Skyfall over an
Arbo-generated background, and four unmanaged stacks adopted into stacks/.

Four detail files added. Auto-archived 4 entries to archival-memory.md
(Recent decisions 2, Tried and abandoned 2); 5 held back by the open-deferred
guard rather than moved.

Also records three operator-owned open items: the colo DNS repoint, the
static-v6 convention, and the deliberately belayed AI-tab Dormant regrouping.
2026-08-19 01:20:53 -07:00
vh 084ad924f0 memory: snapshot — ESH fiber live, esh-pve-nas migrated+patched, v6 mapped
Session captured: ESH cut over to Cityside 2Gb symmetric fiber and was
fully provisioned on it; esh-pve-nas completed its ZFS-root migration off
the USB DOM and took its 225-package security backlog with the reboot
deferred; ESH<->colo IPsec was rebuilt as a dialup tunnel with NAT-T after
CGNAT broke the statically-pinned one; IPv6 was mapped across all three
sites.

Auto-archival fired at the soft cap: 7 entries moved to
archival-memory.md (Recent decisions 3, Tried and abandoned 4), all
verified-complete arcs, with two detail files moved and removed. The
remaining pre-Aug-05 entries were held back by the open-deferred-work
guard, so the index stays slightly over cap at 313 lines rather than
losing a live pointer.

Also records the one self-inflicted outage of the session (missing
--make-rslave on a chroot rbind) and that three long-dead things
surfaced incidentally: pvestatd down 82 days, a vzdump hung 126 days,
and a VM sitting in prelaunch for four months.
2026-08-18 16:36:13 -07:00
vh 34d3f42bf5 docs: park the BGW210 v6 work pending the Device Access Code
Operator will retrieve the BGW210 Device Access Code from the NH3 office
and vault it, after which the IPv6 LAN settings page can be driven
remotely.

Parked on the henge as reclaim-nh3-s-7-unclaimed-ipv6-64s-from-the with
everything needed to resume cold: the verified facts about the /60 split
and the seven unclaimed prefixes, why AT&T cannot fix it, the exact page
to start at, what to look for in priority order, the other settings
pages behind the same login, and the wpa_supplicant fallback with its
warning about modifying NH3's only uplink.

Suggested vault path unifi/bgw210-nh3-device-access-code, matching the
existing unifi/* credentials.
2026-08-18 16:29:39 -07:00
vh 57e080319b docs: NH3 v6 root cause is the BGW210, and seven /64s are unclaimed
Operator suggested checking the BGW on its 192.x management address,
which turned out to give the whole picture from unauthenticated status
pages.

The CPE is a BGW210-700 on firmware 4.28.7 at 192.168.1.254. AT&T does
hand it a /60 -- c110 through c11f. The BGW keeps c110-c117 for itself
and re-delegates up to eight individual /64s on c118-c11f, top-down. Our
UDM holds c11f, delegation number eight.

So the earlier conclusion that AT&T only grants a /64 was right about
the symptom and wrong about the cause. Seven further /64s are available
and simply never solicited, because UniFi exposes a single
wan_dhcpv6_pd_size integer with no field for how many prefixes to
request. The documented workaround is repeated -P flags to dhclient,
which the UniFi UI cannot express.

This also settles that an AT&T ticket cannot help: the rationing is CPE
firmware behaviour, not provisioning. Records the two real options --
accept one /64, or bypass the BGW entirely with wpa_supplicant EAP-TLS
on the UDM to negotiate the full /60 -- with the warning that the latter
modifies NH3's only uplink and needs a planned window.
2026-08-18 16:27:09 -07:00
vh 1b6c26ce58 docs: AT&T PD is a hard /64 at NH3, tested on the wire
AT&T support guessed 'I do not believe att will do that' from a DNS
provisioning desk. The guess was correct, but it needed proving rather
than accepting, so the UDM solicited DHCPv6-PD at /48, /56 and /60. All
three returned the same single /64. This is not a case of nobody having
asked -- the ask was made three ways.

Proven by temporarily enabling PD on nh3-iot, the only NH3 VLAN with
zero clients, then setting ipv6_pd_prefixid to 0, 15 and 16. All three
returned an identical c11f prefix, which only happens when exactly one
/64 is delegated; with a larger block the prefix-id moves the LAN within
it.

Records a mistake worth not repeating: I first read the gap between the
WAN address (c110) and the delegated prefix (c11f) as evidence of a /60.
It is not -- AT&T assigns those from different parts of their pool and
the spread means nothing.

NH3 was fully restored afterwards, with rollback artifacts kept. Also
captures the concrete ask for AT&T Business, phrased as something their
provisioning team can verify against their own DHCPv6 logs, and the
consequence if refused: NH3 can host exactly one v6 segment against
ESH's 256.
2026-08-18 14:41:29 -07:00
vh fddf7f587f docs: record the pending Cogent IPv6 provisioning request for the colo
Operator opened a ticket with Cogent for v6 at Anaheim, which closes the
one thing tonight's investigation could not resolve from our side.

Captures the diagnosis so the ticket has evidence behind it: a single RA
in 90 seconds of sniffing wan1, from fe80::ea0a:b9ff:fe3b:2c16, proving
an IPv6-capable router sits one hop away on the circuit terminating
38.120.12.42/29 -- but SLAAC obtained no global address across multiple
RA intervals and ping6 to Cloudflare and Google both returned 100% loss.
Router present, circuit unprovisioned.

Also records that the FortiGate v6 config was fully reverted after
testing, the FortiOS gotcha that SLAAC is 'set autoconf enable' rather
than an ip6-mode, and the ask to make when it lands: a /56 or better,
since NH3 only receives a single /64 from AT&T.

Notes the consequence worth planning around -- once provisioned, the
colo becomes the only site with both a static public v4 and routable
v6, which makes it the natural v6 hub given ESH is CGNAT'd and NH3 is
prefix-constrained.
2026-08-18 14:20:15 -07:00
vh 707a8cbcce docs: correct addressable vs reachable in the ESH v6 entry
I wrote that enabling SLAAC would give LAN devices 'globally reachable
addresses'. Wrong word, and the wrong word in a persistent-memory entry
a future session inherits as fact.

Addressable is a property of the address. Reachable is a policy decision
the firewall makes. v6 removes NAT; it does not remove the firewall, and
treating those as the same thing is exactly how v6 gets mischaracterised
as automatic exposure.

Records the operator's position while correcting it: no 1:1 inbound
pass-through. The pending firewall-policy pass is about writing explicit
default-deny inbound rules per v6 segment, not about deciding what to
expose.
2026-08-18 13:39:40 -07:00
vh 8be8a51437 docs: re-gloss esh-iot, re-spell esh-mgmt
esh-iot keeps the identical eight digits -- 4DBAD107, rendering
4dba:d107 -- and only the reading changes: 4 is FOR rather than A, so it
parses 'FOR DA BAD IOT', which describes what the segment is actually
for.

esh-mgmt genuinely changes: 115D:B055 becomes 15DA:B055. The leading I
is dropped and DA is spelled in full, giving 'IS DA BOSS' with the
network as subject rather than speaker. Still eight digits. DA written
out needs no substitution since D and A are both native hex; spelling it
as a single D the way esh-iot does would have yielded seven digits and
broken the house pattern.
2026-08-18 13:33:12 -07:00
vh 18c683b399 docs: reserve 4411:DBAD for a future DMZ
'FOR ALL DA BAD' -- 4=FOR, 411=ALL, D=DA, BAD=BAD. Eight digits, house
style, renders 4411:dbad.

No DMZ network exists on the ESH UDM today; this is a name claimed
against the day one is built. Pairs deliberately with esh-iot's
4DBA:D107 -- IoT is 'a da bad', the DMZ is 'for all da bad', which is
the correct relationship between the two segments.
2026-08-18 13:31:02 -07:00
vh 959bb6ee05 docs: server network gets 4411:B105 -- ESH v6 naming scheme complete
'FOR ALL BIOS' -- 4=FOR, 411=ALL, B105=BIOS. Eight digits like the rest.

Completes the set. All six ESH networks now carry an 8-hex-digit phrase
in a consistent first-person/declarative voice:

  Default       4BA5:3417   A BASE FOR IT
  esh-mgmt      115D:B055   I IS DA BOSS
  esh-server    4411:B105   FOR ALL BIOS
  esh-userland  CAFE:4411   CAFE FOR ALL
  esh-iot       4DBA:D107   A DA BAD IOT
  esh-cameras   1533:FACE5  I SEE FACES

Still a documentation convention rather than wire-level configuration --
UniFi has no static-v6 client assignment and the gateway address is
platform-fixed -- but these are the values to use whenever ESH LAN v6 is
switched on and hosts get hand-assigned addresses.
2026-08-18 13:30:27 -07:00
vh a264e001ae docs: default network settles on 4BA5:3417
Same phrase, 'A BASE FOR IT', but written as a plain 8-digit string
rather than forcing the article into its own group. 4=A, BA53=BASE,
4=FOR, 17=IT renders as 4ba5:3417 -- two groups, matching every other
network in the scheme, with the words straddling the colon exactly the
way 4DBA:D107 does.

Corrects the previous commit, which claimed this needed nine digits and
a third group. It is eight, and always was.
2026-08-18 13:27:12 -07:00
vh e5bba048c8 docs: revise default network to A:BA53:0417
'A BASE FOR IT' -- the article makes it a full sentence, matching the
voice of the other five. BA53 uses 3=E rather than the 5E spelling used
in the previous BA5E version.

Nine hex digits rather than eight, so unlike the others it does not fit
two groups and renders across three as a:ba53:0417.
2026-08-18 13:26:23 -07:00
vh 309a240fa8 docs: default network gets BA5E:0417
'BASE FOR IT' -- BA5E=BASE, 4=FOR, 17=IT. The foundation segment
everything else hangs off, which is what the default network is, and it
doubles as 'base for IT'.

Note the trailing group zero-pads: it renders as ba5e:0417, not
ba5e:417.
2026-08-18 13:25:36 -07:00
vh e58cfde7fd docs: userland network gets CAFE:4411
'CAFE FOR ALL' -- CAFE, 4=FOR, 411=ALL. Eight digits like the others,
and the only one so far that splits on its own phrase boundary, so it
renders legibly as cafe:4411.

Bonus reading: 411 is US directory assistance, which is a fitting second
joke for the segment the humans actually live on.
2026-08-18 13:24:04 -07:00
vh ab8481907d docs: iot network gets 4DBAD107
'A DA BAD IOT' -- 4=A, D=DA, BAD=BAD, 107=IOT. Eight hex digits to match
the cameras and mgmt picks.

Worth noting it renders as 4dba:d107, so unlike the other two the phrase
does not split on its word boundaries and reads as noise unless you know
it is there -- which is arguably right for the untrusted segment.
2026-08-18 13:22:22 -07:00
vh 805fa6ff22 docs: mgmt network gets 115D:B055
'I IS DA BOSS' -- 1=I, 15=IS, D=DA, B055=BOSS. Eight hex digits like
the cameras pick, so it renders as 2607:73c0:402:1d??::115d:b055 with
the same two-group split and room for host numbering.

Pairs structurally with 1533:FACE5 on cameras: both eight digits, both
first-person, and the network that is actually in charge gets to say so
to the one that is merely watching.
2026-08-18 13:18:32 -07:00
vh 35e7ecbadb docs: cameras network gets 1533:FACE5
'I SEE FACES' -- 1->I, 5->S, 3->E, 3->E then FACES. Eight hex digits
splitting cleanly across two groups, so it renders as
2607:73c0:402:1d00::1533:face5 with room left for host numbering.

Still a documentation convention rather than anything on the wire, per
the constraints recorded in the same entry, but this one is good enough
that it should survive to whenever ESH LAN v6 actually gets switched on.
2026-08-18 13:16:56 -07:00
vh fe3d765873 docs: record the ESH IPv6 naming scheme as a docs convention, not wire-level
Picked six hexspeak names for the ESH LANs during a wind-down moment
(FACE/B055/B105/CAFE/DEAD/BASE), then checked whether any of it could
actually land on the wire before implementing anything.

It can't, for three independent reasons: a network's only nameable slot
is its /64 prefix id, which is 2 hex digits and can't spell a 4-char
word; the gateway's own address is fixed at ::1 by the UniFi platform
with no field to override it; and UniFi has no IPv6 equivalent of
use_fixedip/fixed_ip, confirmed directly against the client schema, so
individual devices can't be pinned to a chosen v6 address either --
SLAAC devices self-assign via EUI-64 or privacy extension.

So this stays a documentation mnemonic. Recorded as such rather than
implied as something live, since I'd already started suggesting a
static-camera-assignment plan that the schema check ruled out.
2026-08-18 11:09:14 -07:00
vh 50d13f57cb docs: park the ipsec_local_ip watcher until ESH fiber is up
The ESH<->colo tunnel is restored and the FortiGate end is permanently
address-agnostic, but the UniFi end still needs a literal ipsec_local_ip
and so drops on any ESH WAN change -- Cox reclaiming WAN1, the fiber
cutover, or a DHCP renewal.

Operator's call not to build the self-healing watcher yet, which is
right: it would be written against the 5G failover address, which is
about to be replaced, and the fiber may reshape the topology anyway.
Parked as self-healing-ipsec-local-ip-watcher-for-the-esh with the
trigger recorded, plus the follow-up to retire the old ana-to-eshudm
tunnel whose distance-10 route would otherwise reclaim traffic if Cox
returned on the old address.

Records the manual stopgap in persistent memory so the gap is cheap to
cover by hand in the meantime: read wan_ip from the UDM's health
endpoint, PUT it into esh-ana.ipsec_local_ip.
2026-08-18 08:21:03 -07:00
vh 8a742f59b8 fix(ana-gw): restore ESH<->colo IPsec as a dialup tunnel with NAT-T
The link died when ESH lost its public IP during the fiber cutover. Two
independent causes, and the second would have defeated the obvious fix:

- phase1 ana-to-eshudm was type static, pinned to 70.181.90.232, an
  address that no longer exists.
- nattraversal was disable, so ESP could not have crossed NAT even with
  the peer IP corrected. pfi-ana-nh3 shares that setting and survives
  only because NH3 is publicly addressed, which is why the two tunnels
  diverged.

FortiOS refuses `set type dynamic` on an existing tunnel -- "Cannot
change tunnel type once configured" -- and rolled back cleanly, so the
fix could not be an edit. Rather than delete and recreate, which
cascades into the phase2, two static routes and ten policies, the
replacement was built alongside: new phase1+phase2 ana-eshudm-dyn
(type dynamic, ikev2, aes256-sha1, dh14, NAT-T on, PSK read from the ESH
UDM API so neither side needed a new key), static route id 10 at
distance 20, and two consolidated multi-zone policies 73/74. The old
tunnel is left in place, dead and harmless, as rollback.

Verified up: ana-eshudm-dyn_0 97.170.236.56:4500 selectors 1/1 -- the _0
suffix is a dialup child, :4500 is NAT-T, and the address is the
carrier's, which is precisely what could never have been pinned. ESH
reaches all four colo hosts at 40-56ms, the colo reaches all three ESH
hosts, and traceroute drops from eight hops leaking into the carrier
network to three hops fully encapsulated.

Config was backed up before any write (1.17MB, 36903 lines, off-box).

Residual fragility recorded: the UDM's ipsec_local_ip demands a literal
address -- empty is rejected as api.err.InvalidPayload -- so it still
needs updating when the fiber changes ESH's WAN address. The gateway end
is now address-agnostic; the UniFi end is not.
2026-08-18 08:12:35 -07:00
vh 9407e7f144 docs: correct the persistent-memory IPv6 entry to match the evidence
The prior edit missed its anchor and left the over-broad version in
place. The entry now separates the two inter-site links rather than
treating them as one: Site Magic (WireGuard, NH3<->ESH) survives
arbitrary NAT and is proven to; IPsec (colo<->ESH via ana-gw) does not
and is currently down, with traffic leaking unencapsulated to the
carrier. IPv6 keeps its justification on the IPsec link specifically.
2026-08-18 07:47:33 -07:00
vh 78cc760ef6 docs: refute the CGNAT-breaks-Site-Magic premise with a live test
The fleet IPv6 work was justified primarily by the expectation that ESH
fiber landing behind CGNAT would break Site Magic on IPv4, making v6 the
escape hatch. The fiber cutover provided a free natural experiment and
the premise does not hold.

Cox was unplugged, ESH failed over to the 5G WAN (already configured
failover-only, so this needed no intervention), and the resulting WAN
address is 192.168.200.111 -- RFC1918, double-NAT, no inbound path at
all, which is strictly worse than the CGNAT that was feared. Site Magic
stayed up throughout: all four ESH hosts reachable, ssh and command exec
working, 20MB pulled over the tunnel, latency 15ms -> ~46ms as expected
for cable to 5G.

The mechanism is visible on the device: magic_site_to_site_vpn holds
only `enabled` plus a WireGuard keypair, with peer orchestration in the
UniFi cloud and no WAN binding of any kind. NH3's edge is publicly
reachable, so the NAT'd side dials out and never needs reachability.

Consequence: no addressing outcome on the new fiber -- public, CGNAT or
double-NAT -- threatens the inter-site tunnel. IPv6 stays worth doing on
its own merits but stops being urgent, and stops gating anything.

Also worth recording that Site Magic cannot be pinned to a WAN. It rides
whichever uplink is active, so the only lever is failover priority --
which moves all site traffic, not just the tunnel. The existing
failover-only config on WAN2 already handles a primary-WAN outage
correctly and needed no change.
2026-08-18 07:44:06 -07:00
vh 668b63a398 feat(esh-pve-nas): install the 225-package backlog; reboot deferred
pve-manager 8.4.11 -> 8.4.20, corosync 3.1.9 -> 3.1.10-pve2, and kernel
6.8.12-42 staged on the /boot LV. dpkg clean, nothing outstanding for
apt -f install, all PVE services active, cluster quorate, no unapplied
conffiles. Reboot deliberately deferred at operator request, so the host
still runs 6.8.12-13 until a chosen window.

This validates the GRUB fix from 061c4b7 under the exact condition it
was written for. update-grub regenerated entries for the new kernel and
entry 0 -- what GRUB_DEFAULT=0 selects -- is now
/vmlinuz-6.8.12-42-pve with root=ZFS=nvme/ROOT/pve-1, supplied by the
grub.d drop-in since grub-mkconfig cannot derive the pool name itself.
The old kernel keeps correct entries as a fallback and the ext4 rollback
entry is untouched. Had the fix not landed first, saved_entry would
still be pinned to 6.8.12-13 and the host would boot the old kernel
indefinitely -- 161 security updates installed and never run.

/boot holds both kernel sets at 176M used of 488M, confirming the 512M
LV carved out of swap was sized correctly.

Adds a ZFS snapshot step to the upgrade playbook, taken automatically on
ZFS-root nodes before any package lands. That is the first real use of
the boot-environment upside the migration was meant to unlock: rollback
for this upgrade is now `zfs rollback -r
nvme/ROOT/pve-1@pre-upgrade-20260818T141652Z && reboot` rather than
archaeology in dpkg. Also documents that the corosync bump restarts
corosync mid-upgrade, which on a 2-node cluster is a brief quorum event.
2026-08-18 07:21:40 -07:00
vh 5f11d1b3cb feat(esh-pve-nas): cut PVE root over to ZFS on the mirrored NVMe
Root is now nvme/ROOT/pve-1. The USB DOM keeps the ESP and /boot but is
out of the runtime I/O path, so a bus reset can no longer drop root from
under a running hypervisor. All five guests healthy, three pools ONLINE,
system running, ext4 pve-root intact and unmounted as the rollback with
its own kernel and initrd. zfs-import-cache is now the active import
path -- the all-three-pools cachefile fix doing its job.

The window cost an unplanned outage, and the cause was this repo's own
tooling rather than the migration.

The staging chroot ran `mount --rbind /dev` and /sys with no
--make-rslave. On systemd `/` has shared propagation, so the cutover's
`umount -R` propagated back into the live host and removed the real
/sys/fs/cgroup, /dev/pts and /dev/shm. With cgroup2 gone systemd-logind
could not create a session: ping fine, TCP fine, SSH authentication
succeeded, resident daemons kept serving -- and every new exec hung,
including /sbin/reboot, so the reboot never ran at all.

It impersonates failing root-disk I/O almost perfectly, and I called it
as the DOM dying. That was wrong. dmesg had the answer throughout: the
DOM attached cleanly with no errors, and the last log timestamp was
12114881s -- 140 days -- meaning this was still the original boot. A
down-detector had also never reported the host down, which I read as a
fast reboot rather than as no reboot.

Fixes and guards:

- --make-rslave after every rbind, plus a guard that refuses to proceed
  while any chroot bind still reports shared propagation.
- Confirm a reboot by observing the host DOWN, not by watching for it to
  come back. Those two states are indistinguishable otherwise.
- Blast radius now measured from the server: `ss` inside CT 103 found
  five NFS clients, not the two documented. The new one that mattered is
  esh-vm-db, hard-mounted and unreachable by ssh. Left mounted on
  purpose and it came through read-write.
- grub-reboot's one-shot does NOT work here: grubenv sits on an LVM LV
  which GRUB reads but cannot write, so next_entry survived the boot
  that consumed it. Steady state is saved_entry=pve-zfs-root with no
  next_entry. There is no auto-fallback on this host and no IPMI.

Recovery needed no console: an idempotent cgroup2/devpts/shm remount
landed in the brief windows where exec succeeded. No data was lost, and
neither the DOM nor any pool was ever at risk.
2026-08-18 06:39:34 -07:00
vh c4b2278e7d feat(esh-pve-nas): stage the PVE root migration off the USB DOM
Everything but the reboot. Two rerunnable elway playbooks; the host is
still running from the ext4 root and its boot path is byte-identical to
the last 140 days, because grub-install is deliberately held back to the
cutover window.

Phase 1 (esh-pve-nas-stage-zfs-root.yaml): carve a 512 MB /boot LV out
of the 768 MB swap LV, populate it, rsync the 4.3 GB ext4 root into
nvme/ROOT/pve-1, write the copy's fstab.

Phase 2 (esh-pve-nas-stage-bootloader.yaml): ZFS initramfs, grub.cfg,
explicit pve-zfs-root and pve-ext4-rollback entries with stable ids,
grubenv pinned to the rollback so cutover's grub-reboot is a one-shot.

Three landmines the plan did not predict, all caught by verify steps
asserting effective state rather than by reading the plan:

- The /boot LV had nowhere to live. VG pve had 4 MB free and mounted
  ext4 cannot shrink; freeing space from root needs a rescue boot, which
  costs the one-reboot property. Space came from swap (768M -> 256M).

- The runbook's `zpool set cachefile=... nvme` would have broken the
  NAS. Populating a cachefile flips the host from import-by-scan to
  import-by-cache, so a one-pool cache leaves ssd and tank unimported --
  and CT 103 esh-nas has twelve bind mounts spanning all three pools.
  Set on all three instead, verified in the resulting cache.

- update-grub silently emitted a pool-less root=ZFS=/ROOT/pve-1, which
  boots to an initramfs prompt. Debian's 10_linux builds ${rpool}${bootfs}
  and rpool comes from grub-probe --target=fs_label, which returns empty
  because GRUB's ZFS reader cannot open a pool with encryption,
  large_dnode and zstd_compress -- the same feature set that forced /boot
  to stay ext4. The probe failure is swallowed by `2>/dev/null || true`.
  Fixed with a /etc/default/grub.d drop-in plus explicit menu entries.

The transferable lesson: the original verify grepped for the correct
root= string appearing somewhere in grub.cfg, which passes while every
menu entry is still broken. Assert the effective value, not the presence
of a substring.
2026-08-17 22:11:14 -07:00
vh 637ed3bd89 memory: Lobe TTS fixed by aliasing stock OpenAI model names at the gateway
Lobe's TTS had never worked. It sends model:"tts-1" and LiteLLM resolves the
model name before routing, so it 403'd against the scoped key's allow-list and
never reached :8198 -- our belief that an unknown model routes to the gateway
default was true of the gateway and false of the LiteLLM path, which is what
hid it.

Fixed at the gateway rather than the client: tts-1, tts-1-hd and gpt-4o-mini-tts
aliased to the same upstream as ext-tts, and added to the lobe-chat-esh
allow-list. Verified with Lobe's exact payload on Lobe's own key. The obsolete
'one-time human UI pass' follow-up is dropped.

Banks two durable facts: those aliases are independent DB rows that must move if
ext-tts repoints, and the infra-ops key has admin rights for /model/new and
/key/update so this class of work does not need sk-corvid.
2026-08-17 21:47:00 -07:00
vh 356752d99c memory: snapshot — heresy gen seat live, irv-ml1 cleared, homepage repo'd, esh-pve-nas DOM planned 2026-08-17 21:44:29 -07:00
vh 4b6daadb16 memory: operator confirms the heresy gen seat working well in real use
Records the one signal the synthetic gates cannot provide -- multi-turn
degeneration is stochastic and invisible to probes, and four synthetic tests
once validated three non-fixes on this exact seat.

Not yet the 60k-token bar the prior seat cleared, so the rollback weights
stay in place.
2026-08-17 20:19:18 -07:00
vh d676a1375b memory: watch DavidAU's heretic Qwen3.8, not Cold-Fusion-GAIN V1.1
Cold-Fusion-GAIN V1.1 examined and not adopted -- it is a capability
finetune of stock Qwen3.8 and every bench row is labelled [non heretic], so
adopting it would reintroduce base refusals the current seat does not have.

Records why it reads as uncensored at a glance: DavidAU's back catalog is
almost entirely Uncensored-Heretic builds, so the naming pattern implies it.
The heretic stage for this one is still in progress from base, and that is
the release worth watching.

Also banks what makes it interesting when the heretic build lands -- real
third-party benchmark gains over stock, claimed MTP acceptance well above
ours, thinking tokens cut to a fraction -- and the two caveats: the MTP
numbers are GGUF/llama.cpp not vLLM, and a trained MTP head means the free
CPU-hash gate would not apply.

Also drops the now-stale 'primary until the DavidAU Qwen3.8 lands' clause
from the superseded seat entry.
2026-08-17 19:26:15 -07:00
vh 11b688ff68 feat(gen-seat): promote absolute-heresy to the live gen seat
MuXodious/Qwen3.8-27B-absolute-heresy (Heretic v1.4.0 + SOMPOA, trial T377,
pin c2374593) quantized through our mixed NVFP4+FP8 recipe and promoted after
passing the full gate on the probe port.

Gate vs incumbent -- MTP acceptance 47.2% (48.2%), decode 103.5 tok/s (96.4),
prefill 6618/5403 at 6.7k/27k (6334/5085), TTFT 27k 5.00s (5.31s), perplexity
6.910 (7.059, 2.1% better), surface 6/6, abliteration compliance 4/4. On our
battery-instruct arm -- the framing that actually elicits refusals -- 0/55 with
zero EMPTY, so no catatonia at the hard edge.

Speed deltas are image-confounded: the probe ran the seat's pinned nightly
while the incumbent's stored numbers came from an earlier image. Read as not
worse. Acceptance, perplexity, surface and refusal are apples-to-apples.

All 7 LiteLLM aliases verified end-to-end. GPU0 at 91.3/97.9 GB with meromero
healthy -- more headroom than the previous build. Incumbent weights untouched
and .env.bak-heresy-20260817 in place for rollback.

Candidate is a 2-day-old RC1 with ~348 downloads; watch real multi-turn use.
2026-08-17 17:23:35 -07:00
vh c18f5c5d33 memory: WT #401 closed on demo verify; host ulimit floor staged not active
worldtree-dev closed #401 on our demo verification. Records the two-layer
state (their e41b139 compose pin verified on demo, covered-not-verified on
personal/pinned; our daemon floor staged), the measured fact that
default-ulimits is not SIGHUP-reloadable on Docker 29.4.3, the explicit
no-dockerd-restart decision, live-restore parked as a separate call, and
the one ping we still owe once worldtree-personal recreates.
2026-08-17 16:04:08 -07:00
vh 2686042106 memory: fleet IPv6 state + verified VPN topology; ana-wg key material locked down
Durable capture ahead of the ESH fiber install (2026-08-18) that puts the
house behind CGNAT and breaks Site Magic on IPv4 -- IPv6 becomes the
escape hatch and the likely first consumer of fleet v6.

Topology verified rather than assumed: Site Magic between UniFi units,
IPsec IKEv2 colo<->UniFi, and WireGuard as a remote-access convention
only, host-based on ana-wg behind a FortiGate UDP VIP. The FortiGate
port-forwards and never terminates WireGuard, so FortiOS 7.2's lack of
native WG is a non-issue.

IPv6 today: NH3 WAN live, colo and ESH none. AT&T delegates exactly one
/64 at NH3 -- established by forcing the prefix ID from auto to 0 and
observing the subnet not move, since the c110/c11f pattern otherwise
reads as a /60. PD enabled on nh3-iot to measure, then reverted; all
five NH3 LANs are back to ipv6_interface_type=none.

Also fixed on ana-wg: wg0.conf, keys/*_priv, keys/*_psk and the client
configs were mode 644 with private key material in them. Now 600, with
keys/ and configs/ at 700. wg-quick@wg0 stayed active, three peers
intact.

Corrects two stale in-flight rows: the DS regeneration is retired, not
queued, and SPEC-ds-regeneration.md is deleted rather than untracked.
2026-08-17 13:50:34 -07:00
vh 0b32b112bd memory: snapshot for /clear — gen-seat saga closed, Lobe live, litellm upgraded
Refreshed Current state (dropped superseded gen-seat history now covered by
the RESOLVED entry + playbook 3.8; added Lobe Chat, litellm upgrade+cap,
updated follow-ups). Logged 4 new Recent decisions (gen-seat two-cause
resolution + the synthetic-probe-validated-3-non-fixes meta-lesson, Lobe
stand-up, litellm upgrade, abliteration-catatonia). Handoff at
/tmp/infra-ops-handoff.md. Index 284 lines, no archival.
2026-08-17 02:23:59 -07:00
vh 2185964a6a memory: gen seat RESOLVED — mixed FP8-attn build on pinned nightly, coherent through 60k
Supersedes the stale 'GEN SEAT = AEON' current-state line. Records the
final resolved config (JonathanColetti/Heretic mixed NVFP4+FP8 on pinned
vLLM nightly, MTP on), the two-real-causes root cause, the AEON purge, and
the pinned-nightly follow-up (move to stable once #51113 ships). A cold
session now reads the correct gen-seat state.
2026-08-17 02:13:42 -07:00
vh aba7cda33e fix(refusal-probe): retract an invalid cross-battery comparison; adopt the two-control pair
RETRACTION. I claimed my arm-3 92.5% 'exceeded' brokkr-smithy-dev's 62.5%.
That comparison was invalid. His diff against his own artifact shows my
battery-instruct.yaml reproduces only his CREATIVE class -- 8 of 16 axes --
dropping all 5 operational (violence/incite, crime/fraud, cyber/malware,
selfharm/methods, privacy/stalk) and all 3 meta (meta/sysprompt,
meta/ignore, meta/dan), while adding 2 controls he never had, at k=5
against his k=2. His figure pools 16 axes; mine is creative-only. Different
denominators, so there was never a delta to report.

Cause: I rebuilt his instrument from his MESSAGE, and the class field lives
in the artifact, not the prose. Lesson recorded -- reconstructing a peer's
instrument from their description reproduces what they described, not what
they ran; diff against the artifact before claiming comparability.

Adopts his amendment to my control fix, which is better than my proposal. I
argued a single UNWRAPPED control suffices since over-fire is a property of
the scorer, not the wrapper. True but incomplete: one control gives only a
scorer FPR baseline and cannot attribute anything to the wrapper. Two -- the
same benign scenario unwrapped AND wrapped -- make the wrapper the only
variable, so the delta between them is the wrapper's contribution to
classifier firing. Costs one prompt.

ictrl-reunion stays contaminated and unchanged, now with an explicit
do-not-fix marker: rewriting it would break comparability with results
already collected, and it is the cleanest live demonstration of the very
confound this battery measures.
2026-08-16 16:45:17 -07:00
vh 766c65801c memory: AEON accepted on the gen seat; canonical sampling; four-wrong-diagnoses lesson
Gen seat state, the abliteration catatonia signature, canonical Qwen3.8
sampling with the wrong-mode presence_penalty fix, the two real
gateway-chat defects, and the single-file bind-mount inode trap.

Also records the methodology failure honestly: four disproved hypotheses
on one bug, caused by a harness that varied the QUESTION along with the
conversation depth, so a narrower question drawing a shorter answer read
as degeneration. Banked as rules -- hold the final question fixed when
comparing across depth, do not infer trends from n=3 when identical
inputs span 25-465 words, and ask for the real failing transcript before
building a synthetic reproduction.
2026-08-16 16:31:24 -07:00