auto: docs sync 2026-07-12T00:00:23+00:00

Files changed: ", c.get(k))\nPY\n\\\"\n\"" engine/config.yaml engine/lib/lint.py engine/lib/vocab_gen.py engine/lint-report.md engine/sweep.sh vault/.obsidian/workspace.json vault/archive/projects/meshai-native-fire-severity-audit-cc-handoff.md vault/archive/projects/vaultwarden-plan.md vault/docs/matrix/matrix_host.md vault/docs/matrix/synapse.md vault/docs/services/services.md vault/docs/software/authentik.md vault/docs/software/caddy.md vault/docs/software/dns.md vault/docs/software/recon.md vault/docs/software/searxng.md vault/glossary.md vault/notes/echo6-landing-page-data-export.md vault/projects/matrix-synapse-deployment.md vault/projects/meshai.md vault/projects/meshtastic-headscale-runbook.md vault/projects/mmud-project.md vault/runbooks/add-peertube-channel.md vault/runbooks/authentik-access-groups.md vault/runbooks/authentik-create-invitation.md vault/runbooks/authentik-oidc-application.md vault/runbooks/authentik-upgrade.md vault/runbooks/expose-service-contabo.md vault/runbooks/lxc-service-migration.md vault/runbooks/mailcow-create-mailbox.md vault/runbooks/meshtastic-sidecar-node.md vault/runbooks/meshtasticd-sim-nodes-runbook.md vault/runbooks/proxmox-create-ubuntu-vm.md vault/runbooks/recon-operations.md vault/runbooks/recon-service-integration.md vault/runbooks/syncthing-add-node.md
This commit is contained in:
echo6-autocommit 2026-07-12 00:00:23 +00:00
commit cce29c595d
37 changed files with 336 additions and 262 deletions

View file

@ -32,10 +32,10 @@ topic_categories:
# Read-only inventory sources for the generated entity lexicon (tier 2)
inventory:
proxmox_nodes: [data, utility, cloud, media, toc] # pct list / qm list
proxmox_vps: [contabo, edge2] # pct list
docker_hosts: [cortex, utility, media, contabo] # docker ps
headscale_host: contabo # headscale nodes list
proxmox_nodes: [data, utility, cloud, media, toc] # pct list / qm list (root)
proxmox_vps: [edge1, edge2] # edge1=root; edge2=admin+sudo (hardened, no root login)
docker_hosts: [cortex, utility, media] # host-level docker ps; edge1/edge2 services are LXC-nested (not visible at host level)
headscale_host: edge2 # Headscale runs in edge2 CT 107 (dockerized)
ssh_user: zvx
# Frontmatter property schema enforced by lint

View file

@ -290,7 +290,7 @@ def _normalize_name(name: str) -> str:
def build_note_index(vault_dir: Path) -> dict[str, Path]:
index: dict[str, Path] = {}
for p in vault_dir.rglob("*.md"):
if "archive" in p.parts:
if "archive" in p.parts or ".trash" in p.parts:
continue
key = _normalize_name(p.stem)
index[key] = p
@ -328,7 +328,7 @@ def build_backlink_counts(
) -> dict[str, int]:
counts: dict[str, int] = {k: 0 for k in note_index}
for p in vault_dir.rglob("*.md"):
if "archive" in p.parts:
if "archive" in p.parts or ".trash" in p.parts:
continue
try:
_, body = parse_frontmatter(p)
@ -386,7 +386,7 @@ def build_earned_a_doc_candidates(
doc_mentions: dict[str, set] = defaultdict(set)
for p in vault_dir.rglob("*.md"):
if "archive" in p.parts:
if "archive" in p.parts or ".trash" in p.parts:
continue
try:
text = p.read_text(encoding="utf-8", errors="replace")
@ -448,7 +448,7 @@ def build_tag_coverage(
tag_to_paths: dict[str, list[str]] = defaultdict(list)
for p in vault_dir.rglob("*.md"):
if "archive" in p.parts:
if "archive" in p.parts or ".trash" in p.parts:
continue
try:
fm, _ = parse_frontmatter(p)
@ -695,7 +695,7 @@ def run_lint(vault_dir: Path, engine_dir: Path) -> tuple[list[LintResult], dict]
t0 = time.monotonic()
for path in all_paths:
if "archive" in path.parts:
if "archive" in path.parts or ".trash" in path.parts:
continue
findings: list[dict] = []
try:

View file

@ -34,9 +34,9 @@ def load_config(config_path: str) -> dict:
],
"inventory": {
"proxmox_nodes": ["data", "utility", "cloud", "media", "toc"],
"proxmox_vps": ["contabo", "edge2"],
"docker_hosts": ["cortex", "utility", "media", "contabo"],
"headscale_host": "contabo",
"proxmox_vps": ["edge1", "edge2"],
"docker_hosts": ["cortex", "utility", "media"],
"headscale_host": "edge2",
"ssh_user": "zvx",
},
}
@ -114,7 +114,8 @@ HOST_IPS = {
"mt-burleybutte": ("192.168.1.185", None),
"pi-nas": ("192.168.1.245", "100.64.0.21"),
"matt-desktop": ("192.168.1.111", "100.64.0.10"),
"contabo": ("5.189.158.149", "100.64.0.1"),
"contabo": ("5.189.158.149", "100.64.0.40"),
"edge1": ("5.189.158.149", "100.64.0.40"),
"edge2": ("184.174.35.153", "100.64.0.26"),
}
@ -426,7 +427,7 @@ def parse_environment_md(path: Path) -> list[dict]:
aliases.append(node_id_m.group(1))
# Infer type
if 'Contabo' in name or 'VPS' in name.upper():
if 'Contabo' in name or 'edge1' in name.lower() or 'edge2' in name.lower() or 'VPS' in name.upper():
etype = 'vps'
elif re.search(r'pi|Pi|raspberry', purpose, re.I) or name.startswith('pi-') or name.startswith('mt-') or name == 'aida-nebra':
etype = 'pi'
@ -549,7 +550,7 @@ def parse_services_md(path: Path, known_entities: list[dict]) -> list[dict]:
host_map = {
'utility': 'utility', 'cloud': 'cloud', 'media': 'media',
'data': 'data', 'toc': 'toc', 'cortex': 'cortex',
'contabo': 'contabo', 'edge2': 'edge2',
'contabo': 'contabo', 'edge1': 'edge1', 'edge2': 'edge2',
'aida-nebra': 'aida-nebra', 'pi-nas': 'pi-nas',
}
runs_on = host_map.get(first_word, first_word)
@ -813,12 +814,21 @@ def _proxmox_ip_for_name(name: str) -> str | None:
"cloud": "192.168.1.242",
"media": "192.168.1.243",
"toc": "192.168.1.244",
"contabo": "5.189.158.149",
"edge1": "5.189.158.149",
"edge2": "184.174.35.153",
}
return ip_map.get(name)
def _host_access(name: str) -> tuple[str, str]:
"""Return (ssh_user, sudo_prefix) for a host.
edge2 is hardened: root login is disabled; use admin + passwordless sudo.
All other Proxmox hosts (home nodes, edge1) use root."""
if name == "edge2":
return ("admin", "sudo ")
return ("root", "")
def query_proxmox_node(host_name: str) -> list[dict]:
"""Try pct list + qm list on a Proxmox host; return entity dicts."""
ip = _proxmox_ip_for_name(host_name)
@ -826,9 +836,9 @@ def query_proxmox_node(host_name: str) -> list[dict]:
return []
entities = []
# Try root SSH (Proxmox hosts use root)
out_pct = _ssh_run(ip, "root", "pct list 2>/dev/null")
out_qm = _ssh_run(ip, "root", "qm list 2>/dev/null")
user, sudo = _host_access(host_name)
out_pct = _ssh_run(ip, user, f"{sudo}pct list 2>/dev/null")
out_qm = _ssh_run(ip, user, f"{sudo}qm list 2>/dev/null")
if out_pct:
for line in out_pct.splitlines():
@ -861,7 +871,6 @@ def query_docker_host(host_name: str, user: str) -> list[dict]:
"cortex": "192.168.1.150",
"utility": "192.168.1.241",
"media": "192.168.1.160",
"contabo": "5.189.158.149",
}
ip = ip_map.get(host_name)
if not ip:
@ -889,9 +898,14 @@ def query_docker_host(host_name: str, user: str) -> list[dict]:
def query_headscale(headscale_host: str) -> list[dict]:
"""Try headscale nodes list on contabo; return node entities."""
"""Try headscale nodes list; Headscale runs dockerized inside edge2 CT 107."""
ip = _proxmox_ip_for_name(headscale_host) or headscale_host
out = _ssh_run(ip, "root", "headscale nodes list 2>/dev/null")
user, sudo = _host_access(headscale_host)
if headscale_host == "edge2":
cmd = f"{sudo}pct exec 107 -- docker exec headscale headscale nodes list 2>/dev/null"
else:
cmd = "headscale nodes list 2>/dev/null"
out = _ssh_run(ip, user, cmd)
if not out:
return []
@ -952,10 +966,10 @@ def run_live_inventory(config: dict) -> tuple[list[dict], list[str]]:
# Headscale
try:
ents = query_headscale(inv.get("headscale_host", "contabo"))
ents = query_headscale(inv.get("headscale_host", "edge2"))
if ents:
live_entities.extend(ents)
succeeded.append("headscale:contabo")
succeeded.append(f"headscale:{inv.get('headscale_host', 'edge2')}")
except Exception:
pass

View file

@ -1,17 +1,17 @@
# Vault Lint Report
Generated: 2026-07-11T12:00:06Z | Docs scanned: 105 | Elapsed: 0.0s
Generated: 2026-07-11T22:05:39Z | Docs scanned: 105 | Elapsed: 0.0s
## Summary
| Severity | Count |
|----------|-------|
| ERROR (dead links) | 0 |
| WARN (schema) | 2 |
| INFO (orphans) | 40 |
| WARN (schema) | 0 |
| INFO (orphans) | 39 |
### WARN breakdown
- Missing frontmatter block: 2
- Missing frontmatter block: 0
- Invalid/missing frontmatter fields: 0
- Unknown tags: 0
@ -19,14 +19,8 @@ Generated: 2026-07-11T12:00:06Z | Docs scanned: 105 | Elapsed: 0.0s
_None. All wikilinks resolve._
## WARN — Schema & Tag Violations
- `.trash/2026-06-19.md` — missing frontmatter block entirely
- `projects/meshai-native-fire-severity-audit-cc-handoff.md` — missing frontmatter block entirely
## INFO — Orphan Notes (no incoming links, capped at 40)
- no incoming links: .trash/2026-06-19.md
- no incoming links: runbooks/add-peertube-channel.md
- no incoming links: runbooks/authentik-access-groups.md
- no incoming links: runbooks/authentik-create-invitation.md
@ -34,9 +28,8 @@ _None. All wikilinks resolve._
- no incoming links: runbooks/authentik-upgrade.md
- no incoming links: docs/navi/cc-rules.md
- no incoming links: CLAUDE-baseline.md
- no incoming links: runbooks/ct-runbook.md
- no incoming links: notes/echo6-landing-page-data-export.md
- no incoming links: runbooks/expose-service-contabo.md
- no incoming links: runbooks/expose-service-edge2.md
- no incoming links: runbooks/expose-service-home.md
- no incoming links: runbooks/fleet-magicdns-resolved-migration.md
- no incoming links: projects/fleet-platform-baseline.md
@ -51,9 +44,7 @@ _None. All wikilinks resolve._
- no incoming links: runbooks/idahomesh-vpn-device-setup.md
- no incoming links: runbooks/lxc-service-migration.md
- no incoming links: runbooks/mailcow-create-mailbox.md
- no incoming links: docs/matrix/matrix_host.md
- no incoming links: projects/meshai-config-hot-apply.md
- no incoming links: projects/meshai-native-fire-severity-audit-cc-handoff.md
- no incoming links: runbooks/meshai-prod-compose-override.md
- no incoming links: runbooks/meshmonitor-password-reset.md
- no incoming links: runbooks/meshtasticd-sim-nodes-runbook.md
@ -66,18 +57,19 @@ _None. All wikilinks resolve._
- no incoming links: runbooks/pymc-repeater-kiss-tnc-reenumeration.md
- no incoming links: runbooks/recon-operations.md
- no incoming links: runbooks/recon-service-integration.md
- no incoming links: session-resume/SESSION-HANDOFF-meshai-test.md
- no incoming links: docs/matrix/synapse_retention_discovery.md
- no incoming links: runbooks/syncthing-add-node.md
## Gaps & suggestions
### Docs with no tags
- `.trash/2026-06-19.md`
- `projects/meshai-native-fire-severity-audit-cc-handoff.md`
_None — all docs have at least one tag._
### True orphans (no inbound link, no shared tag)
- `.trash/2026-06-19.md`
- `projects/meshai-native-fire-severity-audit-cc-handoff.md`
_None._
### Dead wikilinks
@ -95,17 +87,17 @@ Matt decides whether to create a real doc — when he does, future sweeps will l
| Term | Docs mentioning it |
|------|--------------------|
| `tailscale` | 39 |
| `docker` | 36 |
| `docker` | 34 |
| `proxmox` | 31 |
| `headscale` | 25 |
| `headscale` | 24 |
| `meshtastic` | 19 |
| `peertube` | 19 |
| `mailcow` | 17 |
| `element` | 14 |
| `forgejo` | 13 |
| `immich` | 13 |
| `nextcloud` | 13 |
| `vaultwarden` | 13 |
| `element` | 13 |
| `livesync` | 12 |
| `vaultwarden` | 12 |
| `aida-nebra` | 11 |
| `jellyfin` | 11 |

View file

@ -58,8 +58,13 @@ GPU_DEFERRED=0
DEFER_REASON=""
# Guard 1 — competing GPU processes (share the A4000)
if pgrep -fa 'peertube-runner|whisper|ffmpeg' >/dev/null 2>&1; then
COMPETING="$(pgrep -fa 'peertube-runner|whisper|ffmpeg' | head -1)"
# Note: peertube-runner is intentionally excluded — it's a persistent server
# daemon that's always running, so its mere presence doesn't mean the GPU is
# busy (only an active transcode job does, and that spawns ffmpeg, which is
# still caught here; actual peertube contention is caught by the util/VRAM
# guards below).
if pgrep -fa 'whisper|ffmpeg' >/dev/null 2>&1; then
COMPETING="$(pgrep -fa 'whisper|ffmpeg' | head -1)"
DEFER_REASON="competing GPU process: ${COMPETING}"
GPU_DEFERRED=1
fi