diff --git a/.gitea/workflows/bump.yml b/.gitea/workflows/bump.yml new file mode 100644 index 0000000..ebbe277 --- /dev/null +++ b/.gitea/workflows/bump.yml @@ -0,0 +1,90 @@ +# Nomarchy scheduled lock bump — the automated half of "rock-stable +# without rotting": once a week, update flake.lock (inputs track pinned +# release branches, so this never jumps a NixOS release — that's a +# deliberate hand-edited v2, see agent/GOALS.md), gate it, and land it +# on main only on green. `v1` promotion stays human, always. +# +# Fast lane: workflow_dispatch. For a security fix upstream, run this +# workflow manually from the Actions tab instead of waiting for Monday. +# +# Gate scope: `nix flake check --no-build` — the same eval tier as +# check.yml (this runner has no KVM; see item 20 for the VM-suite +# upgrade path). The py_compile/bash -n steps are skipped on purpose: +# they don't read flake.lock, so a lock bump cannot break them. The +# bump commit's own push then triggers check.yml as a second net. +# A green bump therefore guards evaluation, not VM behaviour — the +# checks.* suite still runs locally / at promotion time. +# +# Failure mode: a red gate fails this run visibly and pushes nothing; +# next schedule retries. A push race (someone landed on main mid-run) +# also just fails the final push — rerun or wait a week. +# +# Container recipe (nixbld users, sandbox=false, pinned Nix, plain-shell +# install) inherited from check.yml — the gotchas are documented there. + +name: Lock bump + +on: + schedule: + - cron: '17 5 * * 1' # Mondays 05:17 UTC + workflow_dispatch: + +jobs: + bump: + runs-on: ubuntu-latest + timeout-minutes: 90 + env: + NIX_CONFIG: | + experimental-features = nix-command flakes + sandbox = false + NIX_SSL_CERT_FILE: /etc/ssl/certs/ca-certificates.crt + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Nix + run: | + NIX_VERSION=2.31.5 + groupadd -r nixbld 2>/dev/null || true + for i in $(seq 1 10); do + useradd -r -g nixbld -G nixbld -d /var/empty \ + -s /usr/sbin/nologin -c "Nix build user $i" "nixbld$i" 2>/dev/null || true + done + curl -L "https://releases.nixos.org/nix/nix-${NIX_VERSION}/install" | sh -s -- --no-daemon + echo "$HOME/.nix-profile/bin" >> "$GITHUB_PATH" + + - name: Update flake.lock + # Inputs track release branches (nixos-26.05, release-26.05), so + # the update stays within them by construction. The human-readable + # change list goes into the commit body below. + run: | + nix flake update 2>&1 | tee /tmp/bump-log + if git diff --quiet flake.lock; then + echo "Lock already up to date — nothing to do." + echo "changed=0" >> "$GITHUB_OUTPUT" + else + echo "changed=1" >> "$GITHUB_OUTPUT" + fi + id: update + + - name: Gate — nix flake check (eval only) + if: steps.update.outputs.changed == '1' + run: nix flake check --no-build + + - name: Commit + push on green + if: steps.update.outputs.changed == '1' + # The checkout step persists the Actions token, so this push + # authenticates as the workflow; its push triggers check.yml as + # the second net. Only flake.lock is committed — pathspec-limited, + # nothing else can ride along. + run: | + { + echo "chore(lock): scheduled upstream bump" + echo + grep -E '^(• | )' /tmp/bump-log || true + echo + echo "Gate: nix flake check --no-build (eval tier — see bump.yml header)." + } > /tmp/bump-msg + git -c user.name="nomarchy-bump" -c user.email="actions@git.bemagri.xyz" \ + commit --only flake.lock -F /tmp/bump-msg + git push origin HEAD:main diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index 867b01c..9954f0c 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -26,14 +26,17 @@ next, in what order*. ## NEXT -### 14. Automated upstream lock bumps (maintainer CI, slices b+c) `[big]` -ROADMAP § Automated upstream lock bumps — the scheduled half (the -checks-on-push workflow shipped; see item 20 for the runner status): -weekly job runs `nix flake update` (within pinned release branches) → -full check suite → lands on `main` on green; `v1` promotion stays -human. Plus the fast-lane note for security bumps. Note the current -runner is eval-only (no KVM) — a green bump run guards eval, not the VM -suite, until item 20's stretch runner exists. +### 14. Automated lock bumps — confirm the first real run +Slices b+c shipped 2026-07-05 (`.gitea/workflows/bump.yml`): weekly +schedule (Mon 05:17 UTC) + `workflow_dispatch` as the security +fast-lane; `nix flake update` → eval gate → pathspec-limited lock +commit pushed to `main` on green (that push triggers check.yml as the +second net). Update/commit/push logic simulated locally end-to-end in +a scratch clone, incl. a real update; today's bumped lock evals green. +Remaining (not confirmable from a session): the first scheduled or +dispatched run must land — watch that the runner picks up the cron and +that the Actions token can push. Then delete this item. Item 20's KVM +runner later upgrades the gate from eval-only to the VM suite. ### 20. KVM runner → VM suite in CI `[human]` The remaining stretch of the CI item — checks-on-push is live and diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index c79d222..c6a4a6f 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -17,6 +17,27 @@ Template: --- +## 2026-07-05 — scheduled lock-bump workflow (iteration #26, item 14 b+c) +- **Task:** BACKLOG NEXT#14 `[big]` — split: (a) checks-on-push shipped + earlier; this ships (b) the weekly bump + (c) the fast-lane as + workflow_dispatch on the same job. +- **Did:** .gitea/workflows/bump.yml — Mon 05:17 UTC cron + dispatch: + nix flake update (pinned branches by construction) → gate `nix flake + check --no-build` (py_compile/bash -n skipped: they don't read the + lock) → commit --only flake.lock with the update's change list as + body → push main (triggers check.yml as second net). Red gate/push + race = failed run, nothing lands. Container recipe from check.yml. +- **Verified:** V0 (yq parse + bash -n each run block); logic simulated + end-to-end in a scratch clone with a REAL nix flake update + bare + remote: changed/unchanged branches, bystander file stays uncommitted, + push lands; today's bumped lock evals green (Monday's baseline). + Gitea 1.25.4 confirmed (schedule supported). The real cron pickup + + token push are NOT confirmable from here → item 14 slimmed to + "confirm first run". +- **Pending:** watch the first scheduled/dispatched bump run. +- **Next suggestion:** #16 greeter theming (next codeable item; #15 + needs its design pass written first). + ## 2026-07-05 — color picker (iteration #25, item 13 final slice → item done) - **Task:** BACKLOG NEXT#13 last slice — hyprpicker → clipboard from the menu + a direct bind. Item 13 complete; deleted from BACKLOG. diff --git a/agent/MEMORY.md b/agent/MEMORY.md index 8a91b73..90a50c0 100644 --- a/agent/MEMORY.md +++ b/agent/MEMORY.md @@ -13,6 +13,9 @@ iteration would otherwise rediscover. `sandbox=false` for Stylix IFD, Nix pinned 2.31.5 vs lazy-trees, no JS actions past node20) — learned over the legacy repo's 57 runs; read them before touching the workflow. +- The Gitea instance is **1.25.4** — `on: schedule` workflows are + supported; bump.yml assumes the Actions token can push to `main` + (standard Gitea behaviour, but unconfirmed until the first run lands). - The git server is **Gitea** (gitea/act_runner via docker-compose), NOT Forgejo — workflows are read from `.gitea/workflows/` (or `.github/`), never `.forgejo/workflows/` (a whole push cycle was lost to that).