跳到主要内容

视觉审计:Rodada 29 之前与之后

AT-290(EP-031,HS-074)。这是一次测量,而不是变更:为了写这一页,apps/ 中没有任何改动。“之前”的截图于 2026-09-30 针对 dev 的 de18e6a6e2 进行; “之后”的截图于同一天针对 dev 的 79e6b1209f 进行,后者已包含整个 Rodada 29—— 带柔和赤陶色强调的中性黑色主题(AT-283/284)、Card/Chip/Badge/Button (AT-286..288)、移动端外框(AT-316)、会话栏(AT-317)、对话流截断 (AT-319)、审批的修复(AT-296..299、AT-310、AT-318、AT-320)、设置的预算 (AT-321)、PR 和 Containers 的文案(AT-323、AT-324)以及 i18n 的一轮处理 (AT-289、AT-326)。

截图不在仓库中。每条发现都写明截图的文件名,以便拥有截图文件夹的人打开它; 每条由检查器测得的发现也写明数字。

产品是如何启动的(以及这不覆盖什么)​

任务要求通过 docker/smoke.sh 并设 SMOKE_KEEP_UP=1 启动生产 compose。这在一个 一次性 compose 项目中尝试过(COMPOSE_PROJECT_NAME=r30visual),并且在此环境中 失败,原因与“之前”记录的相同:出站代理阻止了 dl-cdn.alpinelinux.org(以及 repo.hex.pm/builds.hex.pm),因此 docker/engine/Dockerfile.prod 的第一个 apk add --no-cache build-base git 以 2 退出,没有构建出任何生产镜像。一次性项目已用 down -v 删除。

因此“之后”运行在与“之前”相同的替代环境上,这是有意为之——不同的栈会让比较测量 的是栈本身:

  • Postgres:容器中的 pgvector/pgvector:pg16,api 的 migration 以及 pnpm seed(seed 在新数据库上干净地运行)。
  • api:从此 checkout 构建的 node dist/main,端口 3000。
  • engine:端口 4000 上对一切都返回 200 的 HTTP stub。没有 Phoenix 通道,没有 engine.* schema。
  • web:端口 5173 上 vite 的开发服务器。
  • 数据:seed 加上与“之前”相同的脚本化填充——一个带对话、brief、业务规则、 Criativo→PO handoff、epic/故事/任务和一个 module_map 的创意会话;第二个带真实 对话流和一个 agent.error 的创意会话;以及分布在 3 个会话中的 4 个待处理 proposed_actions(3 个 terminal,1 个 git_push),格式与之前相同。

对阅读本页的影响:

  • 会话的 socket 总是失败,因此回合的活动条和代码页的终端从不出现,会话以回退间隔 轮询。
  • GET /workspaces/:id/projects-summary 返回 500,因为 engine.dev_agent_states 不存在——这是 stub 的产物,和“之前”一样。Dashboard 上的 “0 agentes” 不是发现。
  • 数据与“之前”并不完全相同:seed 现在会激活自己的会话,Criativo→PO 的提议在 PO 的 backlog 事件到来时(AT-291/292)已被取代,而最新的会话是咨询式的。当“之前” 的某条发现依赖于已不存在的数据时,它被标为未复核而不是“已修复”。
  • 截图是 fullPage,但大多数界面在内部容器中滚动,所以它们显示的是视口。定向裁剪 (detalhe-*)覆盖了整页截图够不到的部分。

截图是有节奏的——界面之间 6 s,主题/视口轮次之间 65 s——并记录到零个 429 响应。 “之前”没有控制节奏,所以它的设置页截图部分是在速率限制下拍的;速率限制在下文单独 测量(G1)。

文件​

存放在仓库之外,位于会话的 scratchpad(shots-depois/):

  • <screen>--<dark|light>--<desktop|mobile>.png:19 个界面(登录、dashboard、 项目的 12 个标签页、两个会话、/containers、/account、/status)× 2 种 主题 × 2 种视口(1440×900 和 390×844)= 76 张截图。
  • detalhe-*:1280 和 1024 下的会话、对话流顶部、折叠的侧边会话面板、会话的结尾、 “Precisa de você”、两种主题下的移动端抽屉、设置的 11 个分区,以及在速率限制下 到达的最后一个分区。
  • validacao-visual.json:注入每张截图的 scripts/dev/validacao-visual.js 的输出, 加上实际应用的主题(data-theme)、页面的水平滚动宽度、加载期间对 api 的请求以及 429。
  • console-erros.json、sondas-dark.json、g1.json、g1-cliques.json:下文引用的 控制台错误和 DOM 探针。

截图脚本(capturar-depois.mjs、detalhes-depois.mjs、g1.mjs、 g1-cliques.mjs、gaveta.mjs)就是“之前”的脚本,增加了节奏控制和探针。

检查器,逐个界面​

validacao-visual.js 统计四类布局缺陷 (texto-cortado、fora-da-viewport、recortado-por-ancestral、低于 24 px 的 alvo-pequeno)。每个界面在两种主题下、之前和之后的数字都相同,因此每种视口一列就 够了。“之前”的移动端数字不能直接比较:在 AT-316 之前,大部分内容被推到了屏幕 之外,而检查器看不到的东西它不会统计。

界面桌面 之前 → 之后移动 之前 → 之后每次加载的 api 请求(之后)
login6 → 68 → 8—
dashboard0 → 01 → 06
overview3 → 112 → 232
executors0 → 04 → 022
creative0 → 07 → 320
chat0 → 05 → 116
insights0 → 04 → 017
code0 → 02 → 016
PRs0 → 05 → 118
approvals1 → 113 → 123
backlog0 → 05 → 216
architecture0 → 011 → 015
spend0 → 09 → 018
settings12 → 6120 → 3552
session5 → 214 → 2121
session 24 → 121 → 1921
containers1 → 19 → 87
account0 → 06 → 27
status1 → 11 → 12

在 390 px 下,只有一个界面会让整个页面横向滚动:/status (scrollWidth 413 对 390,两种主题下皆然)。

“之前”的发现,逐条​

严重程度与“之前”相同:A 高(破坏使用或造成误导)、M 中、B 低(打磨)。 状态:已修复、部分修复、仍存在或未复核(显示它的数据已不存在)。

外框与导航​

#严重度状态“之后”显示了什么证据
S1A部分修复外框在 390 px 下重新排布:侧边栏变成抽屉,项目轨道变成横向条,除 /status 外没有任何已认证界面横向滚动。会话路由没有跟上——见 N1。*--mobile.png、detalhe-gaveta-mobile--*.png
S2M仍存在侧边栏 “ATIVIDADES — Nenhum agente entrou em ação ainda.”,旁边的概览却显示 Criativo “aguardando” 以及 4 个待处理审批。projeto-overview--dark--desktop.png
S3M仍存在侧边栏的标签页列表没有计数器,也不标记当前标签页;轨道显示 “Aprovações 4” 和 “Arquitetura 1”,并高亮该标签页。同上
S4M已修复只有一种激活态处理:轨道中赤陶色底配赤陶色文字;侧边栏中的项目行是中性的。同上
S5B仍存在主题切换器仍然读出状态(“Tema escuro”/“Tema claro”);“sair” 仍是小写。任意已认证界面
S6B仍存在项目名称在侧边栏中用等宽字体,在页头中用展示字体。同上

登录、Dashboard​

#严重度状态“之后”显示了什么证据
L1B仍存在同样 4 个低于 24 px 的目标。validacao-visual.json、login--*
L2B仍存在同样被自身框截断的文字。同上
D1M仍存在在没有预算的项目中,“0 / 0 USD” 和 “0%” 显示为绿色。dashboard--dark--desktop.png
D2M仍存在在有 4 个会话和数十个事件的项目中显示 “Sem atividade ainda”(部分是 stub 的 500,见顶部)。同上
D3B仍存在“+ Novo projeto” 带图标;“+ Nova ideação” 和 “+ Nova conversa” 带一个字面的 “+”。dashboard × creative × chat

概览​

#严重度状态“之后”显示了什么证据
O1M未复核动态只显示最新的会话(咨询式),其中没有 PO/Arquiteto 的事件。projeto-overview--*
O2M仍存在现在更长了:“dev-web: ação aguardando decisão — A política decidiu por: default (sem regra aplicável) · raiz do escopo: pasta gerenciada “core-api-665191a6””。同上
O3B未复核在这些数据下团队时间线是空的。同上
O4B部分修复按来源分的页脚消失了(“1 de 1 carregados”),但标题写着 “1 eventos”——见 N9。同上

Criativo、Chat、洞察、执行者​

#严重度状态“之后”显示了什么证据
C1M仍存在Criativo 和 Chat 中是等宽字体的胶囊,PR 中是矩形的无衬线标签页。projeto-criativo--*、projeto-chat--*、projeto-prs--*
C2B部分修复“1 história” 现在会变形;“3 ação(ões) proposta(s) … 0 decidida(s) … auto-aprovada(s)” 和 “0 chamada(s)” 仍然存在(sessions.json:164,172,173、spend.json:20,37)。creative、chat、spend
C3B未复核seed 的会话现在是 active,所以双重 “aguardando” 不出现。creative
C4B仍存在四种空状态形式(洞察中是纯文本,代码中是锁形卡片,Chat 中没有,Backlog 的可追溯性中是一张红色卡片)。标签页
C5B仍存在洞察和架构的标题从 y≈145 开始,其他标签页从 y≈116 开始;故事只有上标题。projeto-insights--*、projeto-arquitetura--*、projeto-backlog--*
C6B仍存在“Conversar/Buscar” 位于标题 “Chat” 之上。projeto-chat--*

代码与 PR​

#严重度状态“之后”显示了什么证据
P1M已修复PR 写着 “A lista de PRs ainda não está liberada” 并解释共享的闸门;代码写着 “A aba Código ainda não está liberada”。projeto-prs--*、projeto-code--*
P2B仍存在“Já sabe o id?” 这一行仍然贴着闸门卡片的底部。projeto-prs--dark--desktop.png

审批​

#严重度状态“之后”显示了什么证据
A1A已修复轨道、审批标签页和 “Precisa de você” 都显示 4,即数据库中的数字,包括另一个会话的 git_push;会话中的侧边会话面板显示属于其他会话的 3 个。projeto-approvals--*、detalhe-precisa-de-voce--dark.png、detalhe-sessao2-topo--dark.png
A2A已修复git_push 的卡片提供 Aprovar/Negar/Modo automático,没有 “Sempre permitir”。projeto-approvals--*
A3M仍存在仍有多种变体:标签页中 4 个按钮外加一段等宽字体的长注释,“Precisa de você” 中 3 个按钮且没有注释,侧边会话面板中 3 个拉伸的按钮。“Sempre permitir” 的注释仍然说两件事:对话流中是 “grava a regra em .brabo/permissions.json”,面板中是 “libera este tipo de ação só para dev-api”。detalhe-sessao2-topo--dark.png、detalhe-precisa-de-voce--dark.png
A4B仍存在⚠ 字形仍约 8 px,而等宽字体的段落比决策本身更显眼。projeto-approvals--*
A5B仍存在命令仍以直引号出现在比例字体中。同上

会话​

#严重度状态“之后”显示了什么证据
X1A已修复在 1440、1280 和 1024 下栏都放得下:模型和回复语言合并为一个 chip,标题和元数据完整显示,“Encerrar” 在 1024 下变为图标。唯一剩下的截断是 chip 自身的省略号(“… · pt…”,217 中放 230 px)。sessao*--*--desktop.png、detalhe-sessao-1280--dark.png、detalhe-sessao-1024--dark.png、sondas-dark.json
X2A部分修复面板现在与对话流同宽(x 302–1082),按会话分组提议(“2 propostas na sessão #cde43f7c”),也不再重复标签。但它仍是 composer 上方一个占 900 px 中 345 px 的固定块,其后的条目从上边缘露出(y≈387)。detalhe-sessao2-topo--dark.png、detalhe-sessao-fim--dark.png、sondas-dark.json
X3A已修复没有按来源的分组;对话流按顺序读作问题 → 回答。detalhe-sessao2-topo--dark.png(sondas-dark.json 中的 grupos: [])
X4M部分修复handoff 卡片不在这些数据中(提议已被取代),但 composer 仍写着 “Endereçar handoff”。sessao*--*
X5M未复核没有可用来比较宽度的 handoff 卡片。—
X6M仍存在“ARTEFATOS GERADOS 3” 只列出一个组(“PO 1”);在第二个会话中 brief 存在,面板却写着 “0 · Nada ainda”。sessao--*、sessao2--*
X7B部分修复“ORIGEM: 0 REF(S)” 变成了 “ORIGEM: 0 REFERÊNCIA”——没有行话了,但数量形式错误;见 N9。sessao2--*
X8B仍存在同一个会话在两种主题下打开时滚动位置不同。sessao2--dark--desktop.png × sessao2--light--desktop.png

/containers、/account、/status​

#严重度状态“之后”显示了什么证据
K1M已修复“Parar” 和 “Remover” 为 disabled(不透明度 0.5),该行写着 “Nunca provisionado: não há container para parar nem remover”。containers--*--desktop.png、sondas-dark.json
K2M已修复broker 的原因只有一行,带一个可展开的 “Por quê?”;界面中没有任何 BROKER_URL。同上
K3B仍存在项目链接为 53×14 px。validacao-visual.json
U1M已修复“só esta página está traduzida” 这句话消失了。account--*
U2B已修复副标题中没有 RN 编号(“Agente local”);表格前的长段落保留。同上
T1B仍存在原始 ISO 时间戳、“Último check”、engine 显示 “—”,以及作为小链接的 “Voltar”。在 390 px 下页面还会溢出——见 N5。status--*

设置​

#严重度状态“之后”显示了什么证据
G1A部分修复界面自身的路径已修复:一次加载(52 个请求)再点击 “Nesta página” 的 11 个条目,在 28 s 内只多花 18 个请求,没有 429。通过直接链接(?section=)重新加载仍然每次加载花 52 个(之前 55 个):16 s 内的第六次重载超出了限制,页面显示 “Limite de requisições excedido”(g1.json:30 s 内 362 个请求,51 × 429)。g1-cliques.json、g1.json、detalhe-g1-ultima-secao--dark.png
G2M部分修复四列消失了:“Nesta página” 位于各分区之上。“Modelos por agente” 仍会截断 agent 名称(“QA de Performance e Segurança”,119 中放 201 px)和模型(143 中放 173)。在移动端表格会坍缩——见 N4。projeto-settings--*--desktop.png、validacao-visual.json
G3M部分修复“Tarefas bloqueadas seguidas até parar” 取代了 “Tasks blocked”;“dev agent(s)”、“bind-mount”、“permissions.json” 和 “runner” 仍留在 “Execução” 和 “Onde o código mora” 分区中。projeto-settings--*--desktop.png
G4M仍存在“Execução” 中的 “Salvar” 在没有任何待处理项、也没有计数时处于激活状态(赤陶色);“Converter” 是无效的。同上
G5–G7B未复核锚定分区的摘要、能力 chip 以及 PAT 的占位符没有在相同条件下重新截图。—

架构、Backlog、花费、浅色主题​

#严重度状态“之后”显示了什么证据
R1B仍存在“a partir do module_map (create_c4_diagram)”。projeto-arquitetura--*
R2B仍存在顶部有孤立段落,“Gastos do workspace” 位于项目标签页内,一张只有坐标轴的图表。projeto-spend--*
R3B仍存在故事的图标仍是 Criativo 的灯泡。projeto-backlog--*
CL1M仍存在无效的 “Converter” 在浅色背景上仍几乎看不见。projeto-settings--light--desktop.png

新发现​

“之前”没有列出的东西——要么是新的,要么是在某次修复让界面可达之前一直被掩盖的。 这里一条也没有修复;每一条都是 AT 的候选。

#严重度界面 / 主题发现证据
N1A会话,两种主题,390 px会话页面没有获得移动端布局。“Contexto da sessão” 保持约 320 px,对话流只剩约 70 px、每行折一个词,侧边会话面板无法阅读,“Iniciar ideação”/“Encerrar” 掉出右边缘。sessao--*--mobile.png、sessao2--*--mobile.png、detalhe-sessao2-mobile--*.png;检查器 19–21 texto-cortado
N2M会话,两种主题每个 chat.message 都按查看者绘制——头像和名字来自登录用户,从不来自 actorKind/actorId(apps/web/src/routes/session-timeline-montagem.tsx:379-395)。agent 的 chat.message 显示为 “owner@brabo.dev”;在共享会话中,别人的消息会显示为查看者的名字。在对话流把历史折叠为按来源分组时(X3),这一点被掩盖了。detalhe-sessao2-topo--dark.png;sondas-dark.json(autoriaChatMessage:对用户、agent、用户三次都是 “owner@brabo.dev”)
N3M/containers,两种主题,390 px表格把七列挤进宽度内:表头 “REGISTRADO/OBSERVADO/RECURSOS/DESDE” 相互重叠,单元格每行折一个词,操作按钮在右侧被截断。containers--*--mobile.png;检查器 8 texto-cortado
N4M设置,两种主题,390 px“Modelos por agente” 在移动端无法使用:agent 名称只得到 6 px 的框,模型的触发器 0 px。projeto-settings--*--mobile.png;检查器 33–35 texto-cortado
N5B/status,两种主题,390 px唯一横向滚动的页面:scrollWidth 413 对 390;表格右边缘被截断。status--*--mobile.png、validacao-visual.json
N6BDashboard,两种主题,390 px搜索框缩成 “Bus”,“Novo projeto” 折成两行。dashboard--*--mobile.png
N7BCriativo,两种主题,390 px每行的会话 id 得到 0 px 的框(“#ae1e5746”、“#cde43f7c”),于是各行失去了标识它们的东西。projeto-criativo--*--mobile.png、validacao-visual.json
N8B项目轨道,两种主题,390 px激活的标签页没有被完整滚入视野(“Config…” 被截断,审批的 “4” 被裁掉),也没有任何提示表明该条可以滚动。projeto-settings--*--mobile.png、projeto-approvals--*--mobile.png
N9B概览与会话,两种主题i18next 那一轮处理留下的复数失误:“1 eventos”(overview.json:70 只有一种形式)和 “0 referência”(pt 的规则把 0 归入 one,所以 origemRefs_one 被用于零)。projeto-overview--*--desktop.png、sessao2--*
N10B登录,两种主题背景光晕是 --success-soft(apps/web/src/routes/AuthLayout.module.css:80-84):配旧的蓝绿色时它读起来像品牌色;在中性主题中,它是赤陶色页面后的一团绿雾。login--dark--desktop.png、login--light--desktop.png
N11B审批标签页,两种主题每张卡片都带有 “Motivo da política fora dos eventos carregados nesta tela”——这是真的(原因在另一个会话的日志里),但这是工具在解释自己,而且每张卡片都重复。projeto-approvals--*

本页不测量什么​

  • 对比度。那是基于 token 的算术,位于 web 的测试套件中 (apps/web/src/lib/contraste.ts);这里的检查器只看布局。
  • engine 之后的任何东西:实时回合条、终端、dev agent 的在场状态。stub 无法产生它们。
  • 生产构建。开发用的 vite 提供相同的组件和 CSS,但不提供生产的 CSP,也没有 web 镜像前面的 nginx。