fix(rectification): allow runtime flag reads
Staging Backend Quality Gate / validate (pull_request) Successful in 17m5s
Staging Backend Quality Gate / publish (pull_request) Has been skipped

This commit is contained in:
Jesse_Chen
2026-08-11 23:49:44 +08:00
parent 139baeb94c
commit d19d398221
3 changed files with 41 additions and 0 deletions
+15
View File
@@ -2884,3 +2884,18 @@
- 防复发:账号重置只允许使用普通管理员 mutation guard;共享高风险 guard 不做全局放松,并由合同测试锁定角色变更仍需邮箱复核。
- 相关记录:无
- 修复版本:本次 staging 候选
## BUG-168 | 生时校正运行时开关被 RLS 静默隐藏并误报服务未开放
- 状态:resolved(本地回归已通过,待 staging 迁移与真实接口验收)
- 首次发现:2026-08-11
- 最近更新:2026-08-11
- 影响面:`POST /api/rectification/agent`、共享 `loadRuntimeFeatureFlags` 的运行时开关读取,以及管理端 feature flag 列表。
- 用户现象:staging 的 V9 生时校正接口返回 `503 rectification_runtime_disabled`,即使数据库中的 `rectification_runtime_version` 已是 `published``enabled=true``rollout_percentage=100`
- 触发条件:self-hosted Web 通过 `ADMIN_DATABASE_URL``admin_runtime` 查询启用了 RLS 的 `public.feature_flags`
- 根因:`20260806050000_operations_feature_flags.sql``admin_runtime` 授予了表级 SELECT,但启用 RLS 后没有创建对应 SELECT policy。PostgreSQL 因此不报权限错误而是返回零行;`loadRuntimeFeatureFlags` 将缺失记录安全降级为 disabled,路由遂返回“生时校正服务暂未开放”。
- 修复:新增向前迁移 `20260811030000_feature_flags_admin_runtime_read_policy.sql`,保留最小 SELECT grant,并为 `admin_runtime` 创建 `feature_flags_admin_read` RLS SELECT policy;不放宽匿名、普通用户或其它运行时角色权限。
- 验证:Docker PostgreSQL 回归先在修复前稳定得到空结果,新增迁移后要求 `admin_runtime` 能读取 `true:100:published`;staging 还需验证迁移账本、角色可见性及真实 Agent 接口不再返回 runtime disabled。
- 防复发:任何对启用 RLS 的表新增 runtime grant 时,必须同时测试对应运行时角色的真实可见行,而不能只断言 `has_table_privilege=true`feature flag 种子测试必须以 Web 实际使用的 `admin_runtime` 读取。
- 相关记录:BUG-151、BUG-166
- 修复版本:待提交
@@ -0,0 +1,15 @@
begin;
do $$
begin
if exists (select 1 from pg_roles where rolname = 'admin_runtime') then
grant select on table public.feature_flags to admin_runtime;
drop policy if exists feature_flags_admin_read on public.feature_flags;
create policy feature_flags_admin_read on public.feature_flags
for select to admin_runtime using (true);
end if;
end;
$$;
commit;
@@ -798,6 +798,7 @@ test("v9 agent api migration applies, seeds the runtime flag and guards consent"
});
assert.equal(migration.status, 0, migration.stderr);
assert.match(migration.stdout, /applied 20260813010000_agentic_rectification_v9_agent_api\.sql/);
assert.match(migration.stdout, /applied 20260811030000_feature_flags_admin_runtime_read_policy\.sql/);
// The runtime selector flag is published and enabled.
assert.equal(
@@ -805,6 +806,16 @@ test("v9 agent api migration applies, seeds the runtime flag and guards consent"
from public.feature_flags where flag_key = 'rectification_runtime_version'`),
"true:100:published",
);
assert.equal(
fixture.psqlAs(
"admin_runtime",
"admin-runtime-test-password",
`select enabled || ':' || rollout_percentage || ':' || status
from public.feature_flags
where flag_key = 'rectification_runtime_version'`,
),
"true:100:published",
);
// Run phases table exists with RLS.
assert.equal(