Commit Graph
450 Commits
Author SHA1 Message Date
notplantsandClaude Opus 5 360999d623 journal: secrets audit of the cc-ci host; leaked keys found in rsynced agent logs and redacted
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-08 17:07:23 +00:00
cc-ci-orchestrator 8af6c5fb45 journal: orchestrator startup entry (opencode agent, phase sequence confirmed DONE) 2026-09-08 16:53:57 +00:00
notplantsandClaude Opus 5 c14c56147d launchers: the opencode UI is oc.ci.commoninternet.net (not tailnet-only); journal the key switch
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-08 16:53:20 +00:00
notplantsandClaude Opus 5 79f69b0d35 cc-ci host on the OpenCode Go subscription key (opencode-go), not ZEN
The operator's AUTONOMIC_OPENCODE_KEY is a Go subscription key. Put in the
`opencode` (ZEN) slot it authenticates but every request fails "Insufficient
balance", because ZEN is pay-as-you-go credit; on the `opencode-go` endpoint
the same key answers fine. So the orchestrator agent moves to
opencode-go/glm-5.2, and README records that this host is a Go host and that
its opencode config must carry no inline apiKey.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-08 16:50:20 +00:00
notplantsandClaude Opus 5 7abea67ad4 host toolbox: vi/vim, sqlite, bat, bc, moreutils, pv, man-pages; set EDITOR
`vi` and `vim` were both absent on the cc-ci host (operator hit it over ssh);
the vim package ships a `vi` binary, so one entry covers both names, and
EDITOR=vim makes git/systemctl/visudo open something that exists.

sqlite earns its place beyond convenience: Drone's build and step logs live in
its sqlite volume, and the runbook plus /cc-ci-status tell you to read them
there — until now every such check needed an ad-hoc `nix-shell -p sqlite`.

Installed via environment.systemPackages, so they are on PATH for BOTH root and
loops through /run/current-system/sw/bin.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-08 16:32:45 +00:00
auto-update ec8b2fef0f flake.lock: weekly auto-update, health-checked 2026-09-08 03:06:27 +00:00
notplantsandClaude Opus 5 1eb176cf09 gitignore the auto-update lock backup; journal the tested auto-update + skill rewrites
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-08 02:02:26 +00:00
auto-update d1f5e916f3 flake.lock: weekly auto-update, health-checked 2026-09-07 22:27:16 +00:00
notplantsandClaude Fable 5.1 a8af8429f2 weekly health-gated auto-update of the cc-ci host; skills rewritten for the combined host
nix/modules/auto-update.nix (own module, no notplants-nix dependency): Tuesday
03:00 UTC, busy-gated (CI run, weekly upgrader, report, sweep, running Drone
builds → skip), `nix flake update` → build → switch-to-configuration test →
cc-ci health checks (sshd, 0 failed units, core units, every swarm service at
replica count, sops decrypted, dashboard/reports/drone 200, opencode UI 401)
→ profile + bootloader → flake.lock committed and pushed to main → /etc/cc-ci
fast-forwarded; revert + lock restore on failure; one-line state file for
/cc-ci-status.

Skills (.opencode canonical, .claude pointers' descriptions synced):
- cc-ci-orchestrator-update: THE host update — drives the auto-update unit by
  hand; --cc-ci-only for a cc-ci-main-only move; failure playbook.
- cc-ci-server-update: delegates to it and explains why the old procedure
  (rebuilding the cc-ci repo's standalone #cc-ci) must not be run on this host.
- cc-ci-update: chains orchestrator-update then tests-update.
- cc-ci-status: §5/§6 for one host — auto-update state, generation vs boot
  generation, front doors (oc.ci = 401), sops, fail2ban, timers, orchestrator
  agent session, secrets inventory; verdict updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 22:22:50 +00:00
notplantsandClaude Fable 5.1 48226dd78f opencode UI stack is ccci-opencode-ui, on the weekly sweep's keep-list; journal: first weekly run on the new host
The 2026-09-07 weekly run's step-0 orphan sweep removed the `opencode-ui`
swarm stack (the traefik route to the opencode web UI) because it was not
on sweep-orphans.sh's keep-list. Renamed to ccci-opencode-ui alongside the
other control-plane stacks and added to KEEP_RE.

Journal: the run itself (lasuite-docs #8, n8n #7 GREEN on the new Drone,
report week-2026-09-07 published) ran entirely on the new host.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 22:13:43 +00:00
autonomic-bot be9687962c upstream(n8n): release-notes sources 2.38.x 2026-09-07 21:49:50 +00:00
notplantsandClaude Fable 5.1 b360bfbb7c journal: evening changes on the cc-ci host (opencode agent, secrets minimised, weekly run started)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:34:58 +00:00
notplantsandClaude Fable 5.1 77f156318e README §4b: the bot deploy key is generated on the host; master age key only for the first deploy
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:32:50 +00:00
notplantsandClaude Fable 5.1 415d530baf cc-ci host: keys generated on the host, nothing copied from another machine
Operator: no ssh keys or non-essential secrets from the old orchestrator
box on the cc-ci host. `ssh cc-ci` uses cc-ci-local-ed25519 (generated on
the host, pub in nix/hosts/cc-ci/ssh-keys); pushes to Gitea use
autonomic-bot-cc-ci-ed25519 (generated on the host, registered on the bot
account); root reuses that file for the cc-ci-secrets submodule. README §4:
the /secrets/files inventory shrinks to exactly what cc-ci needs, and §4b
now says to make the host a sops recipient and take the master key away.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:31:13 +00:00
notplantsandClaude Fable 5.1 a72a816b48 cc-ci host: the orchestrator is an opencode agent; no Claude on the box; /secrets convention
Operator 2026-09-07 (evening): Claude sessions stay on notplants-orchestrator;
on the cc-ci host the orchestrator is an opencode agent (agents.toml:
opencode/glm-5.2) steered from https://oc.ci.commoninternet.net, next to the
upgrader/report sessions. claude-install and CLAUDE_BIN are gone from the
modules; launch-upgrader/report print the real UI URL; README "Operating the
orchestrator" rewritten and a "Weekly upgrade run" section added.

Secrets: only cc-ci's, under /secrets/files with runtime paths symlinked
(README §4 table), nothing from other projects — tangled key and the
tailscale line dropped from the host.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:27:23 +00:00
notplantsandClaude Fable 5.1 01caa90e76 README day-2: regenerate the cc-ci lock on the host; plan: steps 8 + lint follow-ups done
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:20:11 +00:00
notplantsandClaude Fable 5.1 841f8a9d1f flake.lock: cc-ci → main with the lint fixes (#33, #34)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:18:20 +00:00
notplantsandClaude Fable 5.1 536d621865 fail2ban nginx jail: read the journal (NixOS nginx logs errors to stderr, not error.log)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:08:22 +00:00
notplantsandClaude Fable 5.1 666509d53d plan + journal: cutover done 2026-09-07, orchestrator moved, remaining items
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:06:09 +00:00
notplantsandClaude Fable 5.1 bf84245d4b cc-ci host: one resolver set (no Hetzner caches), pin the host's own names
During the DNS cutover the Hetzner resolvers nixos-infect had left in
networking.nix still served the old address (3h TTL) while 1.1.1.1/8.8.8.8
had the new one, so every other lookup of drone.ci.commoninternet.net from
the box itself went to the old server: runner "cannot request stage 404",
bridge "drone trigger failed 404", traefik probes alternating 200/404.
Drop those resolvers; pin ci/drone/report/traefik/warm-keycloak/oc names to
this host in networking.hosts. README §7 records it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 21:03:00 +00:00
notplantsandClaude Fable 5.1 72d4a31910 opencode UI route via traefik labels on a swarm relay, not the file-directory provider
Enabling FILE_PROVIDER_DIRECTORY_ENABLED in the coop-cloud traefik recipe
REPLACES its single provider file (wildcard cert + `security` middleware),
which took every cc-ci front door down for two minutes on 2026-09-07.
Reverted. The route is now what every recipe does: a one-container swarm
stack (`opencode-ui`, alpine/socat relay to nginx on the docker bridge)
carrying the traefik router labels, deployed by opencode-ui-route.service.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 20:57:36 +00:00
notplantsandClaude Fable 5.1 6cc78cf758 orchestrator-host: opencode UI backend on 8090 (8080 is acme-dns's API); note the traefik FILE_PROVIDER_DIRECTORY_ENABLED requirement
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 20:51:53 +00:00
notplantsandClaude Fable 5.1 b23ad96616 opencode UI on 443 via traefik (Host routing), nginx basic auth on the docker bridge
Operator: standard 443, routed by domain. Traefik already owns 443 with the
*.ci.commoninternet.net cert, so opencode-ui-route.service drops a dynamic
config into the traefik stack's watched file-providers volume routing
oc.ci.commoninternet.net -> http://172.18.0.1:8080, where nginx (reachable
only on docker_gwbridge) enforces the basic auth and logs 401s with the
real client IP (real_ip from X-Forwarded-For). The fail2ban nginx jail bans
in DOCKER-USER, since that traffic is forwarded, not INPUT. 8443 and the
ACME-host variant are gone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 20:49:53 +00:00
notplantsandClaude Fable 5.1 8f7f125fc0 cc-ci host: no tailscale; fail2ban; opencode UI public on 8443 with the LE wildcard
Operator 2026-09-07: the combined host stays off the tailnet. ssh is
key-only (password + keyboard-interactive auth off), the opencode UI is
served as oc.ci.commoninternet.net on 8443 — TLS from the CI server's
*.ci.commoninternet.net ACME cert (new orchestrator-host option
opencodeUiAcmeHost; nginx joins the acme group) behind the existing basic
auth — and fail2ban watches sshd plus nginx's 401s (nginx-http-auth jail).
tailscaled ordering dropped from the orchestrator units. README updated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 20:45:59 +00:00
notplantsandClaude Fable 5.1 e5b0177c93 journal + reboots: 2026-09-07 consolidation sessions; agents.toml: orchestrator on claude/fable-5-1 (operator 2026-09-07)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 20:33:49 +00:00
notplantsandClaude Fable 5.1 a895bd3e3e plan-cc-ci-combined-host: steps 1-5 done, host up, waiting on tailscale key + DNS
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 20:28:50 +00:00
autonomic-bot 86f15ae2c3 Merge pull request 'nix: one Hetzner host for the cc-ci CI server + the orchestrator (#cc-ci)' (#19) from feat/combined-cc-ci-host into main
nix: one Hetzner host for the cc-ci CI server + the orchestrator (#19)
2026-09-07 20:26:25 +00:00
notplantsandClaude Fable 5.1 4bc483326b orchestrator-host: symlink the opencode installer's binary into ~/.local/bin; README: nginx file perms, first-rebuild wrapper, pre-cutover checks
Found on the first activation of #cc-ci on 195.201.88.249: the opencode
installer lands in ~/.opencode/bin (opencode-web then failed at EXEC), and
nginx's pre-start config check runs as the nginx user, so the staged
cert/htpasswd must be root:nginx 0640, not root:root 0600.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 20:24:47 +00:00
notplantsandClaude Fable 5.1 f105808bed nix/hosts/cc-ci: real hardware + networking from the box; document the infect fixes
hardware.nix / networking.nix are now the nixos-infect output of
195.201.88.249 (ESP E079-7D41, eth0 MAC-pinned), with the one edit that
matters: defaultGateway as an attrset with interface = "eth0".

README §2a records what it actually took to get NixOS running on the
Debian 13 image: NO_SWAP=true (tmpfs /tmp), a manual lustration from rescue
mode because 26.05's systemd initrd did not honour NIXOS_LUSTRATE (Debian's
unit files shadowed every NixOS service), and the gateway fix applied via a
chroot rebuild with the nix sandbox off.

flake: cc-ci input back on main (PR #32 merged as f6dbfa3); loops uid pinned
to 1000 so workspace rsyncs by uid line up.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 20:15:16 +00:00
notplantsandClaude Fable 5.1 31af820079 nix: one Hetzner host for the CI server + the orchestrator (#cc-ci)
The orchestrator's flake now builds the machine it shares with the cc-ci CI
server: `nixosConfigurations.cc-ci` composes cc-ci's nixosModules.cc-ci-server
(new flake input, nixpkgs + sops-nix follow ours), this repo's orchestrator
module (nix/modules/cc-ci.nix, exported as cc-ci-orchestrator, `cc-ci` kept
as an alias for notplants-nix) and the new nix/modules/orchestrator-host.nix
— the host contract those units always assumed (loops user, claude/opencode
CLIs, opencode web server + tailnet-only UI on 8443 since traefik owns
80/443, nix-ld, tool set, `ssh cc-ci` → loopback).

nix/hosts/cc-ci/{hardware,networking}.nix are PROVISIONAL copies of the old
server's layout so the flake evaluates; they get replaced by the
nixos-infect output of 195.201.88.249.

README.md is the deploy guide (Hetzner Debian → nixos-infect → this flake →
staging → data restore → cutover). archive/ holds the retired Incus/Hetzner
orchestrator host configs, the old terraform and the migration plans;
references updated. cc-ci-plan/plan-cc-ci-combined-host.md is the working
plan for the move.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqkQq3CDmFWcQ7u1LzoyRz
2026-09-07 19:58:33 +00:00
autonomic-bot 5bebd13e49 docs: record weekly upgrade report
Completed DeepSeek Flash run and published report verified.
2026-08-31 20:47:10 +00:00
autonomic-bot 82d3127c2a docs: record weekly upgrade report 2026-08-31 20:46:55 +00:00
autonomic-bot d824800f8a upstream(n8n): 2026-08-31 release-notes (2.34.5/2.34.6, 2.35.4-7, 2.36.8/2.36.9, 2.37.4, 2.37.5 withdrawn, 2.37.6) 2026-08-31 20:31:59 +00:00
autonomic-bot e7f861ec9e upstream(mattermost-lts): 2026-08-31 re-check note (ESR still 11.7.10, PR #2 re-verify) 2026-08-31 20:20:09 +00:00
autonomic-bot 1b75d986b2 fix: default testme Gitea URL
Verified with bash -n; public default only.
2026-08-31 19:29:59 +00:00
autonomic-bot e72fbdb79c fix: default testme Gitea URL 2026-08-31 19:29:31 +00:00
autonomic-bot f6c6b39b18 docs: record acme-dns production issuance 2026-08-31 19:04:54 +00:00
autonomic-bot 02ff90777f docs: record acme-dns production issuance 2026-08-31 19:04:41 +00:00
autonomic-bot 012212498d docs: record acme-dns handoff 2026-08-31 17:17:09 +00:00
autonomic-bot 521f6e6934 docs: record acme-dns handoff 2026-08-31 17:16:51 +00:00
autonomic-bot 07bc0a15d5 Merge pull request 'config: load public cc-ci runtime environment' (#14) from chore/public-runtime-config into main 2026-08-31 16:50:25 +00:00
autonomic-bot 00a4ee6752 config: load public cc-ci runtime environment 2026-08-31 16:49:15 +00:00
autonomic-bot 9c619abd6c upstream(n8n): release-notes sources 2.36.4..2.37.3 2026-08-28 04:15:13 +00:00
autonomic-bot 980530f505 upstream(mattermost-lts): 2026-08-28 re-check — 11.7.10 newest ESR patch 2026-08-28 04:00:02 +00:00
autonomic-bot 3047ee7724 config: GITEA_URL is public config, not a credential
The Gitea host was stored in the credentials env file, so a literal
secret scanner treated it as a secret and refused two READMEs in another
repo that link to git.autonomic.zone.

It was never secret: advisory-scan.py, pr-survey.py and recipe-report.py
already default it to git.autonomic.zone, and it is this repo's own
remote host. It is a bare hostname with no scheme, userinfo or path.

Removed from the env file and defaulted here the same way the Python
already does. GITEA_USERNAME and GITEA_PASSWORD keep their :? guard --
those are real credentials and must still fail loudly if unset.
2026-08-26 17:46:58 +00:00
autonomic-bot c472aa3642 upstream(wordpress): release-notes sources (sftp/atmoz + standing note) 2026-08-21 03:45:57 +00:00
autonomic-bot 7252f7ee35 upstream(mattermost-lts): 2026-08-21 re-check — 11.7.9 ESR is the only current LTS; PR #2 redirected to ESR 2026-08-21 03:34:36 +00:00
autonomic-bot 75386fc23b upstream(n8n): 2.36.x release-notes coverage (2.36.0 feature minor, 2.36.2/2.36.3 patches) 2026-08-21 03:28:47 +00:00
autonomic-botandClaude Opus 4.8 19abebb312 nix: split the cc-ci-specific config into its own module + flake output
The orchestrator host is a general agent box that also serves several unrelated
projects (atproto-likes, the lichen and project orchestrators, the shared
opencode web server). Everything that exists FOR cc-ci — the loops, the cc-ci
orchestrator session, the weekly recipe-upgrade run and its hourly supervisor —
now lives in nix/modules/cc-ci.nix and is exported as `nixosModules.cc-ci`, so
the two can evolve and be reviewed independently and another host can consume
just the cc-ci half.

No behaviour change. Verified by building .#cc-ci-orchestrator-hetzner after the
split: the unit set is identical to the running system, and all six cc-ci units
are byte-identical modulo nix store hashes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016L6nYYwkCWnrEFKTnKAfet
2026-08-20 16:29:02 +00:00
autonomic-bot 565e021185 Merge pull request 'config: drop plausible from weekly upgrade set (-> external)' (#13) from config/drop-plausible-weekly into main 2026-08-17 16:01:38 +00:00