ha-maintenance.sh --restart-core --yes exited 1 in <1s without restarting
Core. Empty output is ssh failure hidden by 2>/dev/null + pipefail, not a
MOTD-strip after a successful restart. Direct `ha core restart` is the
working path.
The host note now states the aiohttp IPv4 client is live, Core loaded it,
and home PPPoE IPv4 to 95598.csg.cn is currently blackholed while IPv6
works on gw. HA still has IPv6 disabled (W1N-85).
- Add tianqi weather recorder patch notes (W1N-75: _unrecorded_attributes)
- Document Bluetooth hci0 RTL8821CS instability (W1N-74) and eMMC lifetime
10% (W1N-76) as known issues
- Rewrite runbook known-issues section: all snapshot items resolved; link
hosts doc for the two remaining known issues
Decision tree for occasional B&W laser MFP purchases: Brother L1638W/L1848W
as default, cloud-subscription models as opt-in only, and one-veto checks
for AirPrint, Ethernet, and duplex/ADF needs.
Add historical snapshot header (baseline 35577d0), rewrite outdated
"current guide" assertions for post-ffb37a9 revisions, and add a
12-row status table mapping review claims to current §4.3/§11 sections.
- hosts/gfw.windy.lan.md: 3 NICs (eth2/VLAN10 ubunt_upg live), mosdns is
now OpenClash's nameserver (not idle), rewrite VLAN10 Wi-Fi section to
live-verified state
- docs/lan-dns-architecture.md: mosdns on gfw no longer 闲置; note the
recommended AGH+.36 companion architecture is still pending review
- runbooks/pdns-health.md: note the legacy powerdns-admin (PDA) orphan was
removed 2026-08-12 (W1N-59).
- runbooks/ansible-operations.md: document the us4 firewalld reconciliation
playbook scope (audited public zone only, fail-closed, no reload).
- docs/agents/domain.md: single-context repo layout for domain docs.
- docs/lan-dns-alternatives.md: notes on LAN DNS alternatives.
- .gitignore: exclude local agent-harness config (.agents/ .claude/ .omp/
.mcp.json WATCHDOG.yml skills-lock.json) from the repo.
Add playbooks/us4-firewalld.yml, a narrow reconciliation of the audited us4
public zone: fails closed on drift or unknown allowances, never reloads or
restarts firewalld, and does not manage Docker rules. Requires explicit
apply + provider-console confirmations, backs up the firewalld config and
ruleset, schedules an automatic 15-minute rollback via at, and verifies SSH,
HTTPS routes, containers, Fail2ban jails, and the WireGuard health check before
cancelling rollback. Pins ansible.posix 2.2.2 in requirements.yml.
Also expand hosts/us4.wsvc.info.md with deployment config and a live audit
snapshot (2026-08-12).
Deploy hbbs + hbbr via a safe-by-default Ansible role (playbooks/rustdesk.yml):
with rustdesk_confirm=false it only reports whether compose.yml matches live
state and refuses to recreate the stack; with rustdesk_confirm=true it deploys
and recreates. The relay assert rejects the known-bad hk2.wsvc.info hostname.
Add health profiles rustdesk (hbbs/hbbr health, relay DNS) and hk2aux (co-located
traefik/adguard/remark42 on hk2), plus the rustdesk-health runbook and AGENTS.md
entry. Server image pinned rustdesk/rustdesk-server:1.1.14.
Inventory now declares the plural healthcheck_profiles list per host (hk2 runs
pdns, rustdesk, hk2aux) instead of a single healthcheck_profile, and carries
the rustdesk server vars (rustdesk_compose_dir/relay/image) plus the rustdesk
host group.
The restic role relied on the removed singular healthcheck_profile var; it now
uses its own restic_backup_profile (set per host to vaultwarden on us2 and pdns
on hk2), so the health-check rename no longer breaks it. audit.yml's summary
labels the host's profile list instead of the singular var.
Replace the single healthcheck_profile with a healthcheck_profiles list so a
host can run several checks (e.g. hk2: pdns, rustdesk, hk2aux). Profiles emit
per-check JSON to latest-<check>.json; the dispatcher clears stale per-check
files, runs every profile, and merges them into latest.json.
Contract: a single complete check keeps the historical verbatim latest.json
shape; several checks produce a worst-status aggregate retaining every check's
detail. A profile that crashes before reporting is aggregated as unknown so
latest.json can never go stale while the dispatcher fails. The dispatcher exits
with the worst (max) profile exit code.
- Add dns.windy.lan to Ansible inventory (adguardhome group/profile) with a
read-only healthcheck template, systemd timer, and on-demand report parity
with the other active hosts; verified green on the host.
- Add synapse.chans.xyz to the AGENTS.md active-host quick map.
- Remove plans/; migrate decisions/verification to a Linear vps project doc and
file the remaining gaps as W1N-46..49 with blocking edges.
- Retire scripts/check-mx2.sh; point mailcow health/update runbooks and the
mx2 host file at the Ansible health report.
- Trim us2 stub software to verified running services; note dormant dirs.
- Normalize repo docs to English; drop the non-existent CONTEXT.md/ADR claim
and remove docs/agents/domain.md.