From 5cc7599af37be8279d6fe41458326e6c1ed64a54 Mon Sep 17 00:00:00 2001 From: Yu Sun Date: Wed, 15 Jul 2026 16:26:47 +0800 Subject: [PATCH] refactor: extend upstream maintenance policy --- AGENTS.md | 2 +- CONTRIBUTING.md | 18 +++--- flake.lock | 24 ++++++- flake.nix | 7 +++ homes/ysun/default.nix | 9 --- scripts/maint/README.md | 8 +-- scripts/maint/ci-cache-gate.sh | 27 +++++--- scripts/maint/policy-overrides.json | 14 +++++ scripts/maint/policy.json | 97 ----------------------------- 9 files changed, 76 insertions(+), 130 deletions(-) create mode 100644 scripts/maint/policy-overrides.json delete mode 100644 scripts/maint/policy.json diff --git a/AGENTS.md b/AGENTS.md index 156457a..f705ffc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,7 +60,7 @@ Do not reintroduce long-lived mutable proxy files for steady-state Nix behavior. - Keep Codex updates upstream-owned. Do not reintroduce a downstream headless `maint-refresh-codex`; `116` receives Codex updates by updating the `upstream` flake input after upstream refreshes the official OpenAI release binary pin. - Renovate may update only the `upstream` flake input automatically. The CI cache gate stubs `yazelix-next` because GitHub Actions cannot rely on Lucca's private repository SSH access; do not broaden this automation to private or downstream-owned inputs without a new explicit decision. - Keep routine tool updates binary-friendly. Before adding inputs to the tools maintenance group, consider whether they normally use binary caches or upstream-provided release binaries instead of expensive local source builds. Put low-frequency infrastructure inputs such as `sops-nix`, `impermanence`, and `disko` in the infra maintenance group instead. -- `scripts/maint/policy.json` mirrors the upstream maintenance gate policy so `maint-switch --repo /home/ysun/github.com/sctmes/dotfiles` can read current markers before activation. If a gate blocks a clearly generated glue derivation, fix the upstream policy narrowly, refresh the downstream mirror/input, and do not bypass the gate or allowlist heavy components. +- `scripts/maint/policy-overrides.json` contains only downstream maintenance markers; the effective policy is `lib.maintenancePolicy`, composed from the locked upstream base plus these overrides. If a gate blocks a clearly generated shared glue derivation, fix the upstream base narrowly and refresh the input; keep company-only markers in the overlay. Do not bypass the gate or allowlist heavy components. - Diagnose network failures by fetch path: Nix substituters, GitHub release/direct fetches, npm registry or node-gyp, Cargo registries, and runtime proxies are separate paths and should not be collapsed into one generic proxy fix. - Long-term upstream direction: prefer a lighter reusable/headless flake boundary so headless downstream hosts do not see desktop-only upstream inputs in routine maintenance. - `scripts/install-116.nu` is the canonical install entrypoint. Keep examples aligned with `nu ./scripts/install-116.nu root@192.168.0.116 --proxy http://:`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 07b780a..0ee727d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,15 +47,15 @@ git commit -m "chore: update upstream dotfiles" maint-switch --no-pull ``` -本仓库的 `scripts/maint/policy.json` 显式转发 upstream 的维护门控策略,供 -`maint-switch --repo /home/ysun/github.com/sctmes/dotfiles` 在新系统激活前读取。 -更新 upstream 时,如果 upstream 的 `scripts/maint/policy.json` 变了,也要同步更新 -本仓库的转发文件。 - -如果 `maint-switch` 因轻量生成式 glue derivation 被拦住,先修 upstream policy, -再更新本仓库的 `upstream` input 和 `scripts/maint/policy.json`;不要直接绕过 gate, -也不要把 kernel、driver、Hyprland、GCC/Rust toolchain、Chromium/Electron 等重组件 -加入 allowlist。 +本仓库的 `scripts/maint/policy-overrides.json` 只声明公司专属的维护门控规则。 +`maint-switch --repo /home/ysun/github.com/sctmes/dotfiles` 在新系统激活前读取 flake +输出的 `lib.maintenancePolicy`;该有效策略由锁定的 upstream 共享基线和本仓库的窄 +overlay 合成,不需要复制 upstream 的完整 policy。 + +如果 `maint-switch` 因共享的轻量生成式 glue derivation 被拦住,先修 upstream +policy,再更新本仓库的 `upstream` input;公司专属 derivation 才加入 +`scripts/maint/policy-overrides.json`。不要直接绕过 gate,也不要把 kernel、driver、 +Hyprland、GCC/Rust toolchain、Chromium/Electron 等重组件加入 allowlist。 网络问题需要按路径拆分:Nix cache、GitHub release/direct fetch、npm registry 或 node-gyp、Cargo registry 和运行时代理不是同一个问题。 diff --git a/flake.lock b/flake.lock index 3da2024..096aaf6 100644 --- a/flake.lock +++ b/flake.lock @@ -1225,6 +1225,23 @@ "type": "github" } }, + "shadcn-improve": { + "flake": false, + "locked": { + "lastModified": 1781504319, + "narHash": "sha256-m0a1n8xguDI2nooJ856sWPofh+tZI5VvIrVZrQH6XgY=", + "owner": "shadcn", + "repo": "improve", + "rev": "03369ee6d7cafbfcecc4346539b05b3dc0a603bb", + "type": "github" + }, + "original": { + "owner": "shadcn", + "repo": "improve", + "rev": "03369ee6d7cafbfcecc4346539b05b3dc0a603bb", + "type": "github" + } + }, "sops-nix": { "inputs": { "nixpkgs": [ @@ -1391,17 +1408,18 @@ ], "nixpkgs-tools": "nixpkgs-tools", "nixpkgs-wechat": "nixpkgs-wechat", + "shadcn-improve": "shadcn-improve", "sops-nix": [ "sops-nix" ], "swww": "swww" }, "locked": { - "lastModified": 1783668819, - "narHash": "sha256-Zn3IpZk6Fkpqg6lUaSuWcXabh+I49Lr+Ady5Y5qoCM0=", + "lastModified": 1784103861, + "narHash": "sha256-ixzEv/vtPZUz3Bpnt1z1PPqOfmDWPbE/56SK2325fYs=", "owner": "bioinformatist", "repo": "dotfiles", - "rev": "516186d56a41d63ec67ae2c55991b59ec1cfd61a", + "rev": "8d10211367b86c5a5030c4763c0cecdd9b08192e", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 086752f..49a61ae 100644 --- a/flake.nix +++ b/flake.nix @@ -44,8 +44,15 @@ inherit inputs; username = "ysun"; }; + maintenancePolicy = upstream.lib.extendMaintenancePolicy upstream.lib.maintenancePolicyBase ( + builtins.fromJSON (builtins.readFile ./scripts/maint/policy-overrides.json) + ); in { + lib = { + inherit maintenancePolicy; + }; + devShells.${system} = { reactive-resume = pkgs.mkShell { packages = with pkgs; [ diff --git a/homes/ysun/default.nix b/homes/ysun/default.nix index 938cf6e..817403f 100644 --- a/homes/ysun/default.nix +++ b/homes/ysun/default.nix @@ -4,11 +4,6 @@ pkgs, ... }: -let - upstreamMaintPolicy = builtins.fromJSON ( - builtins.readFile "${inputs.upstream}/scripts/maint/policy.json" - ); -in { imports = [ inputs.upstream.homeManagerModules.devHeadless @@ -31,10 +26,6 @@ in enable = true; repo = "/home/ysun/github.com/sctmes/dotfiles"; host = "116"; - riskMarkers = upstreamMaintPolicy.riskMarkers ++ [ - "docker" - "containerd" - ]; }; programs.git = { diff --git a/scripts/maint/README.md b/scripts/maint/README.md index 0123af8..bcaadfd 100644 --- a/scripts/maint/README.md +++ b/scripts/maint/README.md @@ -1,6 +1,6 @@ # Maintenance Policy -`policy.json` mirrors `bioinformatist/dotfiles/scripts/maint/policy.json`. -Keep it aligned when updating the `upstream` flake input so -`maint-switch --repo /home/ysun/github.com/sctmes/dotfiles` can read the current -gate markers before the next system generation has activated. +`policy-overrides.json` contains only SCTMES-specific maintenance markers. The +flake exposes `lib.maintenancePolicy` by extending the policy base from its +locked `upstream` input, so `maint-switch` and CI evaluate the same target policy +before activation. diff --git a/scripts/maint/ci-cache-gate.sh b/scripts/maint/ci-cache-gate.sh index f660e98..bf47a69 100755 --- a/scripts/maint/ci-cache-gate.sh +++ b/scripts/maint/ci-cache-gate.sh @@ -50,14 +50,27 @@ EOF collect_blocked_derivations() { local repo="$1" - local policy_repo="$2" - local output_file="$3" - local direct_file="$4" + local output_file="$2" + local direct_file="$3" local dry_run_output="${tmp}/dry-run-$(basename "$repo").log" + local policy_file="${tmp}/policy-$(basename "$repo").json" : > "$output_file" : > "$direct_file" + if [[ -f "${repo}/scripts/maint/policy.json" \ + && ! -f "${repo}/scripts/maint/policy-workstation.json" \ + && ! -f "${repo}/scripts/maint/policy-overrides.json" ]]; then + # Revisions from before the flake policy interface stored one complete policy. + cp "${repo}/scripts/maint/policy.json" "$policy_file" + else + nix eval \ + --json \ + --override-input yazelix-next "path:${tmp}/yazelix-next-stub" \ + "${repo}#lib.maintenancePolicy" \ + > "$policy_file" + fi + if ! ( cd "$repo" nix build \ @@ -77,10 +90,10 @@ collect_blocked_derivations() { awk '/^[[:space:]]*\/nix\/store\/.*\.drv$/ { sub(/^[[:space:]]+/, ""); print }' "$dry_run_output" | sort -u ) mapfile -t allowed_markers < <( - jq -r '.allowedLocalBuildMarkers[]' "${policy_repo}/scripts/maint/policy.json" + jq -r '.allowedLocalBuildMarkers[]' "$policy_file" printf '%s\n' "-yzn-ci-stub.drv" ) - mapfile -t direct_markers < <(jq -r '.allowedDirectFetchMarkers[]' "${policy_repo}/scripts/maint/policy.json") + mapfile -t direct_markers < <(jq -r '.allowedDirectFetchMarkers[]' "$policy_file") local drv for drv in "${derivations[@]}"; do @@ -108,8 +121,8 @@ head_direct="${tmp}/head.direct" new_blocked="${tmp}/new.blocked" new_direct="${tmp}/new.direct" -collect_blocked_derivations "${tmp}/base" "$PWD" "$base_blocked" "$base_direct" -collect_blocked_derivations "$PWD" "$PWD" "$head_blocked" "$head_direct" +collect_blocked_derivations "${tmp}/base" "$base_blocked" "$base_direct" +collect_blocked_derivations "$PWD" "$head_blocked" "$head_direct" comm -13 "$base_blocked" "$head_blocked" > "$new_blocked" comm -13 "$base_direct" "$head_direct" > "$new_direct" diff --git a/scripts/maint/policy-overrides.json b/scripts/maint/policy-overrides.json new file mode 100644 index 0000000..6b961c0 --- /dev/null +++ b/scripts/maint/policy-overrides.json @@ -0,0 +1,14 @@ +{ + "riskMarkers": [ + "docker", + "containerd" + ], + "allowedLocalBuildMarkers": [ + "-futu-opend-10.8.6818.drv", + "-futu-opend-service.drv", + "-futu-opend.service.drv" + ], + "allowedDirectFetchMarkers": [ + "Futu_OpenD_10.8.6818_Ubuntu18.04.tar.gz" + ] +} diff --git a/scripts/maint/policy.json b/scripts/maint/policy.json deleted file mode 100644 index 950ae06..0000000 --- a/scripts/maint/policy.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "_forwardedFrom": "bioinformatist/dotfiles/scripts/maint/policy.json", - "riskMarkers": [ - "nvidia-x11", - "linux-", - "mesa-", - "systemd-", - "hyprland", - "hyprlang", - "hyprutils", - "hyprgraphics", - "hyprwayland-scanner", - "hyprwire", - "gcc-", - "xgcc", - "rustc-", - "cargo-vendor", - "chromium", - "electron", - "serenityos-emoji-font", - "nanoemoji" - ], - "allowedLocalBuildMarkers": [ - "hm_", - "home-manager-path", - "home-manager-files", - "home-manager-generation", - "user-environment", - "user-units", - "X-Restart-Triggers-", - "unit-", - "unit-home-manager-", - "-nix.conf.drv", - "X-Restart-Triggers-nix-daemon", - "unit-nix-daemon", - "-activation-script.drv", - "-dbus-1.drv", - "-dry-activate.drv", - "-hwdb.bin.drv", - "-manifest-for-users.json.drv", - "-manifest.json.drv", - "-hm-session-vars.sh.drv", - "-persistence-run-create-directories.drv", - "-system-generators.drv", - "-system-path.drv", - "-system-shutdown.drv", - "-system-units.drv", - "-set-environment.drv", - "-tmpfiles.d.drv", - "-udev-rules.drv", - "-user-generators.drv", - "-users-groups.json.drv", - "-etc-", - "-etc.drv", - "-ensure-all-wrappers-paths-exist.drv", - "-helix-25.07.1.drv", - "-boot.json.drv", - "-activate.drv", - "nixos-system-", - "-openai.yaml.drv", - "-SKILL-header.md.drv", - "-SKILL.md.drv", - "-skill.drv", - "-codex-config.toml.drv", - "-context7-auth-mcp-server.drv", - "-github-mcp-server.drv", - "-playwright-cli.drv", - "-codex-improve-exec.drv", - "-zeroclaw-daemon.service.drv", - "-appimage-exec.sh.drv", - "-orca-ide-", - "-futu-opend-10.8.6818.drv", - "-futu-opend-service.drv", - "-futu-opend.service.drv" - ], - "allowedDirectFetchMarkers": [ - "-codex-x86_64-unknown-linux-musl.tar.gz", - "-codex-0.", - "-orca-linux.AppImage", - "Futu_OpenD_10.8.6818_Ubuntu18.04.tar.gz", - "-zeroclaw-x86_64-unknown-linux-gnu.tar.gz", - "-zeroclaw-0." - ], - "leafDirectFetchMarkers": { - "codex": [ - "-codex-x86_64-unknown-linux-musl.tar.gz", - "-codex-0." - ], - "orca": [ - "-orca-linux.AppImage" - ], - "zeroclaw": [ - "-zeroclaw-x86_64-unknown-linux-gnu.tar.gz", - "-zeroclaw-0." - ] - } -}