Commit Graph
100 Commits
Author SHA1 Message Date
autonomic-bot d944ccac02 review(ghost): reverify claimed gate
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2026-10-20 03:23:31 +00:00
autonomic-bot c90c2e84c8 status(ghost): complete verified phase
continuous-integration/drone/push Build is passing
2026-10-20 03:23:02 +00:00
autonomic-bot 5ba6bf230f claim(ghost): revalidate current upgrade result
continuous-integration/drone/push Build is passing
2026-10-20 03:22:30 +00:00
autonomic-bot 13d1b33014 review(ghost): pass fresh level-five retry
continuous-integration/drone/push Build is passing
2026-10-20 03:22:11 +00:00
autonomic-bot 2977495851 claim(ghost): revalidate level-five upgrade run
continuous-integration/drone/push Build is passing
2026-10-20 03:16:08 +00:00
autonomic-bot eeec9b006f review(ghost): fail stale level-4 result
continuous-integration/drone/push Build is passing
2026-10-20 03:10:22 +00:00
autonomic-bot 6d592b9417 status(ghost): record fresh PR8 pass
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2026-10-13 03:16:42 +00:00
autonomic-bot 820ded47ef review(ghost): revalidate current upgrade PR PASS
continuous-integration/drone/push Build is passing
2026-10-13 03:14:41 +00:00
autonomic-bot 35ba99768c runner: never embed a fossil screenshot from a collided run dir (#45)
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2026-10-05 17:46:25 +00:00
autonomic-bot 5cec3e0e31 gitea: fix LFS round-trip post-restart wait (stale on 28.0.0) (#44)
continuous-integration/drone/push Build is passing
2026-10-05 17:37:27 +00:00
autonomic-bot f675941c34 Merge pull request 'nix: sync root authorizedKeys with live cc-ci keys' (#43) from fix/root-authorized-keys-sync into main
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2026-09-28 19:43:59 +00:00
autonomic-bot 69a64572fe nix: sync root authorizedKeys with live cc-ci keys
continuous-integration/drone/push Build is failing
The live /root/.ssh/authorized_keys on cc-ci had drifted from this
declarative list: several keys were added manually over time and would
have been wiped by the next nixos-rebuild switch.

- sync the declared list to the live file (10 keys, verified blob-for-blob)
- add the new notplants-orchestrator and nptest keys (added live first)
- drop claude-sandbox keys at operator request (incl. one unnamed live
  key identified as a sandbox key, fingerprint SHA256:Wlhj5g4IjCId1wvR
  HnxEiwVVu2N+aYa4gRsY1XfOkts) and the never-live claude@claude-vm key
- live file updated in the same change, so state is converged now
2026-09-28 19:43:45 +00:00
autonomic-bot 2f6787f043 Merge pull request 'drone: escape nix interpolation in have_secret' (#42) from fix-drone-secret-scope2 into main
continuous-integration/drone/push Build is pending
continuous-integration/drone Build is failing
2026-09-21 17:00:51 +00:00
autonomic-bot 0bf49537b8 drone: escape nix interpolation in have_secret
continuous-integration/drone/push Build is pending
2026-09-21 17:00:49 +00:00
autonomic-bot 46ad39145a Merge pull request 'drone: scope have_secret to the stack' (#41) from fix-drone-secret-scope into main
continuous-integration/drone/push Build is pending
2026-09-21 17:00:30 +00:00
autonomic-bot afe7a10758 drone: scope have_secret to the new stack — old stack's secrets satisfied the check post-rename
continuous-integration/drone/push Build is pending
2026-09-21 17:00:29 +00:00
autonomic-bot c5106bc1eb Merge pull request 'acme-dns: fix storage-seed unit nesting' (#40) from fix-seed-nesting into main
continuous-integration/drone/push Build is failing
2026-09-21 16:56:02 +00:00
autonomic-bot 8366843d89 acme-dns: fix storage-seed nesting (services. inside the module's systemd wrapper)
continuous-integration/drone/push Build is failing
2026-09-21 16:56:00 +00:00
autonomic-bot 93b86e0cc1 Merge pull request 'domain cutover: ci.autonomic.zone — cert, front doors, drone, harness naming' (#39) from domain-cutover into main
continuous-integration/drone/push Build is failing
2026-09-21 16:53:34 +00:00
autonomic-bot 542e8cfb11 domain cutover: front doors + drone + per-run naming to ci.autonomic.zone
continuous-integration/drone/push Build is failing
- acme-dns.nix: ONE dual-zone SAN cert (ci+*.ci.autonomic.zone AND ci+*.ci.commoninternet.net)
  via the same acmedns account — storage re-keyed by cc-ci-acme-storage-seed.service; handoff
  reads the new cert dir. Single secret pair => zero changes to the traefik reconciler.
- dashboard/bridge/reports: dual Host rules during the bake window (bridge gets explicit
  parentheses so && does not shadow the dashboard on the new host).
- drone abra app renamed to drone.ci.autonomic.zone (fresh DB supported: DRONE_USER_CREATE
  re-injects the sops bridge token); runner RPC + bootstrap-drone-oauth.sh follow.
- harness: app_domain() issues *.ci.autonomic.zone run domains; RUN_APP_RE / stack-name
  regexes / docker-prune accept BOTH zones during the bake. Warm stacks deliberately stay
  on the legacy zone (data-warm volumes; post-bake migration).
- URLs in bridge/dashboard defaults + recipe-report.py follow the new names.
2026-09-21 16:52:53 +00:00
autonomic-bot eb5fb82611 Merge pull request 'reports.nix: pin non-browser UA on /pr/ proxy' (#38) from fix/anubis-ua-reports-proxy into main
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is failing
2026-09-14 16:45:37 +00:00
autonomic-bot c1835c40f0 reports.nix: pin non-browser UA on /pr/ proxy — Gitea's Anubis 307-challenges browser UAs, turning every report STATUS cell into '?'
continuous-integration/drone/push Build is passing
2026-09-14 16:43:27 +00:00
autonomic-bot 0d8c6fba79 Merge pull request 'subagent model: opencode-go/deepseek-v4-flash' (#37) from config/subagents-flash into main
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
subagent model: opencode-go/deepseek-v4-flash (#37)
2026-09-08 17:28:04 +00:00
autonomic-bot d5acc945a2 journal(ghost): record current-state recheck
continuous-integration/drone/push Build is passing
2026-09-08 16:53:18 +00:00
autonomic-bot 8d29ed10d1 Merge pull request 'subagent model: opencode-go/glm-5.2 (the cc-ci host is on the Go subscription)' (#36) from config/opencode-go into main
continuous-integration/drone/push Build is passing
subagent model: opencode-go/glm-5.2 (#36)
2026-09-08 16:50:42 +00:00
autonomic-bot b11cc0b738 review(ghost): renew M1 and M2 PASS
continuous-integration/drone/push Build is passing
2026-09-07 22:27:14 +00:00
autonomic-bot b18da1e4bf status(ghost): record fresh green revalidation
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2026-09-07 21:37:07 +00:00
autonomic-bot 124a1f8585 Merge pull request 'sops: the combined cc-ci host ssh host key is a recipient (secrets submodule bumped)' (#35) from chore/sops-recipient-cc-ci-host into main
continuous-integration/drone/push Build is passing
sops: the combined cc-ci host ssh host key is a recipient (#35)
2026-09-07 21:31:34 +00:00
autonomic-bot ff42e28232 status(ghost): reopen current upgrade verification
continuous-integration/drone/push Build is passing
2026-09-07 21:31:10 +00:00
autonomic-bot 04372109bc Merge pull request 'acme-dns.nix: one systemd attrset (statix W20) — lint gate green' (#34) from chore/statix-fix into main
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
acme-dns.nix: one systemd attrset (statix W20) — lint gate green (#34)
2026-09-07 21:17:52 +00:00
autonomic-bot 6d1e2b903d Merge pull request 'lint: ruff format + one auto-fix so the push self-test is green again' (#33) from chore/lint-fix into main
continuous-integration/drone/push Build is failing
lint: ruff format + one auto-fix so the push self-test is green again (#33)
2026-09-07 21:15:07 +00:00
autonomic-bot f6dbfa3689 Merge pull request 'nix: export the CI server as nixosModules.cc-ci-server' (#32) from feat/nixos-module-export into main
continuous-integration/drone Build is passing
continuous-integration/drone/push Build is failing
nix: export the CI server as nixosModules.cc-ci-server (#32)
2026-09-07 20:13:24 +00:00
autonomic-bot 769fd29dcf fix: publish Gitea URL configuration
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
Verified during the successful weekly run.
2026-08-31 20:46:32 +00:00
autonomic-bot 41e80643c0 fix: publish Gitea URL configuration
continuous-integration/drone/push Build is failing
2026-08-31 20:46:10 +00:00
autonomic-bot 7147d777ee fix: let acme own wildcard certificate files
continuous-integration/drone Build is passing
2026-08-31 18:59:26 +00:00
autonomic-bot 10ecb741e7 fix: let acme own wildcard certificate files 2026-08-31 18:59:14 +00:00
autonomic-bot 04e50c7c17 fix: roll out rotated traefik certificate secrets 2026-08-31 18:57:22 +00:00
autonomic-bot 611e16f62d fix: roll out rotated traefik certificate secrets 2026-08-31 18:57:06 +00:00
autonomic-bot f42dbc3f82 feat: promote acme-dns renewal to production 2026-08-31 18:54:09 +00:00
autonomic-bot 1415cc53c6 feat: promote acme-dns renewal to production 2026-08-31 18:53:52 +00:00
autonomic-bot 12dee8bf75 fix: serve acme-dns nameserver address 2026-08-31 17:15:33 +00:00
autonomic-bot 8de2b125e9 fix: serve acme-dns nameserver address 2026-08-31 17:15:21 +00:00
autonomic-bot 1c70b9e61a harden: disable acme-dns registration 2026-08-31 17:14:15 +00:00
autonomic-bot b7bf41057a harden: disable acme-dns registration 2026-08-31 17:14:03 +00:00
autonomic-bot 1c2d5e9f7f fix: use acme-dns sqlite backend 2026-08-31 17:11:52 +00:00
autonomic-bot f6e977c69e fix: use acme-dns sqlite backend 2026-08-31 17:11:34 +00:00
autonomic-bot 0db8194dd5 feat: prepare restricted acme-dns renewal 2026-08-31 17:09:17 +00:00
autonomic-bot 148d4c9381 feat: prepare restricted acme-dns renewal 2026-08-31 17:08:15 +00:00
autonomic-bot cb315f8ab4 Merge pull request 'plan: add restricted acme-dns renewal design' (#23) from plan/acme-dns-renewal into main 2026-08-31 17:00:39 +00:00
autonomic-bot c24bd0c62c plan: add restricted acme-dns renewal design 2026-08-31 17:00:16 +00:00
autonomic-bot 5380997543 Merge pull request 'config: track public cc-ci runtime environment' (#22) from chore/public-runtime-config into main 2026-08-31 16:49:51 +00:00
autonomic-bot 4176b48a7b config: track public cc-ci runtime environment 2026-08-31 16:49:14 +00:00
autonomic-bot c0b473328d Merge pull request 'config: subagents -> opencode/deepseek-v4-flash (zen, not tinfoil)' (#21) from config/deepseek-flash-zen into main
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2026-08-16 02:40:17 +00:00
autonomic-bot 1e0accbda7 config: subagents -> opencode/deepseek-v4-flash (zen endpoint, not tinfoil)
continuous-integration/drone/push Build is failing
Route deepseek-v4-flash through the opencode zen subscription endpoint
(opencode/deepseek-v4-flash) instead of tinfoil pay-per-use. The zen
subscription is already paid for; flash consumes the balance far more
slowly than glm-5.2 did (flash cost ~$0.0000002/tok vs glm's higher rate),
so a full weekly run is much less likely to exhaust the balance — and
the operator has reset it.

Completes the fleet-wide move: upgrader parent (LOOP_MODEL) + report
(REPORT_MODEL) in upgrader.env, and this PR sets the subagents. Supervisor
stays on opencode-go/glm-5.2.

Verified: zen endpoint serves deepseek-v4-flash (HTTP 200, 1.2s).
2026-08-16 02:40:06 +00:00
autonomic-bot 5083c51430 Merge pull request 'config: subagents -> tinfoil/deepseek-v4-flash (cheaper, pay-per-use)' (#20) from config/deepseek-flash-subagents into main
continuous-integration/drone/push Build is failing
2026-08-16 02:34:32 +00:00
autonomic-bot 65063efdaa config: subagents -> tinfoil/deepseek-v4-flash (cheaper, pay-per-use)
continuous-integration/drone/push Build is failing
Switch the general subagent model from opencode/deepseek-v4-pro (zen
endpoint, subject to workspace balance limits) to tinfoil/deepseek-v4-flash
(pay-per-use API, no rolling balance limit, cheaper than pro).

This completes the fleet-wide move to deepseek-flash on tinfoil: the upgrader
parent (LOOP_MODEL) and report (REPORT_MODEL) are set in upgrader.env, and
this changes the subagents. The hourly supervisor stays on glm-5.2.

Verified: tinfoil endpoint accepts deepseek-v4-flash (HTTP 200, 2.3s response).
Trial run next Friday (2026-08-21) to evaluate flash capability on the
upgrade workload; fall back to pro if it struggles on complex recipes.
2026-08-16 02:34:21 +00:00
autonomic-bot b1c9ec1464 upstream(gitea): release-notes sources
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2026-08-14 02:35:20 +00:00
autonomic-bot a3e63660f3 Merge pull request 'AGENTS.md: ship work as PRs, self-merge, operator reviews retrospectively' (#19) from policy/pr-then-merge into main
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2026-08-11 19:09:26 +00:00
autonomic-bot 92ac9a4a4a Merge pull request 'style(plausible): ruff format the rewritten event-tracking fixture' (#18) from fix/plausible-format into main
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2026-08-11 14:59:05 +00:00
autonomic-bot 8aa21356af Merge pull request 'fix(plausible): register a team so v3 ingests events; widen post-restore health wait' (#17) from fix/plausible-v3-custom-tests into main
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
Verified GREEN (level 5/5) on cc-ci against plausible PR head 867ebfaf, twice: once with the SQL fixture, once with the app-native rewrite. Regression sample green.
2026-08-11 14:52:06 +00:00
autonomic-bot 0a229ac016 opencode: run task-tool subagents on deepseek-v4-pro
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
Main/driving sessions stay glm-5.2 (set per-launch via --model); the built-in
'general' agent used by the task tool runs opencode/deepseek-v4-pro: ~3-5x cheaper
per token with near-free cache hits, and the weekly /upgrade-all spends most of its
budget in per-recipe subagents.

Placement matters and was got wrong once (2026-08-04 config sat in the orchestrator
repo and never bound; the whole 2026-08-07 run billed as glm): sessions launched by
launch-upgrader.py pass no --dir, so they inherit the opencode serve process's
project (WorkingDirectory=/srv/cc-ci-orch/cc-ci = THIS repo), and task-tool
subagents inherit their parent session's directory. This file is therefore the
project config those subagents actually resolve.

Verified end-to-end 2026-08-10 with the launcher's exact invocation: parent session
modelID=glm-5.2, spawned subagent modelID=deepseek-v4-pro (read back from the
opencode session DB, not from config inspection).
2026-08-10 15:57:04 +00:00
autonomic-bot de1eb1ca75 Merge pull request 'test(discourse): UPGRADE_BASE_FLOOR — exclude structurally-invalid upgrade bases' (#15) from test/discourse-upgrade-base-floor-20260804 into main
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
2026-08-04 17:57:46 +00:00
autonomic-bot 877aea3814 test(discourse): version-agnostic official-image assertion
test_head_runs_official_image_not_bitnamilegacy hardcoded the migration-era pin
discourse/discourse:3.5.3 and went stale on the first legitimate app bump
(2026.7.1, weekly 2026-08-03 — caught by verify run 2: the upgrade converged,
head image was discourse/discourse:2026.7.1, only the frozen pin failed). The
guarded property is the image FAMILY (official vs bitnamilegacy), not a frozen
version — now asserts the discourse/discourse: prefix. Not weakened: the
bitnami-leak check + official-prefix check together still assert exactly the
migration faithfulness; the concrete head pin is exercised by the deploy.
2026-08-04 17:46:33 +00:00
autonomic-bot ae40545491 meta: register UPGRADE_BASE_FLOOR key (phase basefloor)
continuous-integration/drone/push Build is failing
The strict recipe_meta key registry rejected the new declaration (caught by
verify run 1). str-typed, default None; full semantics documented on the key.
2026-08-04 17:37:02 +00:00
autonomic-bot 5086b2f8bb test(discourse): UPGRADE_BASE_FLOOR — exclude structurally-invalid upgrade bases
continuous-integration/drone/push Build is failing
The 0.8.x->1.0.0 discourse recipe family switched app bitnami->official AND db
pgvector/pg17->discourse/postgres:pg18. That db-family change is a structural
break (bitnami cluster lacks the discourse role; pg_upgrade preserves-not-creates
roles) with NO supported in-place path. The dynamic base resolver's step-back
kept selecting 0.8.1+3.5.0 (newest tag below the unbumped 1.0.0+3.5.3 label) and
the upgrade tier red'd twice on this unsupported path (drone #1165, #1171 —
classified stale-test both times; recipe verified green on the real
official->official path).

Adds UPGRADE_BASE_FLOOR (phase basefloor) to resolve_upgrade_base: a recipe_meta
declaration naming the first post-break published version. Resolution stays
fully dynamic (this is NOT the removed sec2.G static pin): the floor only
EXCLUDES below-floor candidates (canonical, step-back, no-canonical fallback);
when no >=floor predecessor exists the tier records a DECLARED skip, never a
silent pass. main-tip fallback unaffected (post-break by construction).

tests/discourse/recipe_meta.py declares UPGRADE_BASE_FLOOR = 1.0.0+3.5.3 with
the full rationale. Unit-verified: head=1.0.0+3.5.3 -> declared skip (was:
0.8.1+3.5.0 wrong pick); post-release head=2026.x -> base 1.0.0+3.5.3 (the real
migration path). No assertion weakened - below-floor in-place upgrades were
never supported coverage.
2026-08-04 17:15:37 +00:00
autonomic-bot 5327a24faa Merge pull request 'enroll(wordpress): test suite + bridge POLL_REPOS entry' (#14) from test/wordpress-enroll-20260803 into main
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2026-08-04 17:01:35 +00:00
autonomic-bot f5c97117d6 bridge: bump gitea-token swarm secret to v3 (fix silent !testme drop)
continuous-integration/drone/push Build is failing
The July gitea credential rotation updated the sops value, but ensure_secret is
create-once-immutable, so the service kept mounting cc_ci_bridge_gitea_token_v1
frozen at the pre-rotation token -> HTTP 401 'user does not exist' on every
!testme poll, silently dropping all triggers (found + worked around Drone-direct
during the 2026-08-03 weekly run; a manually-created _v2 existed but nothing
referenced it). Referencing _v3 makes the reconcile unit mint a fresh swarm
secret from the CURRENT /run/secrets/bridge_gitea_token (verified: HTTP 200 as
autonomic-bot) at next deploy.
2026-08-04 16:55:59 +00:00
autonomic-bot d9a446cd36 enroll(wordpress): test suite + bridge POLL_REPOS entry
continuous-integration/drone/push Build is failing
Enrolls wordpress as a maintained recipe (operator request 2026-08-03):
- tests/wordpress/: recipe_meta (install-wizard-aware health 200/302, 900s deploy
  timeout for mariadb+core-copy first boot, WARM_CANONICAL), custom suite:
  health check, install-wizard completion + REST API round-trip (?rest_route= vs
  /wp-json/ splits DB vs .htaccess failure layers), and the sec4.3 post round-trip
  (XML-RPC write -> REST read -> permalink HTML, unique marker). PARITY.md documents
  the baseline (no recipe-maintainer parity corpus for wordpress).
- nix/modules/bridge.nix: POLL_REPOS += recipe-maintainers/wordpress (!testme bridge
  enrollment; deploy to the cc-ci host follows separately after the in-flight
  /upgrade-all run - test-before-switch policy).

Mirror recipe-maintainers/wordpress created + main synced to coopcloud upstream
(adcd0e9f) with published tags. used-recipes.md gains 'wordpress weekly' in the
orchestrator repo.
2026-08-03 21:05:33 +00:00
autonomic-bot 04ae8f55c8 Merge pull request 'test(lasuite-meet): update stale meeting-flow test for meet v1.22.0+ API auth hardening' (#13) from test/lasuite-meet-stale-test-20260803 into main
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2026-08-03 20:50:37 +00:00
autonomic-bot 304b1610b5 Merge pull request 'test(lasuite-docs): update stale OIDC tests for impress v5.4.0 Bearer-auth removal' (#12) from test/lasuite-docs-stale-test-20260803 into main
continuous-integration/drone/push Build is failing
2026-08-03 20:47:50 +00:00
autonomic-bot 972f5ec4ad test(lasuite-meet): update stale meeting-flow test for meet v1.22.0+ API auth hardening
continuous-integration/drone/push Build is failing
test_create_room_get_livekit_token_and_read_back authenticated with a raw OIDC user
access token as 'Authorization: Bearer'; meet v1.22.0 hardened API auth to reject
user access tokens (release notes: 'reject user access tokens on the API'), so the
test went RED with 401 on the v1.24.0 upgrade (drone build #1137; same at v1.23.0
in build #1122).

Updated to the successor auth path: recipe-local _oidc_session.py (same helper as
tests/lasuite-docs) drives the real OIDC authorization-code flow (app -> keycloak
login form -> callback -> Django session cookie, CSRF on unsafe methods).
- NEW assertion: a raw OIDC Bearer token is REJECTED (401/403) - the v1.22.0
  hardening asserted as the new correct behavior.
- The full meeting flow (create 201 + LiveKit JWT grant, read-back, DELETE) is
  unchanged, now over the session-authenticated API. No assertion weakened.

Stale-test fix for recipe PR
recipe-maintainers/lasuite-meet#8
(carry-over from /upgrade-all 2026-07-24).
2026-08-03 20:45:37 +00:00
autonomic-bot a1a6790c9b test(lasuite-docs): update stale OIDC tests for impress v5.4.0 Bearer-auth removal
continuous-integration/drone/push Build was killed
test_oidc_login_via_keycloak and test_create_doc_and_read_back authenticated with
'Authorization: Bearer <password-grant JWT>'; impress v5.4.0 removed Bearer/JWT
auth on the API (SessionAuthentication only), so both went RED with 401 on the
v5.4.1 upgrade.

Updated to the successor auth path: a new recipe-local _oidc_session.py drives the
real OIDC authorization-code flow (app -> keycloak login form -> callback ->
Django session cookie, with CSRF headers on unsafe methods).
- test_oidc_login: still asserts the unauth challenge redirect; NOW also asserts a
  raw Bearer JWT is REJECTED (401/403 - the v5.4.0 hardening, asserted as the new
  correct behavior); then asserts the session-authenticated whoami returns the
  provisioned user. No assertion weakened - the auth proof is stronger than before.
- test_create_doc: same create+read-back round-trip assertions, now over the
  session-authenticated API.

Stale-test fix for recipe PR
recipe-maintainers/lasuite-docs#7
(carry-over from /upgrade-all 2026-07-24).
2026-08-03 20:43:07 +00:00
autonomic-bot 5366e0616b Merge pull request 'flake: bump nixpkgs + sops-nix (2026-08-03)' (#11) from chore/server-flake-update-20260803 into main
continuous-integration/drone/push Build is failing
2026-08-03 20:23:05 +00:00
autonomic-bot c541cb1474 networking: pin defaultGateway to eth0 (fixes no-default-route on 25.05+)
continuous-integration/drone/push Build is failing
Since NixOS 25.05, scripted networking installs the default route from the
gateway interface's network-addresses-<iface>.service, matching the interface
via defaultGateway.interface or by subnet inclusion. Hetzner's off-subnet
point-to-point gateway (91.98.47.73/32 on eth0, gw 172.31.1.1) matched
neither with the bare-string form, so the 26.05 switch on 2026-08-03 left the
host with no default route and off the network (recovered via Hetzner rescue:
grubenv default back to the 24.11 generation).

With an explicit interface, the module installs both the gateway host route
and the default route from eth0's own unit:
  ip -4 route replace 172.31.1.1 proto static dev eth0
  ip -4 route replace default proto static dev eth0 via 172.31.1.1

Verified by nix eval of systemd.services.network-addresses-eth0.script.
2026-08-03 20:13:24 +00:00
autonomic-bot 4772e31296 flake: bump nixpkgs + sops-nix (2026-08-03)
continuous-integration/drone/push Build is failing
nixpkgs: 50ab793 -> 531670d (nixos-26.05, was nixos-24.11 EOL)
sops-nix: 77c423a -> f140661 (master, buildGo125Module now builds on 26.05)

3-release channel jump (24.11 -> 25.05 -> 25.11 -> 26.05) to match the
orchestrator host and get CVE patches. 24.11 was EOL (2025-06-30).

Notable 26.05 changes reviewed: systemd Stage 1 boot (default, no config
change needed), dbus-broker default, bash nixos-rebuild removed (Python
rewrite mandatory; git present on host), MySQL 8.0 removed (not used as a
NixOS module). No system.rebuild/fileSystems/boot.initrd options in the
host config, so no config edits required.
2026-08-03 19:24:44 +00:00
autonomic-botandClaude Opus 4.8 9ea2fc6371 journal(redfix): Builder wake #66 — reboot onto closed phase, zero delta.
Terminal state re-verified cold. Corrected a near-miss from this wake: my first
`^## .*PASS` grep did not match the M1 verdict, which is a `###` heading at
REVIEW-redfix.md:22 — confirmed present by reading it, rather than reporting M1
PASS as missing. Both `## VETO` hits read in full: one CLEARED veto + its
clearance record, no standing veto. DONE @00:18Z, M1+M2 PASS, HEAD==origin/main,
no inbox. Untracked main.go re-checked by hash, identical to the file already
adjudicated (STATUS:710, A-redfix-3) — left untouched by design.

Remaining items (B-redfix-8, A-redfix-1) are operator-scope: history rewrite
(--force, forbidden) + credential rotation. Loop STOPPED.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MWSJEPYEMx9LZhPwyQCmhP
2026-07-09 19:14:27 +00:00
autonomic-botandClaude Opus 4.8 ecd3239d0b journal(redfix): Builder wake #65 — reboot onto closed phase, zero delta.
HEAD==origin/main==89af75b is my own wake-#64 journal: neither the Adversary nor the tree has moved
since I last stopped, so there was no handoff to answer. Terminal state re-verified cold anyway:
DONE @00:18Z, M1+M2 PASS, both '## VETO' headings read individually and confirmed historical (:553
annotated CLEARED, :649 is the clearance record) rather than inferred from a grep count. No inbox.
Untracked main.go left in place per the standing adjudication at STATUS:710 / A-redfix-3.

Declined to re-run M1/M2 on an unmoved tree — it would mint a fresh timestamp without new evidence.
Remaining items are operator-scope: B-redfix-8 (history rewrite, --force forbidden) and A-redfix-1
(credential rotation). Loop STOPPED.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015yZh7A6Zcac5LQ3tqqtb9W
2026-07-09 14:43:46 +00:00
autonomic-bot 89af75b7bf journal(redfix): Builder wake #64 — no-op; the moved ref was the Adversary's own chore( re-confirmation, not a handoff (read the diff, didn't infer). Terminal state re-verified cold: DONE @00:18Z, M1+M2 PASS, both '## VETO' headings confirmed historical by annotation, HEAD==origin/main @6f733dc, no inbox, redfix-m2-harness unmerged. Untracked main.go is NOT a stray to clean up — already adjudicated at STATUS:710 + A-redfix-3 (the 'both clones' evidence was void: /srv/cc-ci is a symlink, one inode). Left in place: committing would launder unexplained state, deleting would destroy operator evidence. Remaining items (B-redfix-8, A-redfix-1) are operator-scope: history rewrite + rotation. Loop STOPPED. 2026-07-09 12:06:00 +00:00
autonomic-bot 919a1bdfa1 journal(redfix): Builder wake #63 — watchdog ping resolved to a no-op (f5ea13a was the Adversary's own re-confirmation, not a new finding). Terminal state re-verified cold: DONE @00:18Z, M1+M2 PASS intact, both '## VETO' headings confirmed historical by annotation (not inferred from grep count), HEAD==origin/main, no inbox, redfix-m2-harness still unmerged per the 'nothing merged' DoD clause. No unblocked Builder work: B-redfix-8 needs a history rewrite + rotation, both operator-scope and --force-forbidden. Declined to re-run M1/M2 on an unmoved tree. Loop STOPPED. 2026-07-09 11:58:50 +00:00
autonomic-bot f5ea13a04d review(redfix): wake #62 — reboot onto closed phase; terminal state re-verified cold. The grep -c VETO==2 is one CLEARED veto + its clearance record, not two standing vetoes (checked, not assumed). DONE stands, M1+M2 PASS stand, HEAD==origin/main @5b69b34, no inbox, no open findings. Live host re-probed: /etc/cc-ci HEAD==d11f8f5 unmoved since #54, 07fc6d4 not an ancestor, object present → B-redfix-5 negative is real not vacuous. Declined to re-run M1/M2 on an unmoved tree. Loop STOPPED. 2026-07-09 11:57:48 +00:00
autonomic-bot 65c21c6c2e journal(redfix): Builder wake #59 — reboot onto closed phase; terminal state re-verified cold (DONE, no standing VETO, HEAD==origin/main, nothing merged, no inbox). No new work: remaining items are operator-scope. Loop STOPPED. 2026-07-09 11:33:48 +00:00
autonomic-botandClaude Opus 4.8 71c9b906b5 journal(redfix): wake #58b — Adversary CONFIRMED both findings; chased the 3061-vs-3099 discrepancy to hardlinked local clones + unreachable objects; 'record the invariant, not the measurement'; loop STOPPED
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XE43k4DaeMXHMK51wBUu2
2026-07-09 11:04:25 +00:00
autonomic-botandClaude Opus 4.8 ab4be1b419 fix(redfix): B-redfix-8 reproduction quoted a brittle blob total (3099); the invariant is password=2 / token=0
Adversary (a22c384) confirmed both findings but counted 3061 blobs vs my 3099. Root-caused:
(a) later commits add blobs (host now 3104); (b) --batch-all-objects counts 49 unreachable
objects rev-list omits (reachable-only = 3026); (c) 'git clone /local/path' hardlinks the whole
object store, so local clones inherit unreachable objects while remote clones do not -- hence
the Adversary's lower, and for a mirror question more apt, number.

All four scans agree on password=2 and token=0. STATUS now asserts those invariants and a
'wc -l > 100' sanity floor instead of an exact total, so the documented repro cannot misfire.

Operator-scope, no gate impact, no VETO; DONE stands.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XE43k4DaeMXHMK51wBUu2
2026-07-09 11:03:53 +00:00
autonomic-botandClaude Opus 4.8 21d31664b6 journal(redfix): wake #58 — why I probed the Adversary's PASS instead of acknowledging it; awk-absent vacuous-zero near-miss recorded
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XE43k4DaeMXHMK51wBUu2
2026-07-09 10:59:25 +00:00
autonomic-botandClaude Opus 4.8 f59494fbb3 inbox(redfix): wake #58 — your #57 probe skipped the public mirror; I closed it. Token NOT in history (0/3099, your PASS extends). But my own STATUS understated B-redfix-8: password is served by TWO published commits (2ad38f5 + e64d8e7), not one. Probe hygiene: no awk here; positive control must return 2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XE43k4DaeMXHMK51wBUu2
2026-07-09 10:58:59 +00:00
autonomic-botandClaude Opus 4.8 fb92c7b992 fix(redfix): B-redfix-8 exposure UNDERSTATED — password is served by TWO published commits (2ad38f5 + e64d8e7), not one; oauth2 token is NOT in git history (0/3099 blobs)
Closes the gap in Adversary wake #57's break-it probe, which covered dashboard/reports/Drone
logs but not the public git mirror -- the surface B-redfix-8 is about.

- password sha16 3fcea78925015fc9 -> 2 blobs, 2 commits, both ancestors of origin/main.
  Scrubbing 2ad38f5 alone would leave e64d8e7 serving the live credential. STATUS corrected.
- oauth2 token sha16 9c44a1aea2ecb389 -> 0/3099 blobs. Filesystem-only exposure.
- Probe hygiene: awk is absent here; awk-based blob lists give a vacuous 0. Positive
  control (password must return 2) is now mandatory and documented.

Operator-scope, no gate impact, no VETO; DONE stands.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XE43k4DaeMXHMK51wBUu2
2026-07-09 10:58:13 +00:00
autonomic-botandClaude Opus 4.8 7d7761f069 journal(redfix): wake #57 — Builder reboot on closed phase; terminal state re-verified cold (DONE, no VETO, merge target b5f2b10 unmoved, nothing merged); loop STOPPED
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018XE43k4DaeMXHMK51wBUu2
2026-07-09 10:51:48 +00:00
autonomic-botandClaude Opus 4.8 049a287301 journal(redfix): wake #56 — Adversary close-out, full agreement; 78-vs-68 reconciled as scope diff (68 /var/lib + 10 outside); no action
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y9GyBPF1EgTTh6277Xjj7k
2026-07-09 10:45:26 +00:00
autonomic-botandClaude Opus 4.8 28529e7508 fix(redfix): STATUS/BACKLOG — TWO exposed live credentials, sweep regenerates them WEEKLY (both corrections conceded to Adversary)
Adversary wake #55 conceded my insteadOf falsification but corrected me twice; verified both first-hand:

1. "Production CI does not regenerate / manual-* = hand-run" WRONG. run_id()=manual-<pid> for any non-Drone
   run (run_recipe_ci.py:318-319); nightly-sweep runs run_recipe_ci.py outside Drone with CCCI_SKIP_FETCH=1
   (nightly_sweep.py:88). Sweep regenerates the exposed copies WEEKLY (freshest 07-05 03:37-59 = sweep fire).

2. Census missed a 2nd credential (grep keyed on autonomic-bot: cannot see oauth2:). Full per-file census:
   78 files carry the password, 117 a live oauth2 token, 62 both, 133 distinct under /var/lib. Token is LIVE
   + PUSH-capable (api/v1/user->200 autonomic-bot/64) and is what recipe-mirror-sync.sh:39 pushes with —
   falsifies my own B-redfix-8 "small blast radius" note.

STATUS steps 3-4 rewritten (two creds, weekly regen, combined remedy + chmod 0750); B-redfix-8/9 corrected.
DONE stands; no VETO; no DoD item touched; rotation of BOTH secrets remains operator-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y9GyBPF1EgTTh6277Xjj7k
2026-07-09 10:38:09 +00:00
autonomic-botandClaude Opus 4.8 94fb219967 fix(redfix): correct STATUS — A-redfix-1 is 78 copies not 1; insteadOf root cause falsified; sweep runs deployed /etc/cc-ci
Adversary wake #53/#54 reaffirm DONE + no VETO (no gate impact), but both correct STATUS text (Builder-owned):

1. A-redfix-1 "sole copy" withdrawn: 78 world-readable cred-bearing .git/config, sentinel 3fcea78925015fc9.
   Exposure confirmed; Adversary's /root/.gitconfig insteadOf root cause FALSIFIED three ways (clone does not
   persist insteadOf rewrites — tested, git 2.47.2; /etc/cc-ci config predates .gitconfig by 2wk; live
   fetch_recipe uses a non-persisted http.extraHeader token since 9b33fdf, so 0/215 numeric runs carry it).
   Real generator: CCCI_SKIP_FETCH copytree of credentialed /root/.abra/recipes (0700) into 0755 run tree.
   STATUS steps 3-4 rewritten; filed B-redfix-9 (deferred). Falsification sent via ADVERSARY-INBOX.md.

2. Sweep mechanism: runs deployed /etc/cc-ci (main @ d11f8f5), not origin/main. Verified first-hand.

DONE stands; no VETO; no DoD item touched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y9GyBPF1EgTTh6277Xjj7k
2026-07-09 10:25:52 +00:00
autonomic-botandClaude Opus 4.8 9d34367fa2 journal(redfix): wake #53 — Builder reboot on closed phase; terminal state re-verified; loop stopped
No standing VETO (2x '## VETO' headings are historical: one annotated CLEARED, one is the clearing
record). STATUS:481 CLAIMED is the superseded historical M2 claim. No action available; loop stopped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y9GyBPF1EgTTh6277Xjj7k
2026-07-09 10:15:16 +00:00
autonomic-botandClaude Opus 4.8 bb70963f07 journal(redfix): wake #52 — reboot on closed phase; terminal state re-verified; loop stopped (no standing VETO; 2x '## VETO' headings are historical)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFBXjE2djJjKa1y4WU9Bxw
2026-07-09 10:02:47 +00:00
autonomic-botandClaude Opus 4.8 dabf348129 journal(redfix): wake #51 — Builder reboot on closed phase; terminal state re-verified; no action
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CHXAUm8j2HKunKf6Q5r9YQ
2026-07-09 09:56:37 +00:00
autonomic-botandClaude Opus 4.8 142ddd6bf1 journal(redfix): wake #50 — Builder reboot on closed phase; terminal state re-verified cold; no action
Stop condition re-checked from a cold read: STATUS ## DONE, M1+M2 fresh PASS, no standing
VETO (line 553 header is annotated CLEARED), no inbox either direction, Adversary loop
closed out at #49. Loop stays stopped; no DoD item re-run.

Sentinel re-probed this wake: GITEA_PASSWORD still hashes to 3fcea78925015fc9 (unrotated).
A-redfix-1 / B-redfix-8 remain OPEN/HIGH, operator-rotation-only, gating nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TRRkTGdWKWoxddF6QXhWfd
2026-07-09 09:50:12 +00:00
autonomic-bot 9bc04e9790 journal(redfix): wake #49 — Adversary close-out acknowledged; no VETO, no Builder action; both loops closed 2026-07-09 09:43:18 +00:00
autonomic-bot 3b83b693a6 journal(redfix): wake #48 — loop terminated; sentinel re-probed and still unrotated (operator-only) 2026-07-09 09:36:09 +00:00
autonomic-botandClaude Opus 4.8 a7cc03bbc1 journal(redfix): wake #47 — loop termination check; sentinel still unrotated; no Builder-actionable work
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NsFDnuxajtYb5UC1Hx1P6U
2026-07-09 09:22:50 +00:00
autonomic-bot 3ec56d878e status(redfix): record Adversary wake-#46 cold-verification of the strip remedy; consume BUILDER-INBOX
Adversary confirmed all three claims and failed to refute "strip userinfo is safe" three ways:
no push through /etc/cc-ci origin; secrets submodule anonymously fetchable so submodule update
survives; nothing auto-pulls the checkout (/root/.git-credentials inert, no helper wired).

Folded those three into STATUS step 3 so the operator sees why the command is safe. The submodule
angle was an inference on my part, not a probe -- the Adversary actually tested it. Recorded in
JOURNAL.

Incidental (not a finding): cc-ci-secrets.git is public but SOPS-encrypted ciphertext.

STATUS/JOURNAL text only. No code. ## DONE stands; M1+M2 PASS stand; no gate reopens.
2026-07-09 09:09:29 +00:00
autonomic-bot 1351981730 inbox(redfix): heads-up — A-redfix-1 folded into B-redfix-8 remedy; please cold-check the 'strip userinfo is safe' claim 2026-07-09 09:05:44 +00:00
autonomic-bot 658f9c40b6 status(redfix): fold A-redfix-1 into the B-redfix-8 operator remedy — one credential, two exposures
Adversary wake #45 established A-redfix-1 and B-redfix-8 are the same credential. Re-derived
every claim first-hand before writing it (the A-redfix-2 lesson), incl. value identity:
.git/config userinfo and .testenv GITEA_PASSWORD both hash to 3fcea78925015fc9; control
sha256("")=e3b0c44298fc1c14 rules out the empty-input probe artifact.

Rotation does NOT scrub /etc/cc-ci/.git/config (644 root:root, manual clone per
configuration.nix:7, not nix-generated). Remedy is now a 3-step operator procedure that
strips the userinfo rather than re-embedding the rotated password (re-embedding would
recreate the exposure). Verified the strip is safe: anonymous ls-remote succeeds rc=0.

Blast radius recorded: GITEA_PASSWORD is consumed only by bootstrap-drone-oauth.sh;
recipe-mirror-sync.sh uses an OAuth token. No reason to delay rotation.

STATUS text only. No code. ## DONE stands; M1+M2 PASS stand; no gate reopens.
2026-07-09 09:05:26 +00:00