docs(audit): batch-46 — upload-lane quotas/lifecycle, tracker #8/#1, release-pipeline smoke

Real-machine closure for everything batched since batch 45: #75/#76 verified
end to end on auditfix77 (cooldowns 429, pending cap 403, 2GiB budget 403 via
the real accounting path, failure-does-not-burn-window, withdraw/admin-delete
row+blob double clean, panel two-step confirms in CDP), tracker #8 and #1
landed and verified (#77 panel redirect, #78 felis converge), plus #79 docs.
Also: pgint's new assertions first run on real PG (17/17) and the release
pipeline's first-ever run — tag v0.1.0-rc1, multiarch assets published and
executed on the target arch, /releases/latest deliberately untouched.
This commit is contained in:
Lemon-miaow committed 2026-09-24 11:11:07 +08:00
1 parent b9ebc872ad
commit 34caed5fed
1 file changed
+54 -1
+54 -1
View File
@@ -45,7 +45,7 @@ IPv6-only 接入(`ssh -6 -i ~/.ssh/id_ed25519 root@fdb2:2c26:f4e4:0:21c:42ff:f
| 14 | controller-runtime 日志噪音 | ✅ 修复:SetLogger 接 slog(`a415246`) | | 14 | controller-runtime 日志噪音 | ✅ 修复:SetLogger 接 slog(`a415246`) |
| 15 | reaper 启用未演练 | ✅ 已演练(见"第二日"节;CronJob 仍 `suspend=true` 防误删) | | 15 | reaper 启用未演练 | ✅ 已演练(见"第二日"节;CronJob 仍 `suspend=true` 防误删) |
## 可达性分级(#1–#74;#62 立案后剔除)——这些缺陷真实使用中到底谁能踩到 ## 可达性分级(#1–#79;#62 立案后剔除)——这些缺陷真实使用中到底谁能踩到
回应质疑"是不是全在测边界条件 / 只有内部 hook 才能触发": 回应质疑"是不是全在测边界条件 / 只有内部 hook 才能触发":
@@ -130,6 +130,8 @@ IPv6-only 接入(`ssh -6 -i ~/.ssh/id_ed25519 root@fdb2:2c26:f4e4:0:21c:42ff:f
第四十五批追加:#69(README 中英"审批通过后自动构建**并部署**"过度承诺——数据模型无目标服务器、部署实为"选用该镜像";① 轻);#70(kaniko 拉内建底座默认 HTTPS——`--insecure` 只覆盖推,任何 `FROM registry.felis.svc:5000/…` 构建必败 ①);#71(kaniko 以 drop-ALL 解包底座层,chown 必败——任何非 scratch 底座必败 ①);#72(trivy 扫 jar 必拉 Java DB、被 egress 锁拒绝——含 jar 即所有真实模组包的构建必败 ①);#73(bootstrap 测试在跑 k3s 的主机上必假失败 ④ 工具);#74(console 断连测试读写竞态 flaky ④ 工具)。 第四十五批追加:#69(README 中英"审批通过后自动构建**并部署**"过度承诺——数据模型无目标服务器、部署实为"选用该镜像";① 轻);#70(kaniko 拉内建底座默认 HTTPS——`--insecure` 只覆盖推,任何 `FROM registry.felis.svc:5000/…` 构建必败 ①);#71(kaniko 以 drop-ALL 解包底座层,chown 必败——任何非 scratch 底座必败 ①);#72(trivy 扫 jar 必拉 Java DB、被 egress 锁拒绝——含 jar 即所有真实模组包的构建必败 ①);#73(bootstrap 测试在跑 k3s 的主机上必假失败 ④ 工具);#74(console 断连测试读写竞态 flaky ④ 工具)。
第四十六批追加:#75(提交上传面无上限——pending 无个数上限、无存储预算、create/upload 无节流;一个账号可无限堆积上下文刷爆 uploads PVC ①);#76(提交无撤回/管理员删除路径——提交者无法自救、运维无法回收占用 ①);#77(未完成引导的会话触发受保护操作 → 面板显示"无权执行此操作"而非送往 /setup;tracker #8 ①);#78(create-if-absent 使新增 CR 字段在已装机永不落地——lobby 无 RCON 故控制台死、玩家数恒 0;tracker #1 ②);#79(troubleshooting [INERT] 图例指向已不存在字段 ④ 文档)。
## 已验证事实(正向清单) ## 已验证事实(正向清单)
- 安装→hook 发码→Owner 绑定→passkey(虚拟认证器)→面板管理员全链路 ✅ - 安装→hook 发码→Owner 绑定→passkey(虚拟认证器)→面板管理员全链路 ✅
@@ -851,6 +853,52 @@ IPv6-only 接入(`ssh -6 -i ~/.ssh/id_ed25519 root@fdb2:2c26:f4e4:0:21c:42ff:f
- 升级滚动撞 kubelet **ephemeral-storage 压力**:auditfix64 滚动时新 api/operator pod `Pending 4m46s`(事件 `untolerated taint(s)`),02:58:12 kubelet eviction manager 回收后自动调度成功。诱因 = 构建把根盘压到 89%(docker 构建缓存 + kaniko/emptyDir 临时层);`docker builder prune -af` 两清共回收 ~11G,余 11G free。生产清单:根盘 ≥40G + 升级前清构建缓存(与批 44 注记合并)。 - 升级滚动撞 kubelet **ephemeral-storage 压力**:auditfix64 滚动时新 api/operator pod `Pending 4m46s`(事件 `untolerated taint(s)`),02:58:12 kubelet eviction manager 回收后自动调度成功。诱因 = 构建把根盘压到 89%(docker 构建缓存 + kaniko/emptyDir 临时层);`docker builder prune -af` 两清共回收 ~11G,余 11G free。生产清单:根盘 ≥40G + 升级前清构建缓存(与批 44 注记合并)。
- 中间失败构建留下的 registry 镜像(`user-uploads/sub-83f6…`、`sub-171e…` = 已推未过门;`sub-c006…` = capstone 产物)留档;测试服 `test-one` 已回 `felis/paper:demo` + Stopped;docker 停。 - 中间失败构建留下的 registry 镜像(`user-uploads/sub-83f6…`、`sub-171e…` = 已推未过门;`sub-c006…` = capstone 产物)留档;测试服 `test-one` 已回 `felis/paper:demo` + Stopped;docker 停。
### 本轮新增真机证据(第四十六批:上传面 #75/#76 真机闭环 + tracker #8/#1 收口 #77/#78 + 文案 #79 + 发布链 rc smoke)
**零、现场**:代码三条 commit 先落(`43699b4` #77 面板跳转、`c57daaf` #78 converge、`b9ebc87` #79 INERT 文案),随后按 `b9ebc87` 重建镜像 = `registry.felis.svc:5000/felis/felis:auditfix77`(`v0.0.0+fix77`;宿主源 `10.43.182.43:5000`,docker build → push),控制面 api/operator + minecraft ns `felis-reaper` CronJob + api/operator 的 `FELIS_IMAGE` 四处成对齐;`/opt/felis/src` = b9ebc87 快照(上一版 `src.bak46`);宿主 drill 二进制 `/root/felis-fix77.bin`(Mac 侧 `GOOS=linux GOARCH=arm64` 交叉编译,`-X main.version=v0.0.0+fix77`)。
**一、#75 真机闭环(配额/限流,owner 会话,auditfix77)**——留档 `/root/probe77/create-lane.log`、`lane2.log`:
- **create 失败不烧窗口**:坏 JSON → 400,**同一秒**合法 create → 201(`sub-811427aa7dcf6807`)——`release` 路径生效;
- **create 冷却**:同用户 30s 内第二条 → 429 `submission_cooldown`;
- **pending 上限**:攒到 5 条 pending → 第 6 条 → 403 `submission_quota_exceeded`;
- **upload 失败不烧窗口**:对已审核行上传 → 409 `already_reviewed`,**同一秒**对 pending 行上传 → 200;
- **upload 冷却**:15s 内第二次 → 429 `submission_cooldown`;等 16s → 200;
- **存储预算**:把 S2 的 blob 稀疏 `truncate` 到让 owner 已存字节 = 2GiB−100B(`blocks=8`,不占盘)→ 上传 → 403 `submission_quota_exceeded`;管理员删除 S2(行 + 目录双清)后 → 同一上传 → 200(预算即时释放)。
- 口径:预算按 blob 的实际占用聚合(`Blobs.Size` 遍历汇总,正是"用久了就超"的同一条读取路径);稀疏垫付只是把"已经存了 2GiB 的用户"这一状态合成出来。
**二、#76 真机闭环(撤回 + 管理员删除)**——留档 `/root/probe77/lane3.log`:
- 撤回自己 pending → 200;DB 行 = 0、uploads 目录 = gone;重复撤回 → 404;对已审核 → 409 `already_reviewed`;对他人 id → 404 `not_found`(owner 判定先于状态判定,不泄露他人行状态);
- 管理员删除(pending)→ 200;重复 → 404;行与 blob 双清(lane2 的 S2 同证:`s2 rows=0 dir=gone`);
- 面板侧 CDP:**撤回两步确认**(展开行 → 「撤回提交」→「确认撤回」→ 行消失)与 **admin 队列每行两步删除**(trash →「确认删除」→ 行消失、计数回落)双双走过;截图 `/tmp/withdraw-{1,2}-*.png`、`/tmp/admdelete-{1,2}-*.png`(Mac),脚本 `/tmp/cdp-withdraw76.js`、`/tmp/cdp-admdelete76.js`。
- 真机注记(非缺陷,分级 ZT 的对照实证):admin 面只在 `op.console.<root>` 主机可用——同一 owner 会话在玩家面板主机上 `is_admin=false`(admin 路由 403),在 `op.console.<root>` 上 `is_admin=true`(200);面板按要求显示「无权访问」而不是假装能点。
**三、#77(tracker #8,`43699b4`)真机闭环:锁定会话 → /setup**
- 铸一个未完成引导会话(SQL:`sha256('drill-locked-77')` → `sessions`,用户 `3f2c1b0a-…`,`email_verified=f`、无 passkey)→ `GET /me` 200、`GET /me/submissions` → 403 `setup_required`(后端本就正确);
- CDP 用该 cookie 打开 `/submissions`:页面请求 `/me/submissions` 收 403(code=`setup_required`)→ **自动跳转 `/setup`**(`location.href` 实测)→ 向导渲染「初始化你的账户 / 第一步 · 填写邮箱」(截图 `/tmp/setup8-redirect.png`;网络事件 = 200/403(/setup/status 200) 序列在脚本输出里)。
- 顺带确认:Dashboard 首屏三请求(`/me`、`/me/servers`、`account/link/start`)都是 `SetupAllowed`——所以补丁前用户是在"点受保护操作"时才撞到那句误报「无权执行此操作」。
**四、#78(tracker #1,`c57daaf`)真机演练:`felis converge`**
- 现场先剥后补:`kubectl patch` 清空 lobby `spec.rcon` 与 login `spec.startup.healthHTTPPort`(复刻老装机 CR 缺后加字段的状态)→ `/root/felis-fix77.bin converge` → 两条全部填回(`rcon{enabled:true,secretRef:lobby-rcon/password}`、`healthHTTPPort:8080`);**第二次运行 → 双双 `already converged`**(幂等);operator 侧滚动收尾,login/lobby 回 Running/Ready(日志 `converge-{1,2}.log`、`crs-before.yaml`)。
- 语义边界(单测):非零值一律不碰(运维自换的 secretRef 生还)、缺席 CR 只提示(创建仍归 setup)、占名非系统角色 CR 拒绝收敛、未配镜像跳过。
**五、#79(`b9ebc87`,文档)**:troubleshooting 的 `[INERT]` 图例仍写「§12 列着唯一仍适用的字段」,而唯一候选 `spec.storage.retainOnDelete` 早已移除、§12 自述「每个字段都有 controller 读」。改为「今天没有字段处于该状态」并指向 §13 的移除记录。
**六、发布链 rc smoke(tag `v0.1.0-rc1` → release run `35949621233`)**:
**六、发布链 rc smoke(tag `v0.1.0-rc1` → release run `35949621233`):首次全绿**
- run 步骤实况:go vet/test ✅ → `plugins/test.sh` ✅ → `plugins/test-mods.sh` ✅(**release.yml 史上第一次真正跑这三关**)→ buildx 双架构构建 ✅ → **stamp 校验** ✅(`felis v0.1.0-rc1` + arm64 ELF 断言)→ publish ✅;
- 产物释出:`felis-linux-amd64`(61,378,722 B)与 `felis-linux-arm64`(57,344,162 B)双资产,release 标记 `prerelease=true`;
- **prerelease 语义复核**:`GET /repos/FelisMC/Felis/releases/latest` → **404**(RC 没有顶掉 latest——正是 release.yml 注释里防的那件事);bootstrap 默认通道在无 stable 时按设计给出显式指引后 die、`felis update` 的 404 报错可读——两个行为本批均实测;
- 产物级复验(目标架构实机):arm64 资产 scp 到 VM 执行 → `felis v0.1.0-rc1`(`go1.26.8 linux/arm64`),且直接可用:`/root/felis-rc1.bin converge` 打现集群 → 双服 `already converged`;
- 留档:`/root/felis-rc1.bin`;asset 副本 Mac `/tmp/rc1b/felis-linux-arm64`。
- 剩余(产物决定,未代拍板):仓库仍无 **stable** release → 新装走默认 release 通道会以指引性报错 die(提示改 dev 或等 stable);切首个稳定 tag(如 `v0.1.0`)即让默认通道与 `felis update` 真正上线,建议维护者择时执行。
**七、运维注记(非缺陷)**
- pg_hba 的 `host felis_pgint felis 127.0.0.1/32 scram-sha-256` 行**再次丢失**(批 31 补过一次)——补回并 reload 后 pgint 才能连。重装/动过 PG 后先查这条(已写进速查)。
- 升级域注记:#75/#76 的 pgint 新断言(`CountPendingSubmissionsBy`、`DeletePendingSubmission`/`DeleteSubmission` CAS)首次上真 PG:**17/17 全绿**。
- 根盘:镜像构建后 83% → `docker builder prune -af` 回收 3.5G,docker 停回 inactive。
- CI:`43699b4` success;`c57daaf` 被后一 commit 的并发策略取消(同分支 cancel-in-progress),其树被 `b9ebc87` 的 success 完整覆盖;`b9ebc87` success。
- tracker 收编:**关** #10/#20/#21/#22(#20→`d9246dd`、#21→`f5a76cf`、#22→`3f2b28d`、#10→`23792d6`,均附证据评论)+ **关** #1/#8(本轮实现并真机验证);**注记**(保持打开作老装机待办)#2/#3/#4;**留存** #9/#12/#13/#15(真增强,超出生产可用主干,未动)。
## 结论:离"生产可用"还差什么(按优先级) ## 结论:离"生产可用"还差什么(按优先级)
1. ~~构建链路的上下文通道~~ ✅ **已修**(`f79e5eb`/`02fd2de`,真机全链路含拉回校验;Trivy DB 需按 §8e 镜像一次)。 1. ~~构建链路的上下文通道~~ ✅ **已修**(`f79e5eb`/`02fd2de`,真机全链路含拉回校验;Trivy DB 需按 §8e 镜像一次)。
@@ -880,6 +928,10 @@ IPv6-only 接入(`ssh -6 -i ~/.ssh/id_ed25519 root@fdb2:2c26:f4e4:0:21c:42ff:f
25. ~~内建底座构建(`FROM registry.felis.svc:5000/…`)~~ ✅ **已修并真机闭环**(第四十五批三连修:#70 拉取缺 `--insecure-pull`、#71 drop-ALL 卡解包、#72 trivy Java DB 未镜像——"真实模组包"形态的三个必踩点;修复后 paper 底座构建 27s Complete、`paper.jar` 扫描 0 漏洞)。 25. ~~内建底座构建(`FROM registry.felis.svc:5000/…`)~~ ✅ **已修并真机闭环**(第四十五批三连修:#70 拉取缺 `--insecure-pull`、#71 drop-ALL 卡解包、#72 trivy Java DB 未镜像——"真实模组包"形态的三个必踩点;修复后 paper 底座构建 27s Complete、`paper.jar` 扫描 0 漏洞)。
26. ~~提交 → 装服 → 起服 闭环~~ ✅ **已演练**(第四十五批 capstone:构建产物 PATCH 为服务器镜像〔白名单门通过〕→ wake → Running 1/1 → 用户 marker 可读 + `Done (4.678s)!`;test-one 已复原为 paper:demo/Stopped)。 26. ~~提交 → 装服 → 起服 闭环~~ ✅ **已演练**(第四十五批 capstone:构建产物 PATCH 为服务器镜像〔白名单门通过〕→ wake → Running 1/1 → 用户 marker 可读 + `Done (4.678s)!`;test-one 已复原为 paper:demo/Stopped)。
27. ~~文档与测试工具面~~ ✅ **已修**(第四十五批:#69 README 部署承诺对齐实现;#73 bootstrap 测试密闭化〔VM 140 PASS〕;#74 console 断连测试消抖;CI 全绿)。 27. ~~文档与测试工具面~~ ✅ **已修**(第四十五批:#69 README 部署承诺对齐实现;#73 bootstrap 测试密闭化〔VM 140 PASS〕;#74 console 断连测试消抖;CI 全绿)。
28. ~~提交上传面的上限与生命周期~~ ✅ **已修并真机闭环**(第四十六批:#75 per-user create/upload 冷却〔429〕、pending ≤5〔403〕、2GiB 存储预算〔403〕;#76 撤回〔owner+pending CAS〕与管理员删除〔行+blob 双清〕;面板两步确认 CDP 全绿)。
29. ~~未完成引导的导航(tracker #8)~~ ✅ **已修并真机闭环**(第四十六批 #77:`403 setup_required` → 自动 `/setup`;CDP 复验)。
30. ~~已装机系统服的新增 CR 字段(tracker #1)~~ ✅ **已修并真机闭环**(第四十六批 #78:`sudo felis converge`——零值才填、非零不覆写;剥字段→填回→幂等三连真机过)。
31. ~~troubleshooting `[INERT]` 图例~~ ✅ **已修**(第四十六批 #79,文档级)。
## 剩余待演练队列(截至第四十三批) ## 剩余待演练队列(截至第四十三批)
@@ -925,3 +977,4 @@ IPv6-only 接入(`ssh -6 -i ~/.ssh/id_ed25519 root@fdb2:2c26:f4e4:0:21c:42ff:f
- 第四十三批追加(#68)留档:控制面 api/operator/reaper 镜像 + api/operator `FELIS_IMAGE` = `registry.felis.svc:5000/felis/felis:auditfix63`(`felis version` = `v0.0.0+fix63`;升级时 `set image` 与 `FELIS_IMAGE` env 必须成对改,否则构建 Job 的 fetch 容器会悄悄用旧镜像);`/opt/felis/src` = `b76d0ac` 快照(上一版 `src.bak43` = `2755e41`);复刻 Job `/root/job68-new.json`(由红证据 Job `build-bld-1790187851749257160` 派生:换名 `build-retry68`、剥 controller uid 标签与 selector、镜像改 auditfix63、复用 `felis-service-token` Secret);重演验证法:`kubectl -n felis scale deploy/felis-api --replicas=0` → `kubectl -n felis-build create -f /root/job68-new.json` → `kubectl -n felis-build logs <pod> -c context-fetch`(应见 `connection refused; retrying`)→ `scale --replicas=1` → Job 收敛 `Complete`;对照:api 在线直构成功且 fetch 日志无重试行。 - 第四十三批追加(#68)留档:控制面 api/operator/reaper 镜像 + api/operator `FELIS_IMAGE` = `registry.felis.svc:5000/felis/felis:auditfix63`(`felis version` = `v0.0.0+fix63`;升级时 `set image` 与 `FELIS_IMAGE` env 必须成对改,否则构建 Job 的 fetch 容器会悄悄用旧镜像);`/opt/felis/src` = `b76d0ac` 快照(上一版 `src.bak43` = `2755e41`);复刻 Job `/root/job68-new.json`(由红证据 Job `build-bld-1790187851749257160` 派生:换名 `build-retry68`、剥 controller uid 标签与 selector、镜像改 auditfix63、复用 `felis-service-token` Secret);重演验证法:`kubectl -n felis scale deploy/felis-api --replicas=0` → `kubectl -n felis-build create -f /root/job68-new.json` → `kubectl -n felis-build logs <pod> -c context-fetch`(应见 `connection refused; retrying`)→ `scale --replicas=1` → Job 收敛 `Complete`;对照:api 在线直构成功且 fetch 日志无重试行。
- 第四十四批工具与留档:200MiB 上下文构造 = 5×40MiB `head -c 41943040 /dev/urandom` + `Dockerfile`(`FROM scratch` + `COPY payload /payload`),`tar -czf /root/bigctx.tar.gz Dockerfile payload`;上传 = `curl -sk -b /tmp/owner-jar43.txt -X POST -H "Content-Type: application/gzip" --data-binary @/root/bigctx.tar.gz https://127.0.0.1:30443/api/v1/me/submissions/<id>/context`;采样 = `k3s crictl stats`(此版 **无 `--no-trunc`**,列解析取 `$2=NAME $4=MEM`);docker 缓存清理 = `systemctl start docker && docker builder prune -af && systemctl stop docker`;留档 `/root/stats44.log`、`/root/stats44-build.log`、提交 `sub-cc160b3ad19080f9`、镜像 `e2e/conc-b44-{1,2,3}`。 - 第四十四批工具与留档:200MiB 上下文构造 = 5×40MiB `head -c 41943040 /dev/urandom` + `Dockerfile`(`FROM scratch` + `COPY payload /payload`),`tar -czf /root/bigctx.tar.gz Dockerfile payload`;上传 = `curl -sk -b /tmp/owner-jar43.txt -X POST -H "Content-Type: application/gzip" --data-binary @/root/bigctx.tar.gz https://127.0.0.1:30443/api/v1/me/submissions/<id>/context`;采样 = `k3s crictl stats`(此版 **无 `--no-trunc`**,列解析取 `$2=NAME $4=MEM`);docker 缓存清理 = `systemctl start docker && docker builder prune -af && systemctl stop docker`;留档 `/root/stats44.log`、`/root/stats44-build.log`、提交 `sub-cc160b3ad19080f9`、镜像 `e2e/conc-b44-{1,2,3}`。
- 第四十五批工具与留档:从平台底座构建的配方 = 提交上下文含 `Dockerfile`(`FROM registry.felis.svc:5000/felis/paper:demo` + `COPY marker.txt /felis-probe-marker.txt`);装服验证 = `PATCH /api/v1/servers/test-one {"image":"registry.felis.svc:5000/user-uploads/<sub>:latest"}` → `POST /servers/test-one/wake` → `kubectl -n minecraft exec test-one-0 -- cat /felis-probe-marker.txt`;trivy 双 DB 镜像 = `mirror/trivy-db:2` + `mirror/trivy-java-db:1`(Java DB digest `5766dfbb…`;两键在 `/etc/felis/felis.{host,pod}.toml` 与 felis-config Secret 双副本);`bootstrap_test.sh` 需在 Linux 跑(VM 留档 `/root/btest72/`,应 140 PASS);本批提交样本 `sub-{b45d416f4af811ef(无镜像),83f677e41acd80c3,171e8f967f0de3bc,c006cbd633317ccb,cc160b3ad19080f9}`;留档 `/root/probe44/`、`/root/probe44.tar.gz`、`/root/probe44*.sid`。 - 第四十五批工具与留档:从平台底座构建的配方 = 提交上下文含 `Dockerfile`(`FROM registry.felis.svc:5000/felis/paper:demo` + `COPY marker.txt /felis-probe-marker.txt`);装服验证 = `PATCH /api/v1/servers/test-one {"image":"registry.felis.svc:5000/user-uploads/<sub>:latest"}` → `POST /servers/test-one/wake` → `kubectl -n minecraft exec test-one-0 -- cat /felis-probe-marker.txt`;trivy 双 DB 镜像 = `mirror/trivy-db:2` + `mirror/trivy-java-db:1`(Java DB digest `5766dfbb…`;两键在 `/etc/felis/felis.{host,pod}.toml` 与 felis-config Secret 双副本);`bootstrap_test.sh` 需在 Linux 跑(VM 留档 `/root/btest72/`,应 140 PASS);本批提交样本 `sub-{b45d416f4af811ef(无镜像),83f677e41acd80c3,171e8f967f0de3bc,c006cbd633317ccb,cc160b3ad19080f9}`;留档 `/root/probe44/`、`/root/probe44.tar.gz`、`/root/probe44*.sid`。
- 第四十六批工具与留档:控制面三处 = `registry.felis.svc:5000/felis/felis:auditfix77`(宿主 docker 源 `10.43.182.43:5000/felis/felis:auditfix77`,`v0.0.0+fix77`;api/operator + minecraft ns `felis-reaper` CronJob + api/operator `FELIS_IMAGE` 四处成对改);`/opt/felis/src` = `b9ebc87` 快照(上一版 `src.bak46`);宿主 drill 二进制 `/root/felis-fix77.bin`(Mac 侧 `CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w -X main.version=v0.0.0+fix77" ./cmd/felis`;scp 到 IPv6 主机时主机位必须写 `root@[fdb2:…]` 方括号);#75/#76/#77/#78 留档 `/root/probe77/`(`create-lane.log`、`lane2.log`、`lane3.log`〔含玩家会话矩阵 + 分级 ZT 对照 + curl 7.76 在 `-H Host:` 下**不发 jar cookie**的坑——host 路由 drill 用显式 `-H "Cookie: felis_session=…"`〕、`converge-1.log`/`converge-2.log`、`crs-before.yaml`、各步请求/响应 json);面板 CDP 截图(Mac):`/tmp/setup8-redirect.png`、`/tmp/withdraw-{1,2}-*.png`、`/tmp/admdelete-{1,2}-*.png`,脚本 `/tmp/cdp-setup8.js`、`/tmp/cdp-withdraw76.js`、`/tmp/cdp-admdelete76.js`;锁定会话铸法 = `sha256('drill-locked-77')` 直插 `sessions`(用户 `3f2c1b0a-…`);玩家会话铸法 = `[email protected]` 邮件 OTP(码在 felis-api 日志 `no Mailer configured` 行;`edge-dis2` 是软删死账号,登录门按设计排除);pgint 前置:`pg_hba` 需 `host felis_pgint felis 127.0.0.1/32 scram-sha-256`(本批第二次丢失并补回);发布链 smoke = tag `v0.1.0-rc1`(release run `35949621233`),prerelease 不移动 `/releases/latest`——无 stable 时 bootstrap 默认通道给出显式指引后 die、`felis update` 404 报错可读;首个稳定 tag 是产物决定(未代拍板)。